91 lines
2.6 KiB
Python
91 lines
2.6 KiB
Python
from typing import List, Optional, TypeVar, Generic, Iterator
|
|
|
|
T = TypeVar("T")
|
|
|
|
|
|
class SlidingWindow(Generic[T]):
|
|
"""Class for creating and managing sliding windows over a sequence.
|
|
|
|
This class provides functionality to iterate through windows of a fixed size
|
|
over a sequence of items.
|
|
"""
|
|
|
|
def __init__(self, sequence: List[T], window_size: int):
|
|
"""Initialize the sliding window.
|
|
|
|
Args:
|
|
sequence: The sequence of items to slide over
|
|
window_size: The size of each window (must be positive)
|
|
|
|
Raises:
|
|
ValueError: If window_size is less than 1
|
|
TypeError: If sequence is not iterable
|
|
"""
|
|
if window_size < 1:
|
|
raise ValueError("Window size must be at least 1")
|
|
|
|
if not hasattr(sequence, "__iter__"):
|
|
raise TypeError("Sequence must be iterable")
|
|
|
|
self.sequence = sequence
|
|
self.window_size = window_size
|
|
self.index = 0
|
|
self.max_index = len(sequence) - window_size + 1 if sequence else 0
|
|
|
|
def get_next_window(self) -> Optional[List[T]]:
|
|
"""Return the next window and advance the current position.
|
|
|
|
Returns:
|
|
A list containing the next window of items, or None if all windows
|
|
have been processed.
|
|
"""
|
|
if self.index >= self.max_index:
|
|
return None
|
|
|
|
window = self.sequence[self.index : self.index + self.window_size]
|
|
self.index += 1
|
|
return window
|
|
|
|
def reset(self) -> None:
|
|
"""Reset the window position to the beginning of the sequence."""
|
|
self.index = 0
|
|
|
|
def has_next(self) -> bool:
|
|
"""Check if there are more windows available.
|
|
|
|
Returns:
|
|
True if there are more windows, False otherwise.
|
|
"""
|
|
return self.index < self.max_index
|
|
|
|
def __iter__(self) -> Iterator[List[T]]:
|
|
"""Make the class iterable.
|
|
|
|
Returns:
|
|
An iterator over all windows in the sequence.
|
|
"""
|
|
self.reset()
|
|
return self
|
|
|
|
def __next__(self) -> List[T]:
|
|
"""Get the next window for iteration.
|
|
|
|
Returns:
|
|
The next window as a list.
|
|
|
|
Raises:
|
|
StopIteration: When all windows have been processed.
|
|
"""
|
|
window = self.get_next_window()
|
|
if window is None:
|
|
raise StopIteration
|
|
return window
|
|
|
|
def __len__(self) -> int:
|
|
"""Return the total number of windows.
|
|
|
|
Returns:
|
|
The number of complete windows in the sequence.
|
|
"""
|
|
return max(0, self.max_index)
|