Skip to content

OutOfBoundsError

Bases: ValueError

A generic exception that can be used to signal that a (float) value is outside its expected range.

Parameters:

Name Type Description Default
actual float

The actual value that is outside its expected range.

required
name str | None

The name of the offending variable.

None
lower_bound Bound | None

The lower bound of the expected range. Use None if there is no lower Bound.

None
upper_bound Bound | None

The upper bound of the expected range. Use None if there is no upper Bound.

None
Source code in src/safeds/exceptions/_generic.py
class OutOfBoundsError(ValueError):
    """
    A generic exception that can be used to signal that a (float) value is outside its expected range.

    Parameters
    ----------
    actual: float
        The actual value that is outside its expected range.
    name: str | None
        The name of the offending variable.
    lower_bound: Bound | None
        The lower bound of the expected range. Use None if there is no lower Bound.
    upper_bound: Bound | None
        The upper bound of the expected range. Use None if there is no upper Bound.
    """

    def __init__(
        self,
        actual: float,
        *,
        name: str | None = None,
        lower_bound: Bound | None = None,
        upper_bound: Bound | None = None,
    ):
        """
        Initialize an OutOfBoundsError.

        Parameters
        ----------
        actual: float
            The actual value that is outside its expected range.
        name: str | None
            The name of the offending variable.
        lower_bound: Bound | None
            The lower bound of the expected range. Use None if there is no lower Bound.
        upper_bound: Bound | None
            The upper bound of the expected range. Use None if there is no upper Bound.

        Raises
        ------
        ValueError
            * If one of the given Bounds is +/-inf. (For infinite Bounds, pass None instead.)
            * If one of the given Bounds is nan.
            * If upper_bound < lower_bound.
            * If actual does not lie outside the given interval.
            * If actual is not a real number.
        """
        from numpy import isinf, isnan

        # Validate bound parameters:
        if lower_bound is None and upper_bound is None:
            raise ValueError("Illegal interval: Attempting to raise OutOfBoundsError, but no bounds given.")
        if (lower_bound is not None and isinf(lower_bound.value)) or (
            upper_bound is not None and isinf(upper_bound.value)
        ):
            raise ValueError("Illegal interval: Lower and upper bounds must be real numbers, or None if unbounded.")
        # Validate actual parameter:
        if isinf(actual) or isnan(actual):
            raise ValueError("Attempting to raise OutOfBoundsError with actual value not being a real number.")
        # Use local variables with stricter types to help static analysis:
        _lower_bound: Bound = lower_bound if lower_bound is not None else OpenBound(float("-inf"))
        _upper_bound: Bound = upper_bound if upper_bound is not None else OpenBound(float("inf"))
        # Check bounds:
        if _upper_bound.value < _lower_bound.value:
            raise ValueError(
                (
                    f"Illegal interval: Attempting to raise OutOfBoundsError, but given upper bound {_upper_bound} is "
                    f"actually less than given lower bound {_lower_bound}."
                ),
            )
        # Check that actual is indeed outside the interval:
        elif _lower_bound._check_lower_bound(actual) and _upper_bound._check_upper_bound(actual):
            raise ValueError(
                (
                    f"Illegal interval: Attempting to raise OutOfBoundsError, but value {actual} is not actually"
                    f" outside given interval {_lower_bound._str_lower_bound()}, {_upper_bound._str_upper_bound()}."
                ),
            )
        # Raise the actual exception:
        full_variable_name = actual if name is None else f"{name} (={actual})"
        super().__init__(
            f"{full_variable_name} is not inside {_lower_bound._str_lower_bound()}, {_upper_bound._str_upper_bound()}.",
        )

__init__(actual, *, name=None, lower_bound=None, upper_bound=None)

Initialize an OutOfBoundsError.

Parameters:

Name Type Description Default
actual float

The actual value that is outside its expected range.

required
name str | None

The name of the offending variable.

None
lower_bound Bound | None

The lower bound of the expected range. Use None if there is no lower Bound.

None
upper_bound Bound | None

The upper bound of the expected range. Use None if there is no upper Bound.

None

Raises:

Type Description
ValueError
  • If one of the given Bounds is +/-inf. (For infinite Bounds, pass None instead.)
  • If one of the given Bounds is nan.
  • If upper_bound < lower_bound.
  • If actual does not lie outside the given interval.
  • If actual is not a real number.
Source code in src/safeds/exceptions/_generic.py
def __init__(
    self,
    actual: float,
    *,
    name: str | None = None,
    lower_bound: Bound | None = None,
    upper_bound: Bound | None = None,
):
    """
    Initialize an OutOfBoundsError.

    Parameters
    ----------
    actual: float
        The actual value that is outside its expected range.
    name: str | None
        The name of the offending variable.
    lower_bound: Bound | None
        The lower bound of the expected range. Use None if there is no lower Bound.
    upper_bound: Bound | None
        The upper bound of the expected range. Use None if there is no upper Bound.

    Raises
    ------
    ValueError
        * If one of the given Bounds is +/-inf. (For infinite Bounds, pass None instead.)
        * If one of the given Bounds is nan.
        * If upper_bound < lower_bound.
        * If actual does not lie outside the given interval.
        * If actual is not a real number.
    """
    from numpy import isinf, isnan

    # Validate bound parameters:
    if lower_bound is None and upper_bound is None:
        raise ValueError("Illegal interval: Attempting to raise OutOfBoundsError, but no bounds given.")
    if (lower_bound is not None and isinf(lower_bound.value)) or (
        upper_bound is not None and isinf(upper_bound.value)
    ):
        raise ValueError("Illegal interval: Lower and upper bounds must be real numbers, or None if unbounded.")
    # Validate actual parameter:
    if isinf(actual) or isnan(actual):
        raise ValueError("Attempting to raise OutOfBoundsError with actual value not being a real number.")
    # Use local variables with stricter types to help static analysis:
    _lower_bound: Bound = lower_bound if lower_bound is not None else OpenBound(float("-inf"))
    _upper_bound: Bound = upper_bound if upper_bound is not None else OpenBound(float("inf"))
    # Check bounds:
    if _upper_bound.value < _lower_bound.value:
        raise ValueError(
            (
                f"Illegal interval: Attempting to raise OutOfBoundsError, but given upper bound {_upper_bound} is "
                f"actually less than given lower bound {_lower_bound}."
            ),
        )
    # Check that actual is indeed outside the interval:
    elif _lower_bound._check_lower_bound(actual) and _upper_bound._check_upper_bound(actual):
        raise ValueError(
            (
                f"Illegal interval: Attempting to raise OutOfBoundsError, but value {actual} is not actually"
                f" outside given interval {_lower_bound._str_lower_bound()}, {_upper_bound._str_upper_bound()}."
            ),
        )
    # Raise the actual exception:
    full_variable_name = actual if name is None else f"{name} (={actual})"
    super().__init__(
        f"{full_variable_name} is not inside {_lower_bound._str_lower_bound()}, {_upper_bound._str_upper_bound()}.",
    )