Containers

Contents

pyavia.containers.AttrDict AttrDict is a dictionary class that also allows access using attribute notation.
pyavia.containers.MultiBiDict Bi-directional dict class.
pyavia.containers.ValueRange Represents any range of scalar values (units agnostic).
pyavia.containers.wdg_edge alias of builtins.slice
pyavia.containers.WtDirGraph A weighted directed graph where a value / weight can be assigned to any link / edge between any two hashable nodes / keys.

Members

Adds useful, less common containers not available in the standard library.

class pyavia.containers.AttrDict

Bases: dict

AttrDict is a dictionary class that also allows access using attribute notation.

Examples

>>> my_dict = AttrDict([('make', 'Mazda'), ('model', '3')])
>>> my_dict['yom'] = 2007
>>> print(f"My car is a {my_dict.make} {my_dict.model} made in "
...       f"{my_dict.yom}.")
My car is a Mazda 3 made in 2007.
__delattr__

Delete self[key].

__dir__()

Default dir() implementation.

__getattr__(name)
__repr__()

Return repr(self).

__setattr__

Set self[key] to value.

class pyavia.containers.MultiBiDict(*args, **kwargs)

Bases: dict

Bi-directional dict class.

A forward and inverse dictionary are synchronised to allow searching by either key or value to get the corresponding value / key. Implementation from this StackOverflow answer: https://stackoverflow.com/a/21894086.

Notes

  • The inverse dict bidict_multi.inverse auto-updates itself when the normal dict bidict_multi is modified.
  • Inverse directory entries bidict_multi.inverse[value] are always lists of key such that bidict_multi[key] == value.
  • Multiple keys can have the same value.

Examples

>>> bd = MultiBiDict({'a': 1, 'b': 2})
>>> print(bd)
{'a': 1, 'b': 2}
>>> print(bd.inverse)
{1: ['a'], 2: ['b']}
>>> bd['c'] = 1         # Now two keys have the same value (= 1)
>>> print(bd)
{'a': 1, 'b': 2, 'c': 1}
>>> print(bd.inverse)
{1: ['a', 'c'], 2: ['b']}
>>> del bd['c']
>>> print(bd)
{'a': 1, 'b': 2}
>>> print(bd.inverse)
{1: ['a'], 2: ['b']}
>>> del bd['a']
>>> print(bd)
{'b': 2}
>>> print(bd.inverse)
{2: ['b']}
>>> bd['b'] = 3
>>> print(bd)
{'b': 3}
>>> print(bd.inverse)
{2: [], 3: ['b']}
__delitem__(key)

Delete self[key].

__init__(*args, **kwargs)
Parameters:args,kwargs (dict, optional) – Initialise the forward dict as dict(*args, **kwargs) if supplied. The inverse dict is then constructed.
__setitem__(key, value)

Set self[key] to value.

class pyavia.containers.ValueRange(*, x_min=None, x_max=None, x_mean=None, x_ampl=None)

Bases: object

Represents any range of scalar values (units agnostic).

__init__(*, x_min=None, x_max=None, x_mean=None, x_ampl=None)

Establish a range using any valid combination of two of the input arguments from x_min, x_max, x_mean, x_ampl.

Note

If minimum and maximum are reversed (or amplitude is negative) these will be automatically switched which may produce unexpected results.

Parameters:
  • x_min (scalar) – Range minimum.
  • x_max (scalar) – Range maximum.
  • x_mean (scalar) – Range mean.
  • x_ampl (scalar) – Range amplitude of variation (i.e. +/- value to superimpose on mean).
ampl

Computed amplitude.

mean

Computed mean value.

class pyavia.containers.WtDirGraph(links: Dict[Hashable, Dict[Hashable, Any]] = None)

Bases: object

A weighted directed graph where a value / weight can be assigned to any link / edge between any two hashable nodes / keys. Link values can be different in each direction (or completely absent), i.e. x →[value]→ y and x ←[reverse_value2]← y. Intended for sparse graphs. Implemented as a dict(x-keys)-of-dicts(y-keys), both forward and reverse values are therefore stored independently for each pair of keys.

