Core

A colletion of iterable utilites.

Used to grow on the fly. Aims to provide general purpose abstract functionalities.

depth

Powerfull function to determine depth of iterable.

nestify

Return a nested container of obj of target depth.

itrify

Turn object into an iterable container if not already.

is_empty

Check if list ist empty.

Stringcrementor

Iterator of String + incremented Integer = Stringcrementor.

enum_to_2dix

Map a 1d range to a 2d index.

Index2D

Construct a callable object that maps a number to a 2d index.

zip_split

Split sequence into chunks returning a zipped-like order of elements.

group

Split iterable into chunks.

ittools.core.depth(arg, exclude=None)[source]

Powerfull function to determine depth of iterable.

Credit goes to: https://stackoverflow.com/a/35698158

Parameters
  • arg (Iterable) – Iterable of which nested depth is to be determined

  • exclude (Iterable, default=None) – Iterable of iterable types that should be ignored. If None, str are excluded.

Returns

Depth of depth.arg

Return type

int

Example

>>> depth([[2, 2], [2, [3, 3]], 1])
3

Using exclude to ignore tuples:

>>> depth([[2, 2], [2, (3, 3)], 1], exclude=(tuple,))
2
ittools.core.nestify(obj, target_depth, container=<class 'list'>)[source]

Return a nested container of obj of target depth.

Parameters
  • obj – obj which is to be put in a container

  • target_depth (Number) – Keep nesting object until nesting depth >= target_depth

  • container (Container) – Container (list, tuple, …) the nestify.obj is nested with.

Returns

Nested container object with the depth of nestify.target_depth

Return type

Container

Examples

Standard use case:

>>> nestify([1, 2, 3], 3)
[[[1, 2, 3]]]

Specifying the container to nest with:

>>> nestify([1, 2, 3], 3, tuple)
(([1, 2, 3],),)

Not all containers work with all objects especially when working with sets, since sets itself are not hashable they can not be nested.

>>> nestify([1, 2, 3], 3, set)
Traceback (most recent call last):
  File "/usr/lib/python3.6/doctest.py", line 1330, in __run
    compileflags, 1), test.globs)
  File "<doctest ittools.nestify[2]>", line 1, in <module>
    nestify([1, 2, 3], 3, set)
  File "/home/tze/Code/ittools/ittools.py", line 118, in nestify
    obj = container([obj])
TypeError: unhashable type: 'list'

Frozensets however can be nested:

>>> nestify(frozenset([1, 2, 2]), 3, frozenset)
frozenset({frozenset({frozenset({1, 2})})})
ittools.core.itrify(obj, container=<class 'list'>)[source]

Turn object into an iterable container if not already.

Strings will be itrified without splitting!

Only objects that are of type str or not of collections.abc.Sequence will be itrified.

Parameters
  • obj – Anything not a Sequence (except for str) will be containered as iterable.

  • container (Container, default=list) – Interable container designed to house itrify.obj.

Returns

containered obj. ( i.e. list(obj))

Return type

Container

Examples

Pretty much the same as list(('String',)):

>>> itrify('String')
['String']

A list is already iterable so this is futile:

>>> itrify([1, 2, 3], tuple)
[1, 2, 3]

Strings although iterable will be itrified as whole:

>>> itrify('String', tuple)
('String',)

The itrify.container of course, can be any callable container type:

>>> itrify('String', set)
{'String'}

Pandas is awesome they support out of the box data type transformation:

>>> import pandas as pd
>>> itrify(pd.Series([1,2,3]), set)
{1, 2, 3}
ittools.core.is_empty(lst)[source]

Check if list ist empty.

True if lst is an empty List. False otherwise. Works based on bool([]) == True.

Parameters

lst (list) – List to be checked for emptiness.

Returns

True if lst is an empty List. False otherwise.

Return type

bool

Examples

>>> is_empty([])
True
>>> is_empty([[], [1,2,3]])
False
>>> is_empty([[[[]]]])
True

Tuple is not a list (u dont say):

>>> is_empty(([], []))
False
class ittools.core.Stringcrementor(string='Stringcrementor ', start=0)[source]

Bases: object

Iterator of String + incremented Integer = Stringcrementor.

Returns string + integer of which the integer is incremented by one each time next() is called on the Stringcrementor object.

Parameters
  • string (str) – String/tag/label of what you want to be incremented i.e “Category”. Default: Stringcrementor

  • start (Number) – Starting number which is to be incremented. Default: 0

Returns

string + integer of which the integer is incremented.

Return type

str

Example

