Skip to content

Commit 6251425

Browse files
committed
refactor: update HistogramResult attributes for consistency and improve test cases
1 parent c40e08a commit 6251425

3 files changed

Lines changed: 38 additions & 36 deletions

File tree

src/khisto/array/histogram/api.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,8 @@ def histogram(
119119
histogram_result = _select_histogram(histogram_results, max_bins=max_bins)
120120

121121
if density:
122-
return histogram_result.density.copy(), histogram_result.bin_edges.copy()
122+
return histogram_result.densities.copy(), histogram_result.bin_edges.copy()
123123
else:
124-
return histogram_result.frequency.astype(
124+
return histogram_result.frequencies.astype(
125125
np.float64
126126
), histogram_result.bin_edges.copy()

src/khisto/core/backend.py

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -88,15 +88,15 @@ class HistogramResult:
8888
8989
Attributes
9090
----------
91-
lower_bound : NDArray[np.float64]
91+
lower_bounds : NDArray[np.float64]
9292
Lower bounds of each bin.
93-
upper_bound : NDArray[np.float64]
93+
upper_bounds : NDArray[np.float64]
9494
Upper bounds of each bin.
95-
frequency : NDArray[np.int64]
95+
frequencies : NDArray[np.int64]
9696
Count of values in each bin.
97-
probability : NDArray[np.float64]
97+
probabilities : NDArray[np.float64]
9898
Probability of each bin (frequency / total).
99-
density : NDArray[np.float64]
99+
densities : NDArray[np.float64]
100100
Density of each bin (probability / bin_width).
101101
is_best : bool
102102
Whether this histogram is the optimal one.
@@ -114,11 +114,11 @@ class HistogramResult:
114114
Number of empty intervals in this histogram.
115115
"""
116116

117-
lower_bound: NDArray[np.float64]
118-
upper_bound: NDArray[np.float64]
119-
frequency: NDArray[np.int64]
120-
probability: NDArray[np.float64]
121-
density: NDArray[np.float64]
117+
lower_bounds: NDArray[np.float64]
118+
upper_bounds: NDArray[np.float64]
119+
frequencies: NDArray[np.int64]
120+
probabilities: NDArray[np.float64]
121+
densities: NDArray[np.float64]
122122
is_best: bool = False
123123
granularity: int = 0
124124
level: float = 0.0
@@ -130,31 +130,31 @@ class HistogramResult:
130130
@property
131131
def bin_edges(self) -> NDArray[np.float64]:
132132
"""Return bin edges array (n_bins + 1 values)."""
133-
return np.concatenate([self.lower_bound, [self.upper_bound[-1]]])
133+
return np.concatenate([self.lower_bounds, [self.upper_bounds[-1]]])
134134

135135
@property
136136
def bin_widths(self) -> NDArray[np.float64]:
137137
"""Return width of each bin."""
138-
return self.upper_bound - self.lower_bound
138+
return self.upper_bounds - self.lower_bounds
139139

140140
@property
141141
def bin_centers(self) -> NDArray[np.float64]:
142142
"""Return center of each bin."""
143-
return (self.lower_bound + self.upper_bound) / 2
143+
return (self.lower_bounds + self.upper_bounds) / 2
144144

145145
def __len__(self) -> int:
146146
"""Return number of bins."""
147-
return len(self.lower_bound)
147+
return len(self.lower_bounds)
148148

149149

150150
def _to_result(h: _HistogramPayload, **kwargs: Any) -> HistogramResult:
151151
"""Convert a JSON histogram payload to a HistogramResult."""
152152
return HistogramResult(
153-
lower_bound=np.asarray(h.lowerBounds, dtype=np.float64),
154-
upper_bound=np.asarray(h.upperBounds, dtype=np.float64),
155-
frequency=np.asarray(h.frequencies, dtype=np.int64),
156-
probability=np.asarray(h.probabilities, dtype=np.float64),
157-
density=np.asarray(h.densities, dtype=np.float64),
153+
lower_bounds=np.asarray(h.lowerBounds, dtype=np.float64),
154+
upper_bounds=np.asarray(h.upperBounds, dtype=np.float64),
155+
frequencies=np.asarray(h.frequencies, dtype=np.int64),
156+
probabilities=np.asarray(h.probabilities, dtype=np.float64),
157+
densities=np.asarray(h.densities, dtype=np.float64),
158158
**kwargs,
159159
)
160160

@@ -170,11 +170,13 @@ def _format_runtime_error(
170170

171171

172172
def _process_histogram_file(
173-
temp_output_file: tempfile._TemporaryFileWrapper[str],
173+
temp_output_file_path: str,
174174
) -> list[HistogramResult]:
175175
"""Process exploratory JSON generated by khisto CLI."""
176-
temp_output_file.seek(0)
177-
khisto_output: _KhistoOutput = _KhistoOutput.from_dict(json.load(temp_output_file))
176+
with open(temp_output_file_path, "r") as temp_output_file:
177+
khisto_output: _KhistoOutput = _KhistoOutput.from_dict(
178+
json.load(temp_output_file)
179+
)
178180

179181
histogram_series = khisto_output.histogramSeries
180182
best_idx = histogram_series.interpretableHistogramNumber - 1
@@ -255,7 +257,7 @@ def compute_histograms(x: np.ndarray) -> list[HistogramResult]:
255257
raise RuntimeError(message) from e
256258

257259
try:
258-
return _process_histogram_file(temp_output_file)
260+
return _process_histogram_file(temp_output_file.name)
259261
except json.JSONDecodeError as e:
260262
message = _format_runtime_error(
261263
"khisto produced invalid JSON output",

tests/core/test_backend.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,11 @@ class TestHistogramResult:
4545
def test_histogram_result_properties(self):
4646
"""Test HistogramResult properties."""
4747
result = HistogramResult(
48-
lower_bound=np.array([0.0, 1.0, 2.0]),
49-
upper_bound=np.array([1.0, 2.0, 3.0]),
50-
frequency=np.array([10, 20, 15]),
51-
probability=np.array([0.222, 0.444, 0.333]),
52-
density=np.array([0.222, 0.444, 0.333]),
48+
lower_bounds=np.array([0.0, 1.0, 2.0]),
49+
upper_bounds=np.array([1.0, 2.0, 3.0]),
50+
frequencies=np.array([10, 20, 15]),
51+
probabilities=np.array([0.222, 0.444, 0.333]),
52+
densities=np.array([0.222, 0.444, 0.333]),
5353
is_best=True,
5454
granularity=2,
5555
)
@@ -114,7 +114,7 @@ def test_compute_histograms_nan_handling(self):
114114
results = compute_histograms(data)
115115

116116
finest_result = results[-1]
117-
assert np.sum(finest_result.frequency) == 4
117+
assert np.sum(finest_result.frequencies) == 4
118118

119119
def test_compute_histograms_reports_cli_failure(self, monkeypatch):
120120
"""Test that CLI failures raise a descriptive runtime error."""
@@ -173,11 +173,11 @@ def test_compute_histograms_writes_binary_input(self, monkeypatch):
173173

174174
expected_result = [
175175
HistogramResult(
176-
lower_bound=np.array([0.0]),
177-
upper_bound=np.array([1.0]),
178-
frequency=np.array([2]),
179-
probability=np.array([1.0]),
180-
density=np.array([1.0]),
176+
lower_bounds=np.array([0.0]),
177+
upper_bounds=np.array([1.0]),
178+
frequencies=np.array([2]),
179+
probabilities=np.array([1.0]),
180+
densities=np.array([1.0]),
181181
is_best=True,
182182
granularity=0,
183183
)

0 commit comments

Comments
 (0)