diff --git a/behavioral/iterator/alpha_order_iterator.py b/behavioral/iterator/alpha_order_iterator.py new file mode 100644 index 0000000..914c995 --- /dev/null +++ b/behavioral/iterator/alpha_order_iterator.py @@ -0,0 +1,64 @@ +from __future__ import annotations + +from typing import Iterator, Iterable, List, Any + + +class WordCollection(Iterable): + """ + Concrete Collections provide one or several methods for retrieving fresh + iterator instances, compatible with the collection class. + """ + + def __init__(self, collection: List[Any] = []) -> None: + self._collection = collection + + def __iter__(self) -> AlphabeticalOrderIterator: + """ + The __iter__() method returns the iterator object itself, by default we + return the iterator in ascending order. + """ + return AlphabeticalOrderIterator(self._collection) + + def get_reverse_iterator(self) -> AlphabeticalOrderIterator: + return AlphabeticalOrderIterator(self._collection, reverse=True) + + def add_item(self, item: Any) -> None: + self._collection.append(item) + + +class AlphabeticalOrderIterator(Iterator): + """ + Concrete Iterators implement various traversal algorithms. These classes + store the current traversal position at all times. + """ + + """ + `_position` attribute stores the current traversal position. An iterator may + have a lot of other fields for storing iteration state, especially when it + is supposed to work with a particular kind of collection. + """ + _position: int = None + + """ + This attribute indicates the traversal direction. + """ + _reverse: bool = False + + def __init__(self, collection: WordCollection, reverse: bool = False) -> None: + self._collection = collection + self._reverse = reverse + self._position = -1 if reverse else 0 + + def __next__(self): + """ + The __next__() method must return the next item in the sequence. On + reaching the end, and in subsequent calls, it must raise StopIteration. + """ + + try: + value = self._collection[self._position] + self._position += -1 if self._reverse else 1 + except IndexError: + raise StopIteration() + + return value diff --git a/behavioral/iterator/main.py b/behavioral/iterator/main.py new file mode 100644 index 0000000..757356a --- /dev/null +++ b/behavioral/iterator/main.py @@ -0,0 +1,17 @@ +""" +The client code may or may not know about the Concrete Iterator or Collection +classes, depending on the level of indirection you want to keep in your program. +""" +from behavioral.iterator.alpha_order_iterator import WordCollection + +collection = WordCollection() +collection.add_item("First") +collection.add_item("Second") +collection.add_item("Third") + +print("Straight traversal:") +print("\n".join(collection)) +print("") + +print("Reverse traversal:") +print("\n".join(collection.get_reverse_iterator()), end="")