satella.coding.sequences package¶
Submodules¶
satella.coding.sequences.average module¶
- class satella.coding.sequences.average.RollingArithmeticAverage(n=100)¶
Bases:
object
A class to implement a rolling arithmetic average over n last entries
- Parameters:
n (int) – amount of last entries to count
- avg()¶
Compute current average
- Returns:
current average
- Raises:
ZeroDivisionError – the average buffer is empty
- Return type:
float
- clear()¶
Clear the rolling average buffer
- Return type:
None
- insert(x)¶
Add a value to the rolling average, discarding the previous entry if the buffer size is exceeded
- Parameters:
x (float) – sample to insert
- Return type:
None
- n¶
- queue¶
- tot_sum¶
satella.coding.sequences.choose module¶
- satella.coding.sequences.choose.choose(filter_fun, iterable, check_multiple=False)¶
Return a single value that exists in given iterable.
Essentially the same as:
>>> next(iter(filter(filter_fun, iterable)))
but raises a different exception if nothing matches (and if there are multiple matches and check_multiple is True). If check_multiple is True this guarantees to exhaust the generator (if passed).
- Parameters:
filter_fun (Callable[[T], bool]) – function that returns bool on the single value
iterable (Union[Iterator[T], Iterable[T]]) – iterable to examine
check_multiple (bool) – if True, this will check if there are multiple entries matching filter_fun, and will raise ValueError if so. If True, this will exhaust the iterator. If left at default, False, this may not exhaust the iterator.
- Returns:
single element in the iterable that matches given input
- Raises:
ValueError – on multiple elements matching (if check_multiple), or none at all
- Return type:
T
- satella.coding.sequences.choose.choose_one(filter_fun, iterable)¶
Syntactic sugar for
>>> choose(filter_fun, iterable, check_multiple=True)
This exhausts the iterable.
- Parameters:
filter_fun (Callable[[T], bool]) – function that returns bool on the single value
iterable (Union[Iterator[T], Iterable[T]]) – iterable to examine
- Returns:
single element in the iterable that matches given input
- Raises:
ValueError – on multiple elements matching, or none at all
- Return type:
T
- satella.coding.sequences.choose.choose_with_index(filter_fun, iterable)¶
Return a first found single value that exists in given iterable and filter_fun called on it returns True
- Parameters:
filter_fun (Callable[[T], bool]) – function that returns bool on the single value
iterable (Union[Iterator[T], Iterable[T]]) – iterable to examine
- Returns:
a tuple of (element, index)
- Raises:
ValueError – element not found
- Return type:
Tuple[T, int]
satella.coding.sequences.iterators module¶
- class satella.coding.sequences.iterators.AlreadySeen¶
Bases:
Generic
[K
]Class to filter out unique objects. Objects must be hashable, barring that they must be eq-able, however passing it an non-hashable object will result in O(n^2) complexity, as the class uses a list to keep track of the objects.
Usage:
>>> als = AlreadySeen() >>> for elem in sequence: >>> if als.is_unique(elem): >>> ... process the element ...
- is_unique(key)¶
Has the element been spotted first time?
Add it to the set.
- Parameters:
key (K) – element to check
- Returns:
whether the element was seen for the first time
- Return type:
bool
- set: Union[list, set]¶
- class satella.coding.sequences.iterators.ConstruableIterator(*args, **kwargs)¶
Bases:
object
An iterator that you can attach arbitrary things at the end and consume them during iteration. Eg:
>>> a = ConstruableIterator([1, 2, 3]) >>> for b in a: >>> if b % 2 == 0: >>> a.add(6)
All arguments you provide to the constructor will be passed to underlying deque
- add(t)¶
Schedule given value to be iterated over after current items
- Parameters:
t (T) – value to iterate over
- Return type:
None
- add_immediate(t)¶
Schedule given value to be iterated over during the next __next__ call
- Parameters:
t (T) – value to iterate over
- Return type:
None
- add_many(t)¶
Schedule given values to be iterated over after current items
- Parameters:
t (Iterable[T]) – iterable of values
- Return type:
None
- add_many_immediate(t)¶
Schedule given values to be iterated over during the next __next__ call
- Parameters:
t (Iterable[T]) – values to iterate over
- Return type:
None
- entries¶
- class satella.coding.sequences.iterators.IteratorListAdapter(iterator)¶
Bases:
object
A wrapper around an iterator that enables it to be processed as a list.
Ie. the generator will now support __contains__, __len__ and __getitem__. If a call to such a method is done, the generator will be unfolded in memory so this might take a ton of memory! You’ve been warned!
Deprecated since version 2.15.7: Use :class:`~satella.coding.sequences.ListWrapperIterator ` instead
- Parameters:
iterator (Iterator) – iterator to unfold
- iterator¶
- list¶
- pointer¶
- unfolded¶
- class satella.coding.sequences.iterators.ListWrapperIterator(iterator)¶
Bases:
Sequence
[T
],Iterator
[T
]A wrapped for an iterator, enabling using it as a normal list.
The first time this is evaluated, list is populated with elements.
The second time, items are taken from the list.
It never computes more than it needs to.
Essentially a class that lets you reuse one-shot iterators.
This is additionally a generic class.
- Variables:
internal_pointer – (int) the number of element this list internally points to
- Parameters:
iterator (Union[Iterator[T], Iterable[T]]) –
- advance_to_item(i)¶
Makes the list be at least i in size
- Parameters:
i (int) –
- Return type:
None
- exhaust()¶
Load all elements of this iterator into memory.
- Return type:
None
- exhausted¶
- internal_pointer¶
- iterator¶
- list¶
- satella.coding.sequences.iterators.append_sequence(seq, *elems_to_append)¶
Return an iterator which append elem_to_append to every tuple in seq.
Example:
>>> a = [(1, ), (2, ), (3, )] >>> assert list(append_sequence(a, 1, 2)) == [(1, 1, 2), (2, 1, 2), (3, 1, 2)]
If every element of seq is not a tuple, it will be cast to one.
- Parameters:
seq (Iterator[tuple]) – sequence to append
elems_to_append – element(s) to append
- Returns:
an iterator
- Return type:
Iterator[tuple]
- satella.coding.sequences.iterators.count(sq, start=None, step=1, start_at=None)¶
Return a sequence of integers, for each entry in the sequence with provided step.
Essentially the same (if step were ignored) as:
>>> (i for i, x in enumerate(sq, start=start_at))
Deprecated since version 2.14.22: Use start instead
- Parameters:
sq (Union[Iterator[T], Iterable[T]]) – sequence to enumerate
start (Optional[int]) – alias for start_at. Prefer it in regards to start_at. Default is 0
step (int) – number to add to internal counter after each element
start_at (Optional[int]) – deprecated alias for start
- Returns:
an iterator of subsequent integers
- Return type:
Iterator[int]
- satella.coding.sequences.iterators.enumerate2(iterable, start=0, step=1)¶
Enumerate with a custom step
- Parameters:
iterable (Union[Iterator[T], Iterable[T]]) – iterable to enumerate
start (int) – value to start at
step (int) – step to add during each iteration
- Return type:
Iterator[Tuple[int, T]]
- satella.coding.sequences.iterators.even(sq)¶
Return only elements with even indices in this iterable (first element will be returned, as indices are counted from 0)
- Parameters:
sq (Union[Iterator[T], Iterable[T]]) –
- Return type:
Iterator[T]
- satella.coding.sequences.iterators.f_range(*args)¶
A range() that supports float.
Note that this behaves correctly when given a negative step.
Call either:
>>> f_range(stop) # will start from 0 and step 1 >>> f_range(start, stop) # will start from start and continue until the result is gte stop >>> # will start from start and continue by step until the result is gte stop >>> f_range(start, stop, step)
- Raises:
TypeError – invalid number of arguments
- Parameters:
args (float) –
- Return type:
Iterator[float]
- satella.coding.sequences.iterators.infinite_counter(start_at=0, step=1)¶
Infinite counter, starting at start_at
Deprecated since version 2.14.22: Use itertools.count instead.
- Parameters:
start_at (int) – value at which to start counting. It will be yielded as first
step (int) – step by which to progress the counter
- Return type:
Iterator[int]
- satella.coding.sequences.iterators.is_empty(iterable, exhaust=True)¶
Checks whether an iterator is empty.
This will exhaust the iterator if exhaust is left at default, or True
- Parameters:
iterable (Union[Iterator[T], Iterable[T]]) – iterator to check
exhaust (bool) – if set to False, at most a single element will be consumed from the iterator
- Returns:
whether the iterator is empty
- Return type:
bool
- satella.coding.sequences.iterators.is_instance(classes)¶
- Parameters:
classes (Union[Tuple[type, ...], type]) –
- Return type:
Callable[[object], bool]
- satella.coding.sequences.iterators.iter_dict_of_list(dct)¶
Presents a simple way to iterate over a dictionary whose values are lists.
This will return the dictionary key and each of the value contained in the list attached to the key.
- Parameters:
dct (Dict[T, List[U]]) –
- Return type:
Generator[Tuple[T, U], None, None]
- satella.coding.sequences.iterators.iterate_callable(clbl, start_from=0, exc_classes=(<class 'IndexError'>, <class 'ValueError'>))¶
Given a callable that accepts an integer and returns the n-th entry, iterate over it until it starts to throw some exception.
- Parameters:
clbl (Callable[[int], V]) – callable to call
start_from (int) – number to start from
exc_classes – exceptions that being thrown show that the list was exhausted
- Returns:
an iterator
- Return type:
Iterator[V]
- satella.coding.sequences.iterators.length(iterator)¶
Return the length of an iterator, exhausting it by the way
- Parameters:
iterator (Union[Iterator[T], Iterable[T]]) –
- Return type:
int
- satella.coding.sequences.iterators.map_list(fun, iterable)¶
A syntactic sugar for
>>> list(map(fun, iterable))
- Parameters:
fun (Callable) – function to apply
iterable (Union[Iterator[T], Iterable[T]]) – iterable to iterate over
- Return type:
List
- satella.coding.sequences.iterators.n_th(iterator, n=0)¶
Obtain n-th element (counting from 0) of an iterable
- Parameters:
iterator (Union[Iterator[T], Iterable[T]]) – iterable to process
n (int) – element to return. Note that we’re counting from 0
- Raises:
IndexError – iterable was too short
- Return type:
T
- satella.coding.sequences.iterators.odd(sq)¶
Return only elements with odd indices in this iterable.
- Parameters:
sq (Union[Iterator[T], Iterable[T]]) –
- Return type:
Iterator[T]
- satella.coding.sequences.iterators.other_sequence_no_longer_than(base_sequence, other_sequence)¶
Return every item in other_sequence, but limit it’s p_len to that of base_sequence.
If other_sequence is shorter than base_sequence, the shorter one will be returned.
- Parameters:
base_sequence (Union[Iterator[T], Iterable[T]]) – sequence whose p_len should be taken
other_sequence (Union[Iterator[T], Iterable[T]]) – sequence to output values from
- Return type:
Iterator[T]
- satella.coding.sequences.iterators.shift(iterable_, shift_factor)¶
Return this sequence, but shifted by factor elements, so that elements will appear sooner by factor.
Eg:
>>> assert list(shift([1,2, 3], 1)) == [2, 3, 1]
However note that this will result in iterators which have negative shift to be readed entirely into memory (converted internally to lists). This can be avoided by passing in a Reversible iterable.
- Parameters:
iterable – iterable to shift
shift_factor (int) – factor by which shift elements.
iterable_ (Union[Reversible[T], Iterator[T], Iterable[T]]) –
- Returns:
shifted sequence
- Return type:
Iterator[T]
- satella.coding.sequences.iterators.skip_first(iterator, n)¶
Skip first n elements from given iterator.
Returned iterator may be empty, if source iterator is shorter or equal to n.
Deprecated since version 2.14.22: Use itertools.islice instead
- Parameters:
iterator (Union[Iterator[T], Iterable[T]]) –
n (int) –
- Return type:
Iterator[T]
- satella.coding.sequences.iterators.smart_enumerate(iterator, start=0, step=1)¶
An enumerate that talks pretty with lists of tuples. Consider
>>> a = [(1, 2), (3, 4), (5, 6)] >>> for i, b in enumerate(a): >>> c, d = b >>> ...
This function allows you just to write: >>> for i, c, d in enumerate(a): >>> …
Note that elements in your iterable must be either a list of a tuple for that to work, or need to be able to be coerced to a tuple. Otherwise, TypeError will be thrown.
- Parameters:
iterator (Union[Iterator[T], Iterable[T]]) – iterator to enumerate
start (int) – value to start counting at
step (int) – step to advance the enumeration with
- Raises:
TypeError – could not coerce the elements in your iterable to a tuple
- Return type:
Iterator[Tuple]
- satella.coding.sequences.iterators.smart_zip(*iterators)¶
Zip in such a way that resulted tuples are automatically expanded.
Ie:
>>> b = list(smart_zip([(1, 1), (1, 2)], [1, 2])) >>> assert b == [(1, 1, 1), (1, 2, 2)]
Note that an element of the zipped iterator must be a tuple (ie. isinstance tuple) in order for it to be appended to resulting iterator element!
Deprecated since version Use: the for (a, b), c syntax instead.
- Parameters:
iterators (Union[Iterator[T], Iterable[T]]) – list of iterators to zip together
- Returns:
an iterator zipping the arguments in a smart way
- Return type:
Iterator[Tuple[T, …]]
- satella.coding.sequences.iterators.stop_after(iterator, n)¶
Stop this iterator after returning n elements, even if it’s longer than that.
The resulting iterator may be shorter than n, if the source element is so.
Deprecated since version 2.14.22: Use itertools.islice instead
- Parameters:
iterator (Union[Iterator[T], Iterable[T]]) – iterator or iterable to examine
n (int) – elements to return
- Return type:
Iterator[T]
- satella.coding.sequences.iterators.take_n(iterator, n, skip=0)¶
Take (first) n elements of an iterator, or the entire iterator, whichever comes first
- Parameters:
iterator (Union[Iterator[T], Iterable[T]]) – iterator to take from
n (int) – amount of elements to take
skip (int) – elements from the start to skip
- Returns:
list of p_len n (or shorter)
- Return type:
List[T]
- satella.coding.sequences.iterators.to_iterator(fun)¶
Convert function to an iterator. You can replace the following code:
>>> def iterator(x): >>> for y in x: >>> yield fun(y)
with
>>> @to_iterator >>> def fun(y): >>> ...
and now call fun instead of iterator. fun will accept a single argument - the iterable, and assume that the function you decorate also takes a single argument - the item
- satella.coding.sequences.iterators.try_close(iterator)¶
Try to invoke close() on an iterator. Do nothing if provided iterator doesn’t have a .close() method.
- Parameters:
iterator (Iterator) – iterator to close
- Return type:
None
- satella.coding.sequences.iterators.unique(lst)¶
Return each element from lst, but return every element only once.
Take care for elements of T to be __eq__-able and hashable!
This will keep internally a set of elements encountered, and skip them if same element appears twice
- Parameters:
lst (Union[Iterator[T], Iterable[T]]) – iterable to process
- Returns:
a generator yielding unique items from lst
- Return type:
Iterator[T]
- satella.coding.sequences.iterators.walk(obj, child_getter=<class 'list'>, deep_first=True, leaves_only=False)¶
Return every node of a nested structure.
- Parameters:
obj (T) – structure to traverse. This will not appear in generator
child_getter (Callable[[T], Optional[List[T]]]) – a callable to return a list of children of T. Should return an empty list or None of there are no more children.
deep_first (bool) – if True, deep first will be returned, else it will be breadth first
leaves_only (bool) – if True, only leaf nodes (having no children) will be returned
- Return type:
Iterator[T]
- satella.coding.sequences.iterators.zip_shifted(*args)¶
Construct an iterator, just like zip but first by cycling it’s elements by it’s shift factor. Elements will be shifted by a certain factor, this means that they will appear earlier.
Example:
>>> zip_shifted(([1, 2, 3, 4], 1), ([1, 2, 3, 4], 0)) == [(2, 1), (3, 2), (4, 3), (1, 4)]
This will work on arbitrary iterators and iterables.
Shift can be negative, in which case the last elements will appear sooner, eg.
>>> zip_shifted(([1, 2, 3, 4], -1), ([1, 2, 3, 4], 0)) == [(4, 1), (1, 2), (2, 3), (3, 4)]
Same memory considerations as
shift()
apply.The resulting iterator will be as long as the shortest sequence.
Deprecated since version 2.14.22: Use zip(shift(…)) instead
- Parameters:
args (Union[Iterator[T], Iterable[T], Tuple[Union[Iterator[T], Iterable[T]], int]]) – a tuple with the iterator/iterable and amount of shift. If a non-tuple is given, it is assumed that the shift is zero.
- Return type:
Iterator[Tuple[T, …]]
satella.coding.sequences.sequences module¶
- class satella.coding.sequences.sequences.Multirun(sequence, dont_return_list=False)¶
Bases:
object
A class to launch the same operation on the entire sequence.
Consider:
>>> class Counter: >>> def __init__(self, value=0): >>> self.count = value >>> def add(self, v): >>> self.count += 1 >>> def __eq__(self, other): >>> return self.count == other.count >>> def __iadd__(self, other): >>> self.add(other) >>> a = [Counter(), Counter()]
The following:
>>> for b in a: >>> b.add(2)
Can be replaced with
>>> Multirun(a).add(2)
And the following:
>>> for b in a: >>> b += 3
With this
>>> b = Mulirun(a) >>> b += 3
Furthermore note that:
>>> Multirun(a).add(2) == [Counter(2), Counter(2)]
- Parameters:
sequence (Iterable) – sequence to execute these operations for
dont_return_list (bool) – the operation won’t return a list if this is True
- dont_return_list¶
- sequence¶
- satella.coding.sequences.sequences.add_next(lst, wrap_over=False, skip_last=False)¶
Yields a 2-tuple of given iterable, presenting the next element as second element of the tuple.
The last element will be the last element alongside with a None, if wrap_over is False, or the first element if wrap_over was True
Example:
>>> list(add_next([1, 2, 3, 4, 5])) == [(1, 2), (2, 3), (3, 4), (4, 5), (5, None)] >>> list(add_next([1, 2, 3, 4, 5], True)) == [(1, 2), (2, 3), (3, 4), (4, 5), (5, 1)]
- Parameters:
lst (Union[Iterator[T], Iterable[T]]) – iterable to iterate over
wrap_over (bool) – whether to attach the first element to the pair of the last element instead of None
skip_last (bool) – if this is True, then last element, alongside with a None, won’t be output
- Return type:
Iterator[Tuple[T, Optional[T]]]
- satella.coding.sequences.sequences.filter_out_false(y)¶
Return all elements, as a list, that are True
- Parameters:
y (Sequence[T]) – a sequence of items
- Returns:
a list of all subelements, in order, that are not None
- Return type:
List[T]
- satella.coding.sequences.sequences.filter_out_nones(y)¶
Return all elements, as a list, that are not None
- Parameters:
y (Sequence[T]) – a sequence of items
- Returns:
a list of all subelements, in order, that are not None
- Return type:
List[T]
- satella.coding.sequences.sequences.group_quantity(length, seq)¶
Slice an iterable into lists containing at most len entries.
Eg.
>>> assert list(group_quantity(3, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])) == [[1, 2, 3], [4, 5, 6], >>> [7, 8, 9], [10]]
This correctly detects sequences, and uses an optimized variant via slicing if a sequence is passed.
You can safely pass ranges
- Parameters:
length (int) – p_len for the returning sequences
seq (Union[Iterator[T], Iterable[T]]) – sequence to split
- Return type:
Iterator[List[T]]
- satella.coding.sequences.sequences.half_cartesian(seq, include_same_pairs=True)¶
Generate half of the Cartesian product of both sequences.
Useful when you have a commutative operation that you’d like to execute on both elements (eg. checking for collisions).
Example:
>>> list(half_cartesian([1, 2, 3], [1, 2, 3])) == >>> [(1, 1), (1, 2), (1, 3), (2, 2), (2, 3), (3, 3)]
- Parameters:
seq (Iterable[T]) – The sequence
include_same_pairs (bool) – if True, then pairs returning two of the same objects will be returned. For example, if False, the following will be true:
- Return type:
Iterator[Tuple[T, T]]
>>> list(half_cartesian([1, 2, 3], [1, 2, 3], include_same_pairs=False)) == >>> [(1, 2), (1, 3), (2, 3)]
- satella.coding.sequences.sequences.index_of(predicate, seq)¶
Return an index of first met element that calling predicate on it returns True
- Parameters:
predicate (Callable[[T], bool]) – predicate to apply
seq (Sequence[T]) – sequence to examine
- Returns:
index of the element
- Raises:
ValueError – if no element found
- Return type:
int
- satella.coding.sequences.sequences.index_of_max(seq)¶
Return the index of the maximum element
- Parameters:
seq (Sequence[T]) – sequence to examine
- Returns:
index of the maximum element
- Raises:
ValueError – sequence was empty
- Return type:
int
- satella.coding.sequences.sequences.infinite_iterator(returns=None, return_factory=None)¶
Return an infinite number of objects.
- Parameters:
returns (Optional[T]) – object to return. Note that this will be this very object, it will not be copied.
return_factory (Optional[Callable[[], T]]) – a callable that takes 0 args and returns an element to return.
- Returns:
an infinite iterator of provided values
- Return type:
Iterator[T]
- satella.coding.sequences.sequences.is_last(lst)¶
Return every element of the list, alongside a flag telling is this the last element.
Use like:
>>> for is_last, element in is_last(my_list): >>> if is_last: >>> ...
- Parameters:
lst (Union[Iterator[T], Iterable[T]]) – list to iterate thru
- Returns:
a p_gen returning (bool, T)
- Return type:
Iterator[Tuple[bool, T]]
Note that this returns a nice, O(1) iterator.
- satella.coding.sequences.sequences.make_list(element, n, deep_copy=False)¶
Make a list consisting of n times element. Element will be copied via copy.copy before adding to list.
- Parameters:
element (T) – element
n (int) – times to repeat the element
deep_copy (bool) – whether to use copy.deepcopy instead of copy.copy
- Returns:
list of length n
- Return type:
List[T]
Module contents¶
- class satella.coding.sequences.AlreadySeen¶
Bases:
Generic
[K
]Class to filter out unique objects. Objects must be hashable, barring that they must be eq-able, however passing it an non-hashable object will result in O(n^2) complexity, as the class uses a list to keep track of the objects.
Usage:
>>> als = AlreadySeen() >>> for elem in sequence: >>> if als.is_unique(elem): >>> ... process the element ...
- is_unique(key)¶
Has the element been spotted first time?
Add it to the set.
- Parameters:
key (K) – element to check
- Returns:
whether the element was seen for the first time
- Return type:
bool
- set: Union[list, set]¶
- class satella.coding.sequences.ConstruableIterator(*args, **kwargs)¶
Bases:
object
An iterator that you can attach arbitrary things at the end and consume them during iteration. Eg:
>>> a = ConstruableIterator([1, 2, 3]) >>> for b in a: >>> if b % 2 == 0: >>> a.add(6)
All arguments you provide to the constructor will be passed to underlying deque
- add(t)¶
Schedule given value to be iterated over after current items
- Parameters:
t (T) – value to iterate over
- Return type:
None
- add_immediate(t)¶
Schedule given value to be iterated over during the next __next__ call
- Parameters:
t (T) – value to iterate over
- Return type:
None
- add_many(t)¶
Schedule given values to be iterated over after current items
- Parameters:
t (Iterable[T]) – iterable of values
- Return type:
None
- add_many_immediate(t)¶
Schedule given values to be iterated over during the next __next__ call
- Parameters:
t (Iterable[T]) – values to iterate over
- Return type:
None
- entries¶
- class satella.coding.sequences.IteratorListAdapter(iterator)¶
Bases:
object
A wrapper around an iterator that enables it to be processed as a list.
Ie. the generator will now support __contains__, __len__ and __getitem__. If a call to such a method is done, the generator will be unfolded in memory so this might take a ton of memory! You’ve been warned!
Deprecated since version 2.15.7: Use :class:`~satella.coding.sequences.ListWrapperIterator ` instead
- Parameters:
iterator (Iterator) – iterator to unfold
- iterator¶
- list¶
- pointer¶
- unfolded¶
- class satella.coding.sequences.ListWrapperIterator(iterator)¶
Bases:
Sequence
[T
],Iterator
[T
]A wrapped for an iterator, enabling using it as a normal list.
The first time this is evaluated, list is populated with elements.
The second time, items are taken from the list.
It never computes more than it needs to.
Essentially a class that lets you reuse one-shot iterators.
This is additionally a generic class.
- Variables:
internal_pointer – (int) the number of element this list internally points to
- Parameters:
iterator (Union[Iterator[T], Iterable[T]]) –
- advance_to_item(i)¶
Makes the list be at least i in size
- Parameters:
i (int) –
- Return type:
None
- exhaust()¶
Load all elements of this iterator into memory.
- Return type:
None
- exhausted¶
- internal_pointer¶
- iterator¶
- list¶
- class satella.coding.sequences.Multirun(sequence, dont_return_list=False)¶
Bases:
object
A class to launch the same operation on the entire sequence.
Consider:
>>> class Counter: >>> def __init__(self, value=0): >>> self.count = value >>> def add(self, v): >>> self.count += 1 >>> def __eq__(self, other): >>> return self.count == other.count >>> def __iadd__(self, other): >>> self.add(other) >>> a = [Counter(), Counter()]
The following:
>>> for b in a: >>> b.add(2)
Can be replaced with
>>> Multirun(a).add(2)
And the following:
>>> for b in a: >>> b += 3
With this
>>> b = Mulirun(a) >>> b += 3
Furthermore note that:
>>> Multirun(a).add(2) == [Counter(2), Counter(2)]
- Parameters:
sequence (Iterable) – sequence to execute these operations for
dont_return_list (bool) – the operation won’t return a list if this is True
- dont_return_list¶
- sequence¶
- class satella.coding.sequences.RollingArithmeticAverage(n=100)¶
Bases:
object
A class to implement a rolling arithmetic average over n last entries
- Parameters:
n (int) – amount of last entries to count
- avg()¶
Compute current average
- Returns:
current average
- Raises:
ZeroDivisionError – the average buffer is empty
- Return type:
float
- clear()¶
Clear the rolling average buffer
- Return type:
None
- insert(x)¶
Add a value to the rolling average, discarding the previous entry if the buffer size is exceeded
- Parameters:
x (float) – sample to insert
- Return type:
None
- n¶
- queue¶
- tot_sum¶
- satella.coding.sequences.add_next(lst, wrap_over=False, skip_last=False)¶
Yields a 2-tuple of given iterable, presenting the next element as second element of the tuple.
The last element will be the last element alongside with a None, if wrap_over is False, or the first element if wrap_over was True
Example:
>>> list(add_next([1, 2, 3, 4, 5])) == [(1, 2), (2, 3), (3, 4), (4, 5), (5, None)] >>> list(add_next([1, 2, 3, 4, 5], True)) == [(1, 2), (2, 3), (3, 4), (4, 5), (5, 1)]
- Parameters:
lst (Union[Iterator[T], Iterable[T]]) – iterable to iterate over
wrap_over (bool) – whether to attach the first element to the pair of the last element instead of None
skip_last (bool) – if this is True, then last element, alongside with a None, won’t be output
- Return type:
Iterator[Tuple[T, Optional[T]]]
- satella.coding.sequences.append_sequence(seq, *elems_to_append)¶
Return an iterator which append elem_to_append to every tuple in seq.
Example:
>>> a = [(1, ), (2, ), (3, )] >>> assert list(append_sequence(a, 1, 2)) == [(1, 1, 2), (2, 1, 2), (3, 1, 2)]
If every element of seq is not a tuple, it will be cast to one.
- Parameters:
seq (Iterator[tuple]) – sequence to append
elems_to_append – element(s) to append
- Returns:
an iterator
- Return type:
Iterator[tuple]
- satella.coding.sequences.choose(filter_fun, iterable, check_multiple=False)¶
Return a single value that exists in given iterable.
Essentially the same as:
>>> next(iter(filter(filter_fun, iterable)))
but raises a different exception if nothing matches (and if there are multiple matches and check_multiple is True). If check_multiple is True this guarantees to exhaust the generator (if passed).
- Parameters:
filter_fun (Callable[[T], bool]) – function that returns bool on the single value
iterable (Union[Iterator[T], Iterable[T]]) – iterable to examine
check_multiple (bool) – if True, this will check if there are multiple entries matching filter_fun, and will raise ValueError if so. If True, this will exhaust the iterator. If left at default, False, this may not exhaust the iterator.
- Returns:
single element in the iterable that matches given input
- Raises:
ValueError – on multiple elements matching (if check_multiple), or none at all
- Return type:
T
- satella.coding.sequences.choose_one(filter_fun, iterable)¶
Syntactic sugar for
>>> choose(filter_fun, iterable, check_multiple=True)
This exhausts the iterable.
- Parameters:
filter_fun (Callable[[T], bool]) – function that returns bool on the single value
iterable (Union[Iterator[T], Iterable[T]]) – iterable to examine
- Returns:
single element in the iterable that matches given input
- Raises:
ValueError – on multiple elements matching, or none at all
- Return type:
T
- satella.coding.sequences.choose_with_index(filter_fun, iterable)¶
Return a first found single value that exists in given iterable and filter_fun called on it returns True
- Parameters:
filter_fun (Callable[[T], bool]) – function that returns bool on the single value
iterable (Union[Iterator[T], Iterable[T]]) – iterable to examine
- Returns:
a tuple of (element, index)
- Raises:
ValueError – element not found
- Return type:
Tuple[T, int]
- satella.coding.sequences.count(sq, start=None, step=1, start_at=None)¶
Return a sequence of integers, for each entry in the sequence with provided step.
Essentially the same (if step were ignored) as:
>>> (i for i, x in enumerate(sq, start=start_at))
Deprecated since version 2.14.22: Use start instead
- Parameters:
sq (Union[Iterator[T], Iterable[T]]) – sequence to enumerate
start (Optional[int]) – alias for start_at. Prefer it in regards to start_at. Default is 0
step (int) – number to add to internal counter after each element
start_at (Optional[int]) – deprecated alias for start
- Returns:
an iterator of subsequent integers
- Return type:
Iterator[int]
- satella.coding.sequences.enumerate2(iterable, start=0, step=1)¶
Enumerate with a custom step
- Parameters:
iterable (Union[Iterator[T], Iterable[T]]) – iterable to enumerate
start (int) – value to start at
step (int) – step to add during each iteration
- Return type:
Iterator[Tuple[int, T]]
- satella.coding.sequences.even(sq)¶
Return only elements with even indices in this iterable (first element will be returned, as indices are counted from 0)
- Parameters:
sq (Union[Iterator[T], Iterable[T]]) –
- Return type:
Iterator[T]
- satella.coding.sequences.f_range(*args)¶
A range() that supports float.
Note that this behaves correctly when given a negative step.
Call either:
>>> f_range(stop) # will start from 0 and step 1 >>> f_range(start, stop) # will start from start and continue until the result is gte stop >>> # will start from start and continue by step until the result is gte stop >>> f_range(start, stop, step)
- Raises:
TypeError – invalid number of arguments
- Parameters:
args (float) –
- Return type:
Iterator[float]
- satella.coding.sequences.filter_out_false(y)¶
Return all elements, as a list, that are True
- Parameters:
y (Sequence[T]) – a sequence of items
- Returns:
a list of all subelements, in order, that are not None
- Return type:
List[T]
- satella.coding.sequences.filter_out_nones(y)¶
Return all elements, as a list, that are not None
- Parameters:
y (Sequence[T]) – a sequence of items
- Returns:
a list of all subelements, in order, that are not None
- Return type:
List[T]
- satella.coding.sequences.group_quantity(length, seq)¶
Slice an iterable into lists containing at most len entries.
Eg.
>>> assert list(group_quantity(3, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])) == [[1, 2, 3], [4, 5, 6], >>> [7, 8, 9], [10]]
This correctly detects sequences, and uses an optimized variant via slicing if a sequence is passed.
You can safely pass ranges
- Parameters:
length (int) – p_len for the returning sequences
seq (Union[Iterator[T], Iterable[T]]) – sequence to split
- Return type:
Iterator[List[T]]
- satella.coding.sequences.half_cartesian(seq, include_same_pairs=True)¶
Generate half of the Cartesian product of both sequences.
Useful when you have a commutative operation that you’d like to execute on both elements (eg. checking for collisions).
Example:
>>> list(half_cartesian([1, 2, 3], [1, 2, 3])) == >>> [(1, 1), (1, 2), (1, 3), (2, 2), (2, 3), (3, 3)]
- Parameters:
seq (Iterable[T]) – The sequence
include_same_pairs (bool) – if True, then pairs returning two of the same objects will be returned. For example, if False, the following will be true:
- Return type:
Iterator[Tuple[T, T]]
>>> list(half_cartesian([1, 2, 3], [1, 2, 3], include_same_pairs=False)) == >>> [(1, 2), (1, 3), (2, 3)]
- satella.coding.sequences.index_of(predicate, seq)¶
Return an index of first met element that calling predicate on it returns True
- Parameters:
predicate (Callable[[T], bool]) – predicate to apply
seq (Sequence[T]) – sequence to examine
- Returns:
index of the element
- Raises:
ValueError – if no element found
- Return type:
int
- satella.coding.sequences.index_of_max(seq)¶
Return the index of the maximum element
- Parameters:
seq (Sequence[T]) – sequence to examine
- Returns:
index of the maximum element
- Raises:
ValueError – sequence was empty
- Return type:
int
- satella.coding.sequences.infinite_counter(start_at=0, step=1)¶
Infinite counter, starting at start_at
Deprecated since version 2.14.22: Use itertools.count instead.
- Parameters:
start_at (int) – value at which to start counting. It will be yielded as first
step (int) – step by which to progress the counter
- Return type:
Iterator[int]
- satella.coding.sequences.infinite_iterator(returns=None, return_factory=None)¶
Return an infinite number of objects.
- Parameters:
returns (Optional[T]) – object to return. Note that this will be this very object, it will not be copied.
return_factory (Optional[Callable[[], T]]) – a callable that takes 0 args and returns an element to return.
- Returns:
an infinite iterator of provided values
- Return type:
Iterator[T]
- satella.coding.sequences.is_empty(iterable, exhaust=True)¶
Checks whether an iterator is empty.
This will exhaust the iterator if exhaust is left at default, or True
- Parameters:
iterable (Union[Iterator[T], Iterable[T]]) – iterator to check
exhaust (bool) – if set to False, at most a single element will be consumed from the iterator
- Returns:
whether the iterator is empty
- Return type:
bool
- satella.coding.sequences.is_instance(classes)¶
- Parameters:
classes (Union[Tuple[type, ...], type]) –
- Return type:
Callable[[object], bool]
- satella.coding.sequences.is_last(lst)¶
Return every element of the list, alongside a flag telling is this the last element.
Use like:
>>> for is_last, element in is_last(my_list): >>> if is_last: >>> ...
- Parameters:
lst (Union[Iterator[T], Iterable[T]]) – list to iterate thru
- Returns:
a p_gen returning (bool, T)
- Return type:
Iterator[Tuple[bool, T]]
Note that this returns a nice, O(1) iterator.
- satella.coding.sequences.iter_dict_of_list(dct)¶
Presents a simple way to iterate over a dictionary whose values are lists.
This will return the dictionary key and each of the value contained in the list attached to the key.
- Parameters:
dct (Dict[T, List[U]]) –
- Return type:
Generator[Tuple[T, U], None, None]
- satella.coding.sequences.iterate_callable(clbl, start_from=0, exc_classes=(<class 'IndexError'>, <class 'ValueError'>))¶
Given a callable that accepts an integer and returns the n-th entry, iterate over it until it starts to throw some exception.
- Parameters:
clbl (Callable[[int], V]) – callable to call
start_from (int) – number to start from
exc_classes – exceptions that being thrown show that the list was exhausted
- Returns:
an iterator
- Return type:
Iterator[V]
- satella.coding.sequences.length(iterator)¶
Return the length of an iterator, exhausting it by the way
- Parameters:
iterator (Union[Iterator[T], Iterable[T]]) –
- Return type:
int
- satella.coding.sequences.make_list(element, n, deep_copy=False)¶
Make a list consisting of n times element. Element will be copied via copy.copy before adding to list.
- Parameters:
element (T) – element
n (int) – times to repeat the element
deep_copy (bool) – whether to use copy.deepcopy instead of copy.copy
- Returns:
list of length n
- Return type:
List[T]
- satella.coding.sequences.map_list(fun, iterable)¶
A syntactic sugar for
>>> list(map(fun, iterable))
- Parameters:
fun (Callable) – function to apply
iterable (Union[Iterator[T], Iterable[T]]) – iterable to iterate over
- Return type:
List
- satella.coding.sequences.n_th(iterator, n=0)¶
Obtain n-th element (counting from 0) of an iterable
- Parameters:
iterator (Union[Iterator[T], Iterable[T]]) – iterable to process
n (int) – element to return. Note that we’re counting from 0
- Raises:
IndexError – iterable was too short
- Return type:
T
- satella.coding.sequences.odd(sq)¶
Return only elements with odd indices in this iterable.
- Parameters:
sq (Union[Iterator[T], Iterable[T]]) –
- Return type:
Iterator[T]
- satella.coding.sequences.other_sequence_no_longer_than(base_sequence, other_sequence)¶
Return every item in other_sequence, but limit it’s p_len to that of base_sequence.
If other_sequence is shorter than base_sequence, the shorter one will be returned.
- Parameters:
base_sequence (Union[Iterator[T], Iterable[T]]) – sequence whose p_len should be taken
other_sequence (Union[Iterator[T], Iterable[T]]) – sequence to output values from
- Return type:
Iterator[T]
- satella.coding.sequences.shift(iterable_, shift_factor)¶
Return this sequence, but shifted by factor elements, so that elements will appear sooner by factor.
Eg:
>>> assert list(shift([1,2, 3], 1)) == [2, 3, 1]
However note that this will result in iterators which have negative shift to be readed entirely into memory (converted internally to lists). This can be avoided by passing in a Reversible iterable.
- Parameters:
iterable – iterable to shift
shift_factor (int) – factor by which shift elements.
iterable_ (Union[Reversible[T], Iterator[T], Iterable[T]]) –
- Returns:
shifted sequence
- Return type:
Iterator[T]
- satella.coding.sequences.skip_first(iterator, n)¶
Skip first n elements from given iterator.
Returned iterator may be empty, if source iterator is shorter or equal to n.
Deprecated since version 2.14.22: Use itertools.islice instead
- Parameters:
iterator (Union[Iterator[T], Iterable[T]]) –
n (int) –
- Return type:
Iterator[T]
- satella.coding.sequences.smart_enumerate(iterator, start=0, step=1)¶
An enumerate that talks pretty with lists of tuples. Consider
>>> a = [(1, 2), (3, 4), (5, 6)] >>> for i, b in enumerate(a): >>> c, d = b >>> ...
This function allows you just to write: >>> for i, c, d in enumerate(a): >>> …
Note that elements in your iterable must be either a list of a tuple for that to work, or need to be able to be coerced to a tuple. Otherwise, TypeError will be thrown.
- Parameters:
iterator (Union[Iterator[T], Iterable[T]]) – iterator to enumerate
start (int) – value to start counting at
step (int) – step to advance the enumeration with
- Raises:
TypeError – could not coerce the elements in your iterable to a tuple
- Return type:
Iterator[Tuple]
- satella.coding.sequences.smart_zip(*iterators)¶
Zip in such a way that resulted tuples are automatically expanded.
Ie:
>>> b = list(smart_zip([(1, 1), (1, 2)], [1, 2])) >>> assert b == [(1, 1, 1), (1, 2, 2)]
Note that an element of the zipped iterator must be a tuple (ie. isinstance tuple) in order for it to be appended to resulting iterator element!
Deprecated since version Use: the for (a, b), c syntax instead.
- Parameters:
iterators (Union[Iterator[T], Iterable[T]]) – list of iterators to zip together
- Returns:
an iterator zipping the arguments in a smart way
- Return type:
Iterator[Tuple[T, …]]
- satella.coding.sequences.stop_after(iterator, n)¶
Stop this iterator after returning n elements, even if it’s longer than that.
The resulting iterator may be shorter than n, if the source element is so.
Deprecated since version 2.14.22: Use itertools.islice instead
- Parameters:
iterator (Union[Iterator[T], Iterable[T]]) – iterator or iterable to examine
n (int) – elements to return
- Return type:
Iterator[T]
- satella.coding.sequences.take_n(iterator, n, skip=0)¶
Take (first) n elements of an iterator, or the entire iterator, whichever comes first
- Parameters:
iterator (Union[Iterator[T], Iterable[T]]) – iterator to take from
n (int) – amount of elements to take
skip (int) – elements from the start to skip
- Returns:
list of p_len n (or shorter)
- Return type:
List[T]
- satella.coding.sequences.to_iterator(fun)¶
Convert function to an iterator. You can replace the following code:
>>> def iterator(x): >>> for y in x: >>> yield fun(y)
with
>>> @to_iterator >>> def fun(y): >>> ...
and now call fun instead of iterator. fun will accept a single argument - the iterable, and assume that the function you decorate also takes a single argument - the item
- satella.coding.sequences.try_close(iterator)¶
Try to invoke close() on an iterator. Do nothing if provided iterator doesn’t have a .close() method.
- Parameters:
iterator (Iterator) – iterator to close
- Return type:
None
- satella.coding.sequences.unique(lst)¶
Return each element from lst, but return every element only once.
Take care for elements of T to be __eq__-able and hashable!
This will keep internally a set of elements encountered, and skip them if same element appears twice
- Parameters:
lst (Union[Iterator[T], Iterable[T]]) – iterable to process
- Returns:
a generator yielding unique items from lst
- Return type:
Iterator[T]
- satella.coding.sequences.walk(obj, child_getter=<class 'list'>, deep_first=True, leaves_only=False)¶
Return every node of a nested structure.
- Parameters:
obj (T) – structure to traverse. This will not appear in generator
child_getter (Callable[[T], Optional[List[T]]]) – a callable to return a list of children of T. Should return an empty list or None of there are no more children.
deep_first (bool) – if True, deep first will be returned, else it will be breadth first
leaves_only (bool) – if True, only leaf nodes (having no children) will be returned
- Return type:
Iterator[T]
- satella.coding.sequences.zip_shifted(*args)¶
Construct an iterator, just like zip but first by cycling it’s elements by it’s shift factor. Elements will be shifted by a certain factor, this means that they will appear earlier.
Example:
>>> zip_shifted(([1, 2, 3, 4], 1), ([1, 2, 3, 4], 0)) == [(2, 1), (3, 2), (4, 3), (1, 4)]
This will work on arbitrary iterators and iterables.
Shift can be negative, in which case the last elements will appear sooner, eg.
>>> zip_shifted(([1, 2, 3, 4], -1), ([1, 2, 3, 4], 0)) == [(4, 1), (1, 2), (2, 3), (3, 4)]
Same memory considerations as
shift()
apply.The resulting iterator will be as long as the shortest sequence.
Deprecated since version 2.14.22: Use zip(shift(…)) instead
- Parameters:
args (Union[Iterator[T], Iterable[T], Tuple[Union[Iterator[T], Iterable[T]], int]]) – a tuple with the iterator/iterable and amount of shift. If a non-tuple is given, it is assumed that the shift is zero.
- Return type:
Iterator[Tuple[T, …]]