>>> strementor = Stringcrementor('The Answer is: ')
>>> for i in range(42):
...     pass # just kidding
>>> for i in range(3):
...     print(next(strementor))
The Answer is: 0
The Answer is: 1
The Answer is: 2
ittools.core.enum_to_2dix(number, shape)[source]

Map a 1d range to a 2d index.

Parameters
  • number (int) – Number to be mapped to a 2D index. Usually used with in some form of iteration.

  • shape (tuple) – 2 dimensional tuple defining an arrays 2d shape as in (rows, columns).

Returns

the 1d enumerate numberition mapped to a (row, column) 2d tuple

Return type

tuple

Note

Only the number of columns is actually used. Since this is designed to be used with 2D-Matrices however, it is left as 2D-shape for convenience.

This implies however, that you can actually use infinite number arguments altough your shape might imply only 3 rows.

Examples

Mapping range(6) to a 3,2 dimenstion array:

>>> for i in range(6):
...     print(i, '->', enum_to_2dix(i, (3,2)))
0 -> (0, 0)
1 -> (0, 1)
2 -> (1, 0)
3 -> (1, 1)
4 -> (2, 0)
5 -> (2, 1)

Mapping range(12) to a 3,4 dimenstion array:

>>> for i in range(12):
...     print(i, '->', enum_to_2dix(i, (3,4)))
0 -> (0, 0)
1 -> (0, 1)
2 -> (0, 2)
3 -> (0, 3)
4 -> (1, 0)
5 -> (1, 1)
6 -> (1, 2)
7 -> (1, 3)
8 -> (2, 0)
9 -> (2, 1)
10 -> (2, 2)
11 -> (2, 3)
class ittools.core.Index2D(shape)[source]

Bases: object

Construct a callable object that maps a number to a 2d index.

Parameters

shape (2-tuple) – tuple defining an array’s 2d shape as in (rows, columns)

Returns

the 1d enumerate position mapped to a (row, column) 2d tuple

Return type

tuple

Examples

>>> idx2d = Index2D((3, 2))
>>> for i in range(6):
...     print(i, '->', idx2d(i))
...
0 -> (0, 0)
1 -> (0, 1)
2 -> (1, 0)
3 -> (1, 1)
4 -> (2, 0)
5 -> (2, 1)
property shape

Tuple representing the shape of the Index2D object.

ittools.core.zip_split(sequence, chunks)[source]

Split sequence into chunks returning a zipped-like order of elements.

The last \(n\) chunks will be one item short of the rest, if the number of items in sequence is not an integer multiple of chunks. With \(n\) beeing:

\(n = \text{len}\left(\text{sequence}\right)- \left[\text{len}\left(\text{sequence}\right) \% \text{chunks}\right]\).

Parameters
  • sequence (Sequence) – The sequence to split into chunks.

  • chunks (int) – The number of splitted sequences created.

Yields

Generator – A generator object yielding the chunks of items in zip like order.

Examples

Simple demonstration:

>>> import ittools
>>> hi10 = 10 * ['hi']
>>> print(list(ittools.zip_split(hi10, 3)))
[['hi', 'hi', 'hi', 'hi'], ['hi', 'hi', 'hi'], ['hi', 'hi', 'hi']]

Use case for turning a (supposedly) long iterable into a pandas.DataFrame of 3 rows:

>>> import ittools
>>> import pandas as pd
>>> print(pd.DataFrame(list(ittools.zip_split(hi10, 3))).to_string(
...     index=False, header=False))
hi hi hi   hi
hi hi hi None
hi hi hi None
ittools.core.group(iterable, chunks, fillvalue=None)[source]

Split iterable into chunks.

If the number of items in iterable is not an integer multiple of chunks, the last chunk is filled using fillvalue.

Parameters
  • iterable (Iterable) – The iterable to split into groups.

  • chunks (int) – The number of groups created

  • fillvalue (Number, None, default = None) – The last chunk is filled with this in case the number of items in iterable is not an integer multiple of chunks

Returns

A generator object yielding the groups.

Return type

Generator

Note

Credit to https://stackoverflow.com/a/434411 (Boris)

Examples

Simple example:

>>> import ittools
>>> print(list(ittools.group(range(10), chunks=3)))
[(0, 1, 2, 3), (4, 5, 6, 7), (8, 9, None, None)]

Use case for turning a(supposedly) long iterable into a pandas.DataFrame of 3 columns:

>>> import ittools
>>> import pandas as pd
>>> print(pd.DataFrame(list(zip(*ittools.group(range(10), 3)))).to_string(
...     index=False, header=False))
0 4 8.0
1 5 9.0
2 6 NaN
3 7 NaN