misc_utils

Commonly used miscellaneous utilities and helper functions.

class parityos.utils.misc_utils.SupportsLessThan(*args, **kwargs)

Bases: Protocol

class parityos.utils.misc_utils.Parity(value)

Bases: Enum

Parity as boolean in accordance with bit_to_spin_value.

even = False

even parity represented as False

odd = True

odd parity represented as True

parityos.utils.misc_utils.convert_to_iterator(elements: T | Iterable[T]) Iterator[T]

Wrap a single element or an iterable of elements in an Iterator.

parityos.utils.misc_utils.convert_to_tuple(elements: T | Iterable[T]) tuple[T, ...]

Wrap a single element or an iterable of elements in a tuple.

parityos.utils.misc_utils.convert_to_sorted_qubit_tuple(qubits: QubitT_co | Iterable[QubitT_co]) tuple[QubitT_co, ...]

Wrap a single Qubit or an iterable of Qubits in a tuple.

parityos.utils.misc_utils.convert_to_sorted_tuple(elements: SupportsLessThanT | Iterable[SupportsLessThanT]) tuple[SupportsLessThanT, ...]

Wrap a single element or an iterable of sortable elements in a tuple.

parityos.utils.misc_utils.convert_to_list(elements: T | Iterable[T]) list[T]

Wrap a single element or an iterable of elements in a list.

parityos.utils.misc_utils.convert_to_qubit_frozenset_validate_unique(qubits: QubitT_co | Iterable[QubitT_co]) frozenset[QubitT_co]

Convert input qubits to a frozenset of qubits and raise if there are duplicates.

Specialized version of convert_to_frozenset_validate_unique for qubits, aimed at showing correct signatures for classes in the documentation. Input elements can be a single qubit or an iterable of qubits.

Parameters:

qubits – The qubit(s) to be collected into a frozenset.

Returns:

frozenset of input qubits.

Raises:

ParityOSUniquenessError – If there are duplicate input qubits.

parityos.utils.misc_utils.convert_iterable_to_qubit_frozenset_validate_unique(qubits: Iterable[QubitT_co]) frozenset[QubitT_co]

Convert an iterable of qubits into a frozenset of qubits, raise if there are duplicates.

Specialized version of convert_iterable_to_frozenset_validate_unique for qubits, aimed at showing correct signatures for classes in the documentation.

Parameters:

qubits – An iterable of qubits to be turned into a frozenset.

Returns:

frozenset of input qubits.

Raises:
parityos.utils.misc_utils.convert_to_frozenset_validate_unique(elements: T | Iterable[T]) frozenset[T]

Convert input elements to a frozenset and raise if there are duplicates.

Input elements can be a single element or an iterable of elements.

Parameters:

elements – The element(s) to be turned into a frozenset.

Returns:

frozenset of input elements.

Raises:

ParityOSUniquenessError – If there are duplicate input elements.

parityos.utils.misc_utils.convert_iterable_to_frozenset_validate_unique(elements: Iterable[T]) frozenset[T]

Convert an iterable of elements to a frozenset and raise if there are duplicates.

Parameters:

elements – An iterable of elements to be turned into a frozenset.

Returns:

frozenset of input elements.

Raises:
parityos.utils.misc_utils.convert_to_unique_key_value_pair_items(elements: Iterable[tuple[KeyT, ValueT]] | Mapping[KeyT, ValueT]) ItemsView[KeyT, ValueT]

Convert an iterable of (key, value) pairs to a collections.abc.ItemsView of (key, value) pairs.

Pairs with the same key but different values are collected into a single pair by summing up the values.

Parameters:

elements – Iterable or mapping of (key, value) pairs.

Returns:

collections.abc.ItemsView of (key, value) pairs with no duplicate keys.

parityos.utils.misc_utils.collect_pairs(pairs: Iterable[tuple[KeyT, ValueT]]) ItemsView[KeyT, ValueT]

Remove duplicate first values in an iterable of pairs by collecting pairs with the same first value and summing their second values.

Caution

Zero value elements are not removed and need to be filtered out separately if necessary.

Parameters:

pairs – Pairs to be collected.

Returns:

collections.abc.ItemsView of collected pairs with no duplicate first values.

