Source code for qupulse.utils

"""This package contains utility functions and classes as well as custom sympy extensions(hacks)."""

from typing import Union, Iterable, Any, Tuple, Mapping
import itertools
import re
import numbers
from collections import OrderedDict

import numpy

try:
    from math import isclose
except ImportError:
    # py version < 3.5
    isclose = None

__all__ = ["checked_int_cast", "is_integer", "isclose", "pairwise", "replace_multiple"]


[docs]def checked_int_cast(x: Union[float, int, numpy.ndarray], epsilon: float=1e-6) -> int: if isinstance(x, numpy.ndarray): if len(x) != 1: raise ValueError('Not a scalar value') if isinstance(x, int): return x int_x = int(round(x)) if abs(x - int_x) > epsilon: raise ValueError('No integer', x) return int_x
[docs]def is_integer(x: numbers.Real, epsilon: float=1e-6) -> bool: return abs(x - int(round(x))) < epsilon
def _fallback_is_close(a, b, *, rel_tol=1e-09, abs_tol=0.0): """Copied from https://docs.python.org/3/library/math.html Does no error checks.""" return abs(a-b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol) # pragma: no cover if not isclose: isclose = _fallback_is_close
[docs]def pairwise(iterable: Iterable[Any], zip_function=itertools.zip_longest, **kwargs) -> Iterable[Tuple[Any, Any]]: """s -> (s0,s1), (s1,s2), (s2, s3), ... Args: iterable: Iterable to iterate over pairwise zip_function: Either zip or itertools.zip_longest(default) **kwargs: Gets passed to zip_function Returns: An iterable that yield neighbouring elements """ a, b = itertools.tee(iterable) next(b, None) return zip_function(a, b, **kwargs)
[docs]def replace_multiple(s: str, replacements: Mapping[str, str]) -> str: """Replace multiple strings at once. If multiple replacements overlap the precedence is given by the order in replacements. For pyver >= 3.6 (otherwise use OrderedDict) >>> assert replace_multiple('asdf', {'asd': '1', 'asdf', '2'}) == 'asd1' >>> assert replace_multiple('asdf', {'asdf': '2', 'asd', '1'}) == '2' """ rep = OrderedDict((re.escape(k), v) for k, v in replacements.items()) pattern = re.compile("|".join(rep.keys())) return pattern.sub(lambda m: rep[re.escape(m.group(0))], s)