Skip to content

Commit 992632a

Browse files
committed
Replace len magic with count_valid for moving window
Signed-off-by: cwasicki <[email protected]>
1 parent 985e071 commit 992632a

File tree

4 files changed

+20
-12
lines changed

4 files changed

+20
-12
lines changed

benchmarks/timeseries/periodic_feature_extractor.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,16 @@ def _num_windows(
115115
Returns:
116116
The number of windows that are fully contained in the MovingWindow.
117117
"""
118-
num_windows = len(window) // period
119-
if len(window) - num_windows * period >= window_size:
118+
119+
def length(window: NDArray[np.float_] | MovingWindow) -> int:
120+
return (
121+
window.count_valid()
122+
if isinstance(window, MovingWindow)
123+
else len(window)
124+
)
125+
126+
num_windows = length(window) // period
127+
if length(window) - num_windows * period >= window_size:
120128
num_windows += 1
121129

122130
return num_windows

src/frequenz/sdk/timeseries/_moving_window.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ def __getitem__(self, key: SupportsIndex | datetime | slice) -> float | ArrayLik
376376
if isinstance(key, slice):
377377
if isinstance(key.start, int) or isinstance(key.stop, int):
378378
if key.start is None or key.stop is None:
379-
key = slice(slice(key.start, key.stop).indices(self.__len__()))
379+
key = slice(slice(key.start, key.stop).indices(self.count_valid()))
380380
elif isinstance(key.start, datetime) or isinstance(key.stop, datetime):
381381
if key.start is None:
382382
key = slice(self._buffer.time_bound_oldest, key.stop)

src/frequenz/sdk/timeseries/_periodic_feature_extractor.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,13 +128,13 @@ def __init__(
128128
"""Distance between two succeeding intervals in samples."""
129129

130130
_logger.debug("Initializing PeriodicFeatureExtractor!")
131-
_logger.debug("MovingWindow size: %i", len(self._moving_window))
131+
_logger.debug("MovingWindow size: %i", self._moving_window.count_valid())
132132
_logger.debug(
133133
"Period between two succeeding intervals (in samples): %i",
134134
self._period,
135135
)
136136

137-
if not len(self._moving_window) % self._period == 0:
137+
if not self._moving_window.count_valid() % self._period == 0:
138138
raise ValueError(
139139
"The MovingWindow size is not a integer multiple of the period."
140140
)
@@ -323,7 +323,7 @@ def _get_buffer_bounds(
323323

324324
rel_pos = self._get_relative_positions(start, window_size)
325325

326-
if window_size > len(self._moving_window):
326+
if window_size > self._moving_window.count_valid():
327327
raise ValueError(
328328
"The window size must be smaller than the size of the `MovingWindow`"
329329
)
@@ -379,7 +379,7 @@ def _get_reshaped_np_array(
379379
(start_pos, end_pos, window_size) = self._get_buffer_bounds(start, end)
380380

381381
if start_pos >= end_pos:
382-
window_start = self._buffer[start_pos : len(self._moving_window)]
382+
window_start = self._buffer[start_pos : self._moving_window.count_valid()]
383383
window_end = self._buffer[0:end_pos]
384384
# make the linter happy
385385
assert isinstance(window_start, np.ndarray)

tests/timeseries/test_moving_window.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -143,13 +143,13 @@ async def test_window_size() -> None:
143143
window, sender = init_moving_window(timedelta(seconds=5))
144144
async with window:
145145
assert window.capacity == 5, "Wrong window capacity"
146-
assert len(window) == 0, "Window should be empty"
146+
assert window.count_valid() == 0, "Window should be empty"
147147
await push_logical_meter_data(sender, range(0, 2))
148148
assert window.capacity == 5, "Wrong window capacity"
149-
assert len(window) == 2, "Window should be partially full"
149+
assert window.count_valid() == 2, "Window should be partially full"
150150
await push_logical_meter_data(sender, range(2, 20))
151151
assert window.capacity == 5, "Wrong window capacity"
152-
assert len(window) == 5, "Window should be full"
152+
assert window.count_valid() == 5, "Window should be full"
153153

154154

155155
# pylint: disable=redefined-outer-name
@@ -170,7 +170,7 @@ async def test_resampling_window(fake_time: time_machine.Coordinates) -> None:
170170
resampler_config=resampler_config,
171171
) as window:
172172
assert window.capacity == window_size / output_sampling, "Wrong window capacity"
173-
assert len(window) == 0, "Window should be empty at the beginning"
173+
assert window.count_valid() == 0, "Window should be empty at the beginning"
174174
stream_values = [4.0, 8.0, 2.0, 6.0, 5.0] * 100
175175
for value in stream_values:
176176
timestamp = datetime.now(tz=timezone.utc)
@@ -179,7 +179,7 @@ async def test_resampling_window(fake_time: time_machine.Coordinates) -> None:
179179
await asyncio.sleep(0.1)
180180
fake_time.shift(0.1)
181181

182-
assert len(window) == window_size / output_sampling
182+
assert window.count_valid() == window_size / output_sampling
183183
for value in window: # type: ignore
184184
assert 4.9 < value < 5.1
185185

0 commit comments

Comments
 (0)