Скользящие окна Python: генерация кортежей без загрузки всего потока
Напишите решение на Python и проверьте его на странице.
Другие упражнения по этой теме: Itertools в Python: задачи на комбинации, groupby и ленивые потоки.
Скользящие окна вибромониторинга
Модуль мониторинга промышленного привода непрерывно принимает поток виброакустических замеров и передаёт их в анализатор перегрузок. Чтобы вовремя заметить опасные вибрации, данные группируют в скользящие окна фиксированной ширины со сдвигом ровно на один шаг.
Очередное окно отдаётся в виде неизменяемого кортежа сразу же, как только поступает новая точка замеров. Пока накопилось меньше значений, анализатор ждёт, а если входящий поток исчерпался или был остановлен досрочно, неполный финальный кортеж длиной меньше просто отбрасывается.
Поскольку поток может быть бесконечным, элементы нельзя целиком сохранять в памяти. Постройте потоковый генератор скользящих окон заданной длины, который выдаёт сформированные кортежи строго по мере поступления данных.
Что уже дано
В среде выполнения уже определены вспомогательные инструменты для тестирования: WindowSource, make_window_source, observe_overlapping_iterator и observe_overlapping_memory. Реализовывать их заново не требуется: вам нужно написать только саму функцию overlapping_windows.
Что нужно сделать
Реализуйте функцию overlapping_windows(source, width).
Функция принимает два аргумента:
source— однократный итерируемый объект с конечными числовыми замерами (intилиfloatв диапазоне от -1 000 000 до 1 000 000). Поток может быть потенциально бесконечным, не поддерживает индексацию, вызовlen()и перемотку назад;width— целое число от 1 до 128, задающее ширину скользящего окна.
Функция должна вернуть ленивый однократный итератор (например, генератор), выдающий окна в виде неизменяемых кортежей tuple.
Правила формирования и выдачи окон:
- Вызов
overlapping_windows(source, width)не должен вычитывать элементы изsourceдо первого явного запроса очередного элемента у возвращённого итератора. - Первое окно формируется из первых
widthзамеровsource. Каждое следующее окно сдвигается на один замер: старейший элемент отбрасывается, а в конец добавляется одно новое прочитанное значение с сохранением исходного порядка и повторов. - Каждое следующее запрашиваемое окно считывает из
sourceровно столько данных, сколько требуется для его построения: никаких упреждающих чтений сверх текущего окна производиться не должно. - Если поток завершился до того, как набралось полное окно шириной
width, неполный хвост отбрасывается, и итератор останавливает работу. - Если вызывающий код прекращает запрашивать результаты или запрашивает лишь часть окон, фонового чтения оставшегося потока не происходит.
- Запрещено материализовать входной поток целиком или хранить неограниченную историю значений. Дополнительный пик потребления памяти при итерации по замерам (за вычетом исходных структур вызывающей стороны) не должен превышать 1 048 576 байт (1 МиБ).
Ввод и вывод
Стандартные потоки ввода stdin и вывода stdout в решении не используются: считывать ввод и вызывать print() не нужно. После выполнения кода учащегося проверяющая система считывает из пространства имён модуля функцию верхнего уровня overlapping_windows и вызывает её с проверочными аргументами.
Пример использования
source = make_window_source([1, 2, 3, 4, 5])
print(list(overlapping_windows(source, 3)))
Вывод:
[(1, 2, 3), (2, 3, 4), (3, 4, 5)]
Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.
Отправьте решение, чтобы увидеть результаты тестов.
Связанные задачи
- Как groupby группирует несортированные данные: тест itertools Python
- Itertools на Python: ленивый перебор комбинаций параметров
- Itertools на Python: разбейте поток на партии с лимитом
- Itertools на Python: объедините генераторы в непрерывный поток
- Groupby на Python: сводка последовательных серий событий
- Итераторы Python: сборка кадра из двух потоков без лишнего чтения
