Skip to content

math

frequenz.core.math ¤

Math tools.

Attributes¤

frequenz.core.math.LessThanComparableOrNoneT module-attribute ¤

LessThanComparableOrNoneT = TypeVar(
    "LessThanComparableOrNoneT",
    bound=LessThanComparable | None,
)

Type variable for a value that is LessThanComparable or None.

Deprecated

This type variable is deprecated and it will be removed in a future version. Use LessThanComparableT instead.

frequenz.core.math.LessThanComparableT module-attribute ¤

LessThanComparableT = TypeVar(
    "LessThanComparableT", bound=LessThanComparable
)

Type variable for a value that is LessThanComparable.

Classes¤

frequenz.core.math.Interval dataclass ¤

Bases: Generic[LessThanComparableT]

An interval to test if a value is within its limits.

The .start and .end are inclusive, meaning that the .start and .end limits are included in the range when checking if a value is contained by the interval.

If the .start or .end is None, it means that the interval is unbounded in that direction. None is used purely as a bound marker; it is never a value in the interval.

If .start is bigger than .end, a ValueError is raised.

The type stored in the interval must be comparable, meaning that it must implement the __lt__ method to be able to compare values.

Source code in src/frequenz/core/math.py
@dataclass(frozen=True, repr=False)
class Interval(Generic[LessThanComparableT]):
    """An interval to test if a value is within its limits.

    The [`.start`][.start] and [`.end`][.end] are inclusive, meaning that the
    [`.start`][.start] and [`.end`][.end] limits are included in the range when
    checking if a value is contained by the interval.

    If the [`.start`][.start] or [`.end`][.end] is `None`, it means that the interval
    is unbounded in that direction. `None` is used purely as a bound marker; it is
    never a value in the interval.

    If [`.start`][.start] is bigger than [`.end`][.end], a `ValueError` is raised.

    The type stored in the interval must be comparable, meaning that it must implement
    the `__lt__` method to be able to compare values.
    """

    start: LessThanComparableT | None
    """The start of the interval, or `None` to indicate no lower bound (-∞)."""

    end: LessThanComparableT | None
    """The end of the interval, or `None` to indicate no upper bound (+∞)."""

    def __post_init__(self) -> None:
        """Check if the start is less than or equal to the end."""
        if self.start is None or self.end is None:
            return
        if self.start > self.end:
            raise ValueError(
                f"The start ({self.start}) can't be bigger than end ({self.end})"
            )

    def __contains__(self, item: LessThanComparableT) -> bool:
        """Check if the value is within the range of the interval.

        Args:
            item: The value to check.

        Returns:
            True if value is within the range, otherwise False.
        """
        if self.start is not None and item < self.start:
            return False
        if self.end is not None and item > self.end:
            return False
        return True

    def __repr__(self) -> str:
        """Return a string representation of this instance."""
        return f"Interval({self.start!r}, {self.end!r})"

    def __str__(self) -> str:
        """Return a string representation of this instance."""
        start = "∞" if self.start is None else str(self.start)
        end = "∞" if self.end is None else str(self.end)
        return f"[{start}, {end}]"
Attributes¤
end instance-attribute ¤
end: LessThanComparableT | None

The end of the interval, or None to indicate no upper bound (+∞).

start instance-attribute ¤
start: LessThanComparableT | None

The start of the interval, or None to indicate no lower bound (-∞).

Methods:¤
__contains__ ¤
__contains__(item: LessThanComparableT) -> bool

Check if the value is within the range of the interval.

PARAMETER DESCRIPTION
item

The value to check.

TYPE: LessThanComparableT

RETURNS DESCRIPTION
bool

True if value is within the range, otherwise False.

Source code in src/frequenz/core/math.py
def __contains__(self, item: LessThanComparableT) -> bool:
    """Check if the value is within the range of the interval.

    Args:
        item: The value to check.

    Returns:
        True if value is within the range, otherwise False.
    """
    if self.start is not None and item < self.start:
        return False
    if self.end is not None and item > self.end:
        return False
    return True
__post_init__ ¤
__post_init__() -> None

Check if the start is less than or equal to the end.

Source code in src/frequenz/core/math.py
def __post_init__(self) -> None:
    """Check if the start is less than or equal to the end."""
    if self.start is None or self.end is None:
        return
    if self.start > self.end:
        raise ValueError(
            f"The start ({self.start}) can't be bigger than end ({self.end})"
        )
__repr__ ¤
__repr__() -> str

Return a string representation of this instance.

Source code in src/frequenz/core/math.py
def __repr__(self) -> str:
    """Return a string representation of this instance."""
    return f"Interval({self.start!r}, {self.end!r})"
__str__ ¤
__str__() -> str

Return a string representation of this instance.

Source code in src/frequenz/core/math.py
def __str__(self) -> str:
    """Return a string representation of this instance."""
    start = "∞" if self.start is None else str(self.start)
    end = "∞" if self.end is None else str(self.end)
    return f"[{start}, {end}]"

frequenz.core.math.LessThanComparable ¤

Bases: Protocol

A protocol that requires the __lt__ method to compare values.

Source code in src/frequenz/core/math.py
class LessThanComparable(Protocol):
    """A protocol that requires the `__lt__` method to compare values."""

    def __lt__(self, other: Self, /) -> bool:
        """Return whether self is less than other."""
Methods:¤
__lt__ ¤
__lt__(other: Self) -> bool

Return whether self is less than other.

Source code in src/frequenz/core/math.py
def __lt__(self, other: Self, /) -> bool:
    """Return whether self is less than other."""

Functions:¤

frequenz.core.math.is_close_to_zero ¤

is_close_to_zero(
    value: FloatInt, abs_tol: FloatInt = 1e-09
) -> bool

Check if a floating point value is close to zero.

A value of 1e-9 is a commonly used absolute tolerance to balance precision and robustness for floating-point numbers comparisons close to zero. Note that this is also the default value for the relative tolerance. For more technical details, see https://peps.python.org/pep-0485/#behavior-near-zero

PARAMETER DESCRIPTION
value

The floating point value to compare to.

TYPE: FloatInt

abs_tol

The minimum absolute tolerance. Defaults to 1e-9.

TYPE: FloatInt DEFAULT: 1e-09

RETURNS DESCRIPTION
bool

Whether the floating point value is close to zero.

Source code in src/frequenz/core/math.py
def is_close_to_zero(value: FloatInt, abs_tol: FloatInt = 1e-9) -> bool:
    """Check if a floating point value is close to zero.

    A value of 1e-9 is a commonly used absolute tolerance to balance precision
    and robustness for floating-point numbers comparisons close to zero. Note
    that this is also the default value for the relative tolerance.
    For more technical details, see https://peps.python.org/pep-0485/#behavior-near-zero

    Args:
        value: The floating point value to compare to.
        abs_tol: The minimum absolute tolerance. Defaults to 1e-9.

    Returns:
        Whether the floating point value is close to zero.
    """
    zero: float = 0.0
    return math.isclose(a=value, b=zero, abs_tol=abs_tol)