Exercise 2: A Tuple-Backed PlayingCardDeck — Possible Solution ==================================================================== THE NEW COLLECTION AND ITERATOR ------------------------------ class PlayingCardDeckIterator: def __init__(self, cards): self._cards = cards; self._index = 0 def has_next(self): return self._index < len(self._cards) def next(self): card = self._cards[self._index] self._index += 1 return card class PlayingCardDeck: def __init__(self): self._cards = ('Ace', 'King', 'Queen', 'Jack') # a tuple def create_iterator(self): return PlayingCardDeckIterator(self._cards) This follows the exact same has_next()/next() shape as this chapter's own BookShelfIterator and PlaylistIterator - only the underlying storage (a tuple this time, instead of a list or a dict) and the iterator's own class name differ. VERIFYING print_all() WORKS UNMODIFIED ------------------------------ Using this chapter's own print_all(iterator) function, completely unchanged: deck iteration: ['Ace', 'King', 'Queen', 'Jack'] The identical while iterator.has_next(): ... loop that already worked against a list-backed BookShelf and a dict-backed Playlist now also works against a tuple-backed PlayingCardDeck - a third, genuinely different storage type, with zero changes to print_all() itself. WHY THIS CONFIRMS ITERATOR'S OWN GENERALITY ------------------------------ print_all() only ever calls .has_next() and .next() - it has never once referenced _books, _songs, or (now) _cards directly, and it never will need to, no matter how many more collection types get added. Each new collection only needs to supply its own iterator implementing the same two methods; the client-facing traversal code this chapter already wrote stays exactly as it was. WHY THIS WORKS AS AN ANSWER ------------------------------ The new iterator follows the has_next()/next() interface established by this chapter's own two existing iterators exactly, the underlying storage is a genuinely different type (a tuple, distinct from both a list and a dict), and the result is verified through this chapter's own unmodified print_all() function rather than a new one written specifically for this exercise.