parityos.utils.misc_utils.stringify_iterable(iterable: Iterable[T], /, separator: str = ', ') str

Stringify a sequence of elements.

This is different from e.g. str([obj1, obj2, obj3]) as Python stringifies containers by always using “, “ as separator and calling the elements’ __repr__ instead of __str__ method.

Examples

>>> from parityos.bits import get_q
>>> from parityos.utils.misc_utils import stringify_iterable
>>> assert stringify_iterable((3,)) == "3"
>>> assert stringify_iterable(("a", "b")) == "a, b"
>>> assert stringify_iterable([get_q(0), get_q(1)]) == "q_0, q_1"
>>> assert stringify_iterable((get_q(0), get_q(1)), separator="|") == "q_0|q_1"
Parameters:
  • iterable – Elements of a sequence to be stringified

  • separator – Separator to put between stringified elements. Keyword-only.

Returns:

Stringified iterable.

parityos.utils.misc_utils.is_iterable_of_pairs_mapping(obj: Iterable[tuple[KeyT, T]] | Mapping[KeyT, T]) TypeIs[Mapping[KeyT, T]]

Return whether a passed object is a collections.abc.Mapping.

The main purpose of this method is the typing.TypeIs return type used for type narrowing.

Parameters:

obj – Object to check.

Returns:

Whether obj is a collections.abc.Mapping.

parityos.utils.misc_utils.bit_to_spin_value(bit: bool) int

Transform computational state bit to spin eigenvalue.

Transformation follows the convention

  • \(|+S\rangle\) = \(|0\rangle\) = False

  • \(|-S\rangle\) = \(|1\rangle\) = True

with \(|+S\rangle\), \(|-S\rangle\) the spin operator eigenstates in Pauli basis \(S \in \{X, Y, Z\}\) and \(|0\rangle\), \(|1\rangle\) the computational basis states.

Parameters:

bit – Bit to convert to integer spin eigenvalue.

Returns:

Transformed spin eigenvalue of bit.

parityos.utils.misc_utils.bipartitions(items: Set[T], n: int) Iterator[tuple[frozenset[T], frozenset[T]]]

Generate all possible bipartitions of a set items of N objects into two ordered partitions (A, B) of size n and N - n, such that their intersection is empty and their union is items.

The order in (A, B) matters, i.e. (A, B) is considered different from (B, A).

Parameters:
  • items – Set of objects to partition.

  • n – Size of first partition.

Yields:

Pair (A, B) of partitions of items, where len(A) = n and len(B) = len(items) - n.

parityos.utils.misc_utils.fast_astuple(obj: AttrsInstance) tuple[Any, ...]

Fast version of attrs.astuple with no recursion, filters and input checks.

Parameters:

objattrs class instance.

Returns:

A tuple containing obj’s attributes.

parityos.utils.misc_utils.fast_asdict(obj: AttrsInstance) dict[str, Any]

Fast version of attrs.asdict with no recursion, filters and input checks.

Parameters:

objattrs class instance.

Returns:

A dict mapping obj’s attribute names to their values.

parityos.utils.misc_utils.get_abstract_classvars(cls: type) frozenset[str]

Get names of abstract typing.ClassVar attributes in cls.

Abstract class variables are attributes annotated as typing.ClassVar, but are not assigned a value. In contrast to abc.abstractmethod, Python has no built-in mechanism to check for such abstract class variables.

This function collects all such abstract class variables from all of cls’s base classes and returns those that are not implemented (i.e. assigned a definite value). It does so by

  • fetching all annotations from cls and all its base classes

  • filtering out those that are typing.ClassVar

  • filtering out those that are also present in cls’s vars (i.e. they are assigned a

    concrete value)

This constitutes a check for unimplemented abstract class variables.

Parameters:

cls – The class for which to return unimplemented abstract class variables.

Returns:

A frozenset of names of all abstract class variables that are not implemented.

parityos.utils.misc_utils.get_module_classes(module: ModuleType) list[type]

Get all classes that are defined in module module.

Only classes implemented directly in module are returned, any imported classes are skipped.

Parameters:

module – Module from which to get all classes.

Returns:

A list of all classes defined in module.