diff --git a/server/entertainment_decider/common/_itertools.py b/server/entertainment_decider/common/_itertools.py index c6b1b10..a3c4bee 100644 --- a/server/entertainment_decider/common/_itertools.py +++ b/server/entertainment_decider/common/_itertools.py @@ -24,6 +24,8 @@ class _IterFixer(Iterator[T]): self.__it = it def __iter__(self) -> Iterator[T]: + # this method is the reason for this class + # some iterators miss it and so are not Iterable without this proxy return self def __next__(self) -> T: @@ -31,6 +33,13 @@ class _IterFixer(Iterator[T]): def fix_iter(iterable: Iterable[T]) -> Iterable[T]: + """ + wraps the iterator of iterable + into a simple proxy Iterator/Iterable implementation. + + Required in weird edgecases, + where the iterator of an iterable is not an iterable. + """ return _IterFixer(iter(iterable)) @@ -43,6 +52,20 @@ def iter_lookahead( get_first: Literal[False] = False, get_last: Literal[False] = False, ) -> Iterable[Tuple[T, T]]: + """ + allows iterating over while also getting the last/next item + + The pairs are given as a Tuple and so can be split: + ```python + for last, cur in iter_lookahead(iterable): ... + ``` + + The first and last tuple will contain the first / last two entries, so that + - `iterable[0]` only appears in `last` and not in `cur` + - `iterable[-1]` only appears in `cur` and not in `last` + + You can change that behavior with /. + """ ... @@ -52,6 +75,21 @@ def iter_lookahead( get_first: Literal[True], get_last: Literal[False] = False, ) -> Iterable[Tuple[None, T] | Tuple[T, T]]: + """ + allows iterating over while also getting the last/next item + + The pairs are given as a Tuple and so can be split: + ```python + for last, cur in iter_lookahead(iterable): ... + ``` + + - The first tuple will look like `(None, cur)`, + so that `iterable[0]` will appear in both `cur` and `last`. + - The last tuple will contain the last two entries, + so that `iterable[-1]` only appears in `cur` and not in `last`. + + You can change that behavior with /. + """ ... @@ -61,6 +99,21 @@ def iter_lookahead( get_first: Literal[False] = False, get_last: Literal[True] = True, # <- default only to satisfy python ) -> Iterable[Tuple[T, T] | Tuple[T, None]]: + """ + allows iterating over while also getting the last/next item + + The pairs are given as a Tuple and so can be split: + ```python + for last, cur in iter_lookahead(iterable): ... + ``` + + - The first tuple will contain the first two entries, + so that `iterable[0]` only appears in `cur` and not in `last`. + - The last tuple will look like `(last, None)`, + so that `iterable[-1]` will appear in both `cur` and `last`. + + You can change that behavior with /. + """ ... @@ -70,6 +123,20 @@ def iter_lookahead( get_first: Literal[True], get_last: Literal[True], ) -> Iterable[Tuple[None, T] | Tuple[T, T] | Tuple[T, None]]: + """ + allows iterating over while also getting the last/next item + + The pairs are given as a Tuple and so can be split: + ```python + for last, cur in iter_lookahead(iterable): ... + ``` + + The first / last tuple will look like `(None, T)` / `(T, None)`, + so that both `iterable[0]` and `iterable[-1]` + will both appear in `cur` and `last`. + + You can change that behavior with /. + """ ... @@ -78,6 +145,20 @@ def iter_lookahead( get_first: bool = False, get_last: bool = False, ) -> Iterable[Tuple[None, T] | Tuple[T, T] | Tuple[T, None]]: + """ + allows iterating over while also getting the last/next item + + The pairs are given as a Tuple and so can be split: + ```python + for last, cur in iter_lookahead(iterable): ... + ``` + + The behavior for the border cases can be configured. + If is True, the first tuple will be `(None, last)`. + If is True, the last tuple will be `(cur, None)`. + Otherwise, both values will be set at the borders respectively. + See the docstrings for the overloaded methods. + """ it = iter(iterable) last = next(it) if get_first: @@ -93,4 +174,5 @@ def iter_lookahead( def limit_iter(iter: Iterable[T], limit: int) -> List[T]: + """gets the first elements of and puts them in a list""" return list(itertools.islice(iter, limit))