design-patterns/behavioral/iterator/alpha_order_iterator.py
2020-10-02 15:23:39 +02:00

64 lines
2 KiB
Python

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