# Implement these 4 utilities on iterables: # - prefix and suffix list # - prefix and suffix sum from __future__ import annotations import types from typing import List, Generator # Prefix / Postfix iterator class Fix: def __init__( self, step: int, list_in: List[ int ] ) -> None: self.slice = 0 self.step = step self.list = list_in self.lenlist = len( list_in ) def __iter__( self ) -> Fix: return self def __next__( self ) -> List[ int ]: slice_ = self.slice self.slice += self.step if self.slice > 0: if slice_ > self.lenlist: raise StopIteration return self.list[ 0 : slice_ ] else: if slice_ < -self.lenlist: raise StopIteration return self.list[ self.lenlist + slice_ : self.lenlist ] def prefixes_iter( list_in: List[ int ] ) -> Fix: return Fix( 1, list_in ) def prefixes_gen( list_in: List[ int ] ) \ -> Generator[ List[ int ], None, None ]: for i in range( len( list_in ) + 1 ): yield list_in[ : i ] def suffixes( list_in: List[ int ] ) -> Fix: return Fix( -1, list_in ) def prefix_sum( list_in: List[ int ] ) \ -> Generator[ int, None, None ]: count = 0 for item in list_in: count += item yield count def suffix_sum( list_in: List[ int ] ) \ -> Generator[ int, None, None ]: count = 0 for item in reversed( list_in ): count += item yield count