Skip to content

Errors

ts_stat_tests.utils.errors 🔗

Summary

Provides utility functions for generating standardized error messages and performing numeric assertions.

This module includes functions to format error messages consistently and check if numeric values are within a specified tolerance, which is useful for testing and validation purposes.

generate_error_message 🔗

generate_error_message(
    parameter_name: str,
    value_parsed: str,
    options: Union[
        Mapping[
            str, Union[tuple[str, ...], list[str], str]
        ],
        tuple[str, ...],
        list[str],
    ],
) -> str

Summary

Generates a formatted error message for mismatched values or invalid options.

Details

This function constructs a standardized string that describes a mismatch between a provided value and the allowed options for a given parameter. It is primarily used to provide clear, consistent feedback in ValueError exceptions within dispatchers.

Parameters:

Name Type Description Default
parameter_name str

The name of the parameter or variable being checked.

required
value_parsed str

The actual value that was received.

required
options Union[Mapping[str, Union[tuple[str, ...], list[str], str]], tuple[str, ...], list[str]]

The set of valid options or a dictionary mapping categories to valid options.

required

Returns:

Type Description
str

A formatted error message string.

Examples
Setup
1
>>> from ts_stat_tests.utils.errors import generate_error_message
Example 1: Simple Options
1
2
3
>>> msg = generate_error_message("param", "invalid", ["opt1", "opt2"])
>>> print(msg)
Invalid 'param': invalid. Options: ['opt1', 'opt2']
References
  1. Python F-Strings documentation
Source code in src/ts_stat_tests/utils/errors.py
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
@typechecked
def generate_error_message(
    parameter_name: str,
    value_parsed: str,
    options: Union[Mapping[str, Union[tuple[str, ...], list[str], str]], tuple[str, ...], list[str]],
) -> str:
    r"""
    !!! note "Summary"
        Generates a formatted error message for mismatched values or invalid options.

    ???+ abstract "Details"
        This function constructs a standardized string that describes a mismatch between a provided value and the allowed options for a given parameter. It is primarily used to provide clear, consistent feedback in `ValueError` exceptions within dispatchers.

    Params:
        parameter_name (str):
            The name of the parameter or variable being checked.
        value_parsed (str):
            The actual value that was received.
        options (Union[Mapping[str, Union[tuple[str, ...], list[str], str]], tuple[str, ...], list[str]]):
            The set of valid options or a dictionary mapping categories to valid options.

    Returns:
        (str):
            A formatted error message string.

    ???+ example "Examples"

        ```pycon {.py .python linenums="1" title="Setup"}
        >>> from ts_stat_tests.utils.errors import generate_error_message

        ```

        ```pycon {.py .python linenums="1" title="Example 1: Simple Options"}
        >>> msg = generate_error_message("param", "invalid", ["opt1", "opt2"])
        >>> print(msg)
        Invalid 'param': invalid. Options: ['opt1', 'opt2']

        ```

    ??? question "References"
        1. [Python F-Strings documentation](https://docs.python.org/3/reference/lexical_analysis.html#f-strings)

    """
    return f"Invalid '{parameter_name}': {value_parsed}. Options: {options}"

is_almost_equal 🔗

is_almost_equal(
    first: float, second: float, *, places: int = 7
) -> bool
is_almost_equal(
    first: float, second: float, *, delta: float
) -> bool
is_almost_equal(
    first: float,
    second: float,
    *,
    places: Optional[int] = None,
    delta: Optional[float] = None
) -> bool

Summary

Checks if two float values are almost equal within a specified precision.

Details

Determines the equality of two floating-point numbers within a tolerance. This is necessary because floating-point arithmetic can introduce small errors that make direct equality comparisons (e.g., a == b) unreliable.

The user can specify tolerance either by places (decimal places) or by an absolute delta.

Parameters:

Name Type Description Default
first float

The first float value.

required
second float

The second float value.

required
places Optional[int]

The number of decimal places for comparison. Defaults to 7 if not provided.

None
delta Optional[float]

An optional delta value for comparison.

None

Raises:

Type Description
ValueError

If both places and delta are provided.

Returns:

Type Description
bool

True if the values are almost equal, False otherwise.

