Coverage for src/dummypy/things.py: 100%
23 statements
« prev ^ index » next coverage.py v7.14.3, created at 2026-06-29 05:53 +0000
« prev ^ index » next coverage.py v7.14.3, created at 2026-06-29 05:53 +0000
1"""Core data structures for the dummypy analytics library."""
3import attrs
4import numpy as np
5import pandas as pd
8def _check_n(_instance: object, _attribute: "attrs.Attribute[int]", value: object) -> None:
9 """Reject non-integer or negative grid sizes with a clear error.
11 Args:
12 _instance: The Grid instance being validated (unused).
13 _attribute: The attrs attribute being validated (unused).
14 value: The proposed value for ``n``.
16 Raises:
17 TypeError: If ``value`` is not an integer (bool is rejected too).
18 ValueError: If ``value`` is negative.
19 """
20 # bool is a subclass of int; reject it to avoid Grid(n=True) surprises.
21 if not isinstance(value, int) or isinstance(value, bool):
22 msg = f"Grid size n must be an integer, got {type(value).__name__}"
23 raise TypeError(msg)
24 if value < 0:
25 msg = f"Grid size n must be non-negative, got {value}"
26 raise ValueError(msg)
29@attrs.define
30class Grid:
31 """A grid representing data points for analytics calculations.
33 Creates two DataFrames (x and y) with goal-like structure for data analysis.
35 Args:
36 n: Maximum size for the grid (default: 10). Must be a non-negative
37 integer.
39 Raises:
40 TypeError: If ``n`` is not an integer (e.g. a float or a bool).
41 ValueError: If ``n`` is negative.
42 """
44 n: int = attrs.field(init=True, repr=True, default=10, validator=_check_n)
45 x: pd.DataFrame = attrs.field(repr=False, init=False)
46 y: pd.DataFrame = attrs.field(repr=False, init=False)
48 def __attrs_post_init__(self) -> None:
49 """Initialize the x and y data matrices after object creation."""
50 nn = np.arange(self.n + 1)
51 cols = [str(n) for n in nn]
52 data = np.tile(nn, (self.n + 1, 1))
53 self.y = pd.DataFrame(data, index=pd.Index(cols), columns=pd.Index(cols))
54 self.x = self.y.T
56 def diff(self) -> pd.DataFrame:
57 """Returns a grid of differences.
59 Returns:
60 DataFrame of element-wise differences (x - y).
61 """
62 return self.x - self.y