pytoolbox.collections module

pytoolbox.collections.swap_dict_of_values(the_dict, type=<class 'set'>, method=<method 'add' of 'set' objects>)[source]

Return a dictionary (collections.defaultdict) with keys and values swapped.

This algorithm expect that the values are a container with objects, not a single object. Set type to None if values are unique and you want keys to be the values.

Example usage

Simple swap:

>>> swap_dict_of_values({'odd': [1, 3], 'even': (0, 2)}, type=None)
{1: 'odd', 3: 'odd', 0: 'even', 2: 'even'}

Complex swap:

>>> def S(value):
...     return {k: sorted(v) for k, v in sorted(value.items())}
...
>>> S(swap_dict_of_values(
...     {'odd': [1, 3], 'even': (0, 2), 'fib': {1, 2, 3}},
...     type=list,
...     method=list.append))
{0: ['even'], 1: ['fib', 'odd'], 2: ['even', 'fib'], 3: ['fib', 'odd']}
>>> swap_dict_of_values({'o': [1, 3], 'e': (0, 2), 'f': {2, 3}}, method='add')[2] == {'f', 'e'}
True
>>> swap_dict_of_values({'bad': 'ab', 'example': 'ab'})['a'] == {'bad', 'example'}
True
pytoolbox.collections.merge_dicts(*dicts)[source]

Return a dictionary from multiple dictionaries.

Warning

This operation is not commutative.

Example usage

>>> merge_dicts({'a': 1, 'b': 2}, {'b': 3, 'c': 4}, {'c': 5})
{'a': 1, 'b': 3, 'c': 5}
>>> merge_dicts({'c': 5}, {'b': 3, 'c': 4}, {'a': 1, 'b': 2})
{'c': 4, 'b': 2, 'a': 1}
pytoolbox.collections.window(values, index, delta)[source]

Extract 1+2*`delta` items from values centered at index and return a tuple with (items, left, right).

This function tries to simulate a physical slider, meaning the number of extracted elements is constant but the centering at index is not guaranteed.

A visual example with 6 values and delta=1:

index = 0  [+++]---  left = 0, right = 2
index = 1  [+++]---  left = 0, right = 2
index = 2  -[+++]--  left = 1, right = 3
index = 3  --[+++]-  left = 2, right = 4
index = 4  ---[+++]  left = 3, right = 5
index = 5  ---[+++]  left = 3, right = 5

Example usage

>>> window(['a'], 0, 2)
(['a'], 0, 0)
>>> window(['a', 'b', 'c', 'd'], 2, 0)
(['c'], 2, 2)
>>> window(['a', 'b', 'c', 'd', 'e'], 0, 1)
(['a', 'b', 'c'], 0, 2)
>>> window(['a', 'b', 'c', 'd', 'e'], 1, 1)
(['a', 'b', 'c'], 0, 2)
>>> window(['a', 'b', 'c', 'd', 'e'], 2, 1)
(['b', 'c', 'd'], 1, 3)
>>> window(['a', 'b', 'c', 'd', 'e'], 3, 1)
(['c', 'd', 'e'], 2, 4)
>>> window(['a', 'b', 'c', 'd', 'e'], 4, 1)
(['c', 'd', 'e'], 2, 4)
>>> window(['a', 'b', 'c', 'd', 'e'], 3, 6)
(['a', 'b', 'c', 'd', 'e'], 0, 4)
>>> data = list(range(20))
>>> window(data, 6, 6)
([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], 0, 12)
>>> window(data, 7, 6)
([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], 1, 13)
>>> window(data, 10, 6)
([4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], 4, 16)
>>> window(data, 19, 6)
([7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], 7, 19)
class pytoolbox.collections.EventsTable(sparse_events_table, time_range, time_speedup, sleep_factor=1.0)[source]

Bases: object

Scan a spare events table and replace missing entry by previous (non empty) entry.

__init__(sparse_events_table, time_range, time_speedup, sleep_factor=1.0)[source]
get(time, time_speedup=None, default_value=None)[source]
sleep_time(time, time_speedup=None, sleep_factor=None)[source]

Return required sleep time to wait for next scheduled event.

Example usage

>>> table = EventsTable({0: 'salut'}, 24, 60)
>>> table.sleep_time(1)
59
>>> table.sleep_time(58)
2
>>> table.sleep_time(60)
60
>>> table.sleep_time(62)
58
>>> table.sleep_time(3590, time_speedup=1)
10
>>> table.sleep_time(12543, time_speedup=1)
1857
>>> table.sleep_time(12543, time_speedup=1, sleep_factor=2)
57
>>> table.sleep_time(12600, time_speedup=1, sleep_factor=2)
1800
>>> table.sleep_time(1, time_speedup=60, sleep_factor=1)
59
>>> table.sleep_time(1, time_speedup=60, sleep_factor=2)
29
>>> table.sleep_time(30, time_speedup=60, sleep_factor=2)
30
>>> table.time_range = 1
>>> table.sleep_time(1, time_speedup=1)
149
class pytoolbox.collections.pygal_deque[source]

Bases: deque

A deque None’ing duplicated values to produce nicer pygal line charts (e.g. 5555322211111 -> 5__532_21___1).

Warning

Not yet implemented:

  • appendleft(x)

  • clear()

  • count(x)

  • extend(iterable)

  • extendleft(iterable)

  • pop()

  • popleft()

  • remove(value)

  • reverse()

  • rotate(n)

last = None
append(value)[source]

Add an element to the right side of the deque.

list(fill=False)[source]
pytoolbox.collections.flatten_dict(the_dict, key_template='{0}.{1}')[source]

Flatten the keys of a nested dictionary. Nested keys will be appended iteratively using given key_template.

Example usage

>>> flatten_dict({'a': 'b', 'c': 'd'})
{'a': 'b', 'c': 'd'}
>>> flatten_dict({'a': {'b': {'c': ['d', 'e']}, 'f': 'g'}})
{'a.b.c': ['d', 'e'], 'a.f': 'g'}
>>> flatten_dict({'a': {'b': {'c': ['d', 'e']}, 'f': 'g'}}, '{1}-{0}')
{'c-b-a': ['d', 'e'], 'f-a': 'g'}
pytoolbox.collections.to_dict_of_values(iterable, type=<class 'list'>, method=<method 'append' of 'list' objects>)[source]

Return a dictionary (collections.defaultdict) with key, value pairs merged as key -> values.

Example usage

>>> from pytoolbox.unittest import asserts
>>> asserts.dict_equal(
...     to_dict_of_values([('odd', 1), ('odd', 3), ('even', 0), ('even', 2)]),
...     {'even': [0, 2], 'odd': [1, 3]})
>>> asserts.dict_equal(
...     to_dict_of_values((('a', 1), ('a', 1), ('a', 2)), type=set, method=set.add),
...     {'a': {1, 2}})