Examples
Setup
1
>>> from ts_stat_tests.utils.errors import is_almost_equal
Example 1: Using `places`
1
2
3
>>> res_places = is_almost_equal(1.0, 1.00000001, places=7)
>>> print(res_places)
True
Example 2: Using `delta`
1
2
3
>>> res_delta = is_almost_equal(1.0, 1.1, delta=0.2)
>>> print(res_delta)
True
Example 3: Not Almost Equal
1
2
3
>>> res_not_equal = is_almost_equal(1.0, 1.1, places=3)
>>> print(res_not_equal)
False
Calculation

The comparison depends on whether delta or places is provided.

If delta is specified:

\[ |first - second| \le \text{delta} \]

If places is specified (defaults to 7):

\[ \text{round}(|first - second|, \text{places}) = 0 \]
Credit

Inspiration from Python's UnitTest function assertAlmostEqual.

References
  1. Python unittest source code
Source code in src/ts_stat_tests/utils/errors.py
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
@typechecked
def is_almost_equal(
    first: float,
    second: float,
    *,
    places: Optional[int] = None,
    delta: Optional[float] = None,
) -> bool:
    r"""
    !!! note "Summary"
        Checks if two float values are almost equal within a specified precision.

    ???+ abstract "Details"
        Determines the equality of two floating-point numbers within a tolerance. This is necessary because floating-point arithmetic can introduce small errors that make direct equality comparisons (e.g., `a == b`) unreliable.

        The user can specify tolerance either by `places` (decimal places) or by an absolute `delta`.

    Params:
        first (float):
            The first float value.
        second (float):
            The second float value.
        places (Optional[int]):
            The number of decimal places for comparison. Defaults to 7 if not provided.
        delta (Optional[float]):
            An optional delta value for comparison.

    Raises:
        (ValueError):
            If both `places` and `delta` are provided.

    Returns:
        (bool):
            `True` if the values are almost equal, `False` otherwise.

    ???+ example "Examples"

        ```pycon {.py .python linenums="1" title="Setup"}
        >>> from ts_stat_tests.utils.errors import is_almost_equal

        ```

        ```pycon {.py .python linenums="1" title="Example 1: Using `places`"}
        >>> res_places = is_almost_equal(1.0, 1.00000001, places=7)
        >>> print(res_places)
        True

        ```

        ```pycon {.py .python linenums="1" title="Example 2: Using `delta`"}
        >>> res_delta = is_almost_equal(1.0, 1.1, delta=0.2)
        >>> print(res_delta)
        True

        ```

        ```pycon {.py .python linenums="1" title="Example 3: Not Almost Equal"}
        >>> res_not_equal = is_almost_equal(1.0, 1.1, places=3)
        >>> print(res_not_equal)
        False

        ```

    ??? equation "Calculation"

        The comparison depends on whether `delta` or `places` is provided.

        If `delta` is specified:

        $$
        |first - second| \le \text{delta}
        $$

        If `places` is specified (defaults to 7):

        $$
        \text{round}(|first - second|, \text{places}) = 0
        $$

    ??? success "Credit"
        Inspiration from Python's UnitTest function [`assertAlmostEqual`](https://github.com/python/cpython/blob/3.11/Lib/unittest/case.py).

    ??? question "References"
        1. [Python unittest source code](https://github.com/python/cpython/blob/main/Lib/unittest/case.py)

    """
    if places is not None and delta is not None:
        raise ValueError("Specify `delta` or `places`, not both.")
    if first == second:
        return True
    diff: float = abs(first - second)
    if delta is not None:
        if diff <= delta:
            return True
    else:
        places_val: int = places if places is not None else 7
        if round(diff, places_val) == 0:
            return True
    return False

assert_almost_equal 🔗

assert_almost_equal(
    first: float,
    second: float,
    msg: Optional[str] = None,
    *,
    places: int = 7
) -> None
assert_almost_equal(
    first: float,
    second: float,
    msg: Optional[str] = None,
    *,
    delta: float
) -> None
assert_almost_equal(
    first: float,
    second: float,
    msg: Optional[str] = None,
    *,
    places: Optional[int] = None,
    delta: Optional[float] = None
) -> None

Summary

Asserts that two float values are almost equal within a specified precision.

Details

Performs a floating-point comparison using is_almost_equal. If the comparison fails, an AssertionError is raised with a descriptive message.

Parameters:

Name Type Description Default
first float

The first float value.

required
second float

The second float value.

required
msg Optional[str]

An optional message to include in the exception if the values are not almost equal.

None
places Optional[int]

The number of decimal places for comparison. Defaults to 7 if not provided.

None
delta Optional[float]

An optional delta value for comparison.

None

Raises:

Type Description
ValueError

If both places and delta are provided.

AssertionError

If the two float values are not almost equal.

Returns:

Type Description
None

None. Raises an AssertionError if the values are not almost equal to within the tolerances specified.

Examples
Setup
1
>>> from ts_stat_tests.utils.errors import assert_almost_equal
Example 1: Using `places`
1
2
3
>>> res_places = assert_almost_equal(1.0, 1.0, places=7)
>>> print(res_places is None)
True
Example 2: Using `delta`
1
2
3
>>> res_delta = assert_almost_equal(1.0, 1.1, delta=0.2)
>>> print(res_delta is None)
True
Example 3: AssertionError Raised
1
2
3
4
>>> assert_almost_equal(1.0, 1.1, places=3)
Traceback (most recent call last):
    ...
AssertionError: Assertion failed: 1.0 != 1.1 (places=3, delta=None)
Calculation

Refer to is_almost_equal for the underlying logic.

Credit

Inspiration from Python's UnitTest function assertAlmostEqual.

References
  1. Python unittest source code
Source code in src/ts_stat_tests/utils/errors.py
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
@typechecked
def assert_almost_equal(
    first: float,
    second: float,
    msg: Optional[str] = None,
    *,
    places: Optional[int] = None,
    delta: Optional[float] = None,
) -> None:
    r"""
    !!! note "Summary"
        Asserts that two float values are almost equal within a specified precision.

    ???+ abstract "Details"
        Performs a floating-point comparison using [is_almost_equal][ts_stat_tests.utils.errors.is_almost_equal]. If the comparison fails, an `AssertionError` is raised with a descriptive message.

    Params:
        first (float):
            The first float value.
        second (float):
            The second float value.
        msg (Optional[str]):
            An optional message to include in the exception if the values are not almost equal.
        places (Optional[int]):
            The number of decimal places for comparison. Defaults to 7 if not provided.
        delta (Optional[float]):
            An optional delta value for comparison.

    Raises:
        (ValueError):
            If both `places` and `delta` are provided.
        (AssertionError):
            If the two float values are not almost equal.

    Returns:
        (None):
            None. Raises an `AssertionError` if the values are not almost equal to within the tolerances specified.

    ???+ example "Examples"

        ```pycon {.py .python linenums="1" title="Setup"}
        >>> from ts_stat_tests.utils.errors import assert_almost_equal

        ```

        ```pycon {.py .python linenums="1" title="Example 1: Using `places`"}
        >>> res_places = assert_almost_equal(1.0, 1.0, places=7)
        >>> print(res_places is None)
        True

        ```

        ```pycon {.py .python linenums="1" title="Example 2: Using `delta`"}
        >>> res_delta = assert_almost_equal(1.0, 1.1, delta=0.2)
        >>> print(res_delta is None)
        True

        ```

        ```pycon {.py .python linenums="1" title="Example 3: AssertionError Raised"}
        >>> assert_almost_equal(1.0, 1.1, places=3)
        Traceback (most recent call last):
            ...
        AssertionError: Assertion failed: 1.0 != 1.1 (places=3, delta=None)

        ```

    ??? equation "Calculation"

        Refer to [is_almost_equal][ts_stat_tests.utils.errors.is_almost_equal] for the underlying logic.

    ??? success "Credit"
        Inspiration from Python's UnitTest function [`assertAlmostEqual`](https://github.com/python/cpython/blob/3.11/Lib/unittest/case.py).

    ??? question "References"
        1. [Python unittest source code](https://github.com/python/cpython/blob/main/Lib/unittest/case.py)

    """
    is_equal: bool = False
    if delta is not None:
        is_equal = is_almost_equal(first, second, delta=delta)
    else:
        places_val: int = places if places is not None else 7
        is_equal = is_almost_equal(first, second, places=places_val)

    if not is_equal:
        error_msg: str = msg if msg is not None else f"Assertion failed: {first} != {second} ({places=}, {delta=})"
        raise AssertionError(error_msg)