Access to all links from a given key is the same as a dict, but access to a specific link between two keys uses the slice [:] notation. e.g.: wdg['a':'b'] returns the value between ab, whereas wdg['a'] returns a dict of all link / edge values starting at a i.e. {'b': 'somevalue', 'c': 'anotherval'}.

Note

Where slice / square bracket syntax cannot be used, alias wdg_edge(a, b) is defined as an alias of the builtin slice function. This is used to define a graph edge. e.g.: if wdg_edge(a, b) in wdg:.

Examples

>>> wdg = pa.WtDirGraph()
>>> wdg['a':'b'] = 'Here'
>>> print(wdg)
WtDirgraph({'a': {'b': 'Here'}, 'b': {}})
>>> print(wdg['a':'b'])
Here
>>> print(wdg['b':'a'])
Traceback (most recent call last):
...
KeyError: 'a'
>>> wdg['a':3.14159] = (22, 7)
>>> wdg['b':'c'] = 'it'
>>> wdg['c':'d'] = 'is.'
>>> path, joined = wdg.trace('a', 'd', op=lambda x, y: ' '.join([x, y]))
>>> print(path, joined)
['a', 'b', 'c', 'd'] Here it is.
>>> del wdg['a']
>>> print(wdg)
WtDirgraph({'b': {'c': 'it'}, 3.14159: {}, 'c': {'d': 'is.'}, 'd': {}})
__contains__(arg)

Returns True if a link value x → y exists (slice arg), or True if key exists (single arg). Because standalone slice notation is not available on the LHS, use the following syntax: wdg_edge(x, y) in wdg.

Parameters:arg (slice or key) – If slice, [from:to] otherwise key value x.
Returns:result
  • Slice arg: True if a link value xy exists, else False.
  • Key arg: True if key exists (single arg), else False.
Return type:bool
__delitem__(arg)

Delete link value for x → y (slice arg) or delete key x and all associated links (single arg).

Parameters:arg (slice or key) – If slice, [from:to] otherwise key value x.
Raises:KeyError – Invalid slice argument or if link/s do not exist.
__getitem__(arg: slice)

Get link value for x → y.

Parameters:arg (slice) – [from:to].
Returns:Link value.
Raises:KeyError – Invalid slice argument or link does not exist.
__init__(links: Dict[Hashable, Dict[Hashable, Any]] = None)

Construct a weighted directional graph.

Parameters:links

If provided this is to be a dict-of-dicts representing forward links. Each key corresponds to a dict holding other keys and the link value. Example:

>>> wdg = WtDirGraph({'a': {'b': 2, 'c': 5}, 'c': {'a': 4}})
>>> print(wdg['c':'a'])
4

Creates a graph with linkages of:

a -→ b  link value = 2
  |→ c  link value = 5
b -→    (no links)
c -→ a  link value = 4
__repr__()

Return repr(self).

__setitem__(arg: slice, value)

Set / overwrite link value for x → y.

Parameters:
  • arg (slice) – [from:to]
  • value – Link value.
Raises:

KeyError – Invalid slice argument (including path to nowhere x == y).

trace(x: Hashable, y: Hashable, op: Optional[Callable[[Any, Any], Any]] = None)

Trace shortest path between two existing keys x and y using a breath-first search (refer https://en.wikipedia.org/wiki/Breadth-first_search and https://www.python.org/doc/essays/graphs/).

If op is supplied, calculate the combined link / edge value by successively applying operator op to intermediate link values. E.G. To determine xz_val x →[xz_val]→ z we can compute xz_val = op(xy_val, yz_val) if we have x →[xy_val]→ y and y →[yz_val]→ z.

Parameters:
  • x,y (Hashable) – Starting and ending node / vertex / key.
  • op (Callable[[Any, Any], Any]], optional) – Operator that produces a combined value valid for any two link / edge values, i.e. result = op(val1, val2).
Returns:

  • path (List) – List of all points visited along the path including the end nodes, i.e. from x → y: [x, i, j, k, y]. If no path is found it is None.
  • path,value (Tuple[List, Any]) – If op is given, the path value is computed and returned along with the path list (as above), if the path covers more than one link. For direct links, the link value is returned. If op is given but no path is found this is also None.

Raises:

KeyError – If x or y are not verticies, or if x == y.

pyavia.containers.wdg_edge

alias of builtins.slice