Генератор Python: центрирование данных в скользящем окне
Напишите решение на Python и проверьте его на странице.
Другие упражнения по этой теме: Генератор send в Python: задачи на состояние и управление потоком.
Центрирующее окно
Потоковый анализатор геофизических сигналов выполняет центрирование данных прямо в процессе измерений. Он принимает замеры один за другим, накапливает историю в скользящем окне заданной ёмкости и вычитает из каждого поступившего значения среднее арифметическое всех точек, которые уже успели накопиться в окне, начиная с самой первой.
Параметры сбора можно менять на лету: в любой момент оператор вправе прислать настроечную директиву с новым размером окна. Если новая ёмкость меньше числа уже накопленных замеров, анализатор сразу отбрасывает самые старые точки до нужного лимита. Если же окно увеличивают, анализатор сохраняет все текущие данные и продолжает набирать историю со следующих замеров. В ответ на такую директиву генератор сразу сообщает подтверждённое число сохранённых в окне точек.
Реализуйте сопрограмму, которая обрабатывает числовые замеры и настроечные команды, возвращая скорректированное значение для каждого измерения или фактическое количество оставшихся точек при смене размера окна.
Что уже дано
В среде выполнения доступна вспомогательная функция observe_coroutine_calls(generators, actions), отслеживающая состояния и ответы нативных генераторов. В заготовке решения объявлена функция-генератор centering_window(initial_width), тело которой предстоит написать.
Что нужно сделать
Реализуйте функцию-генератор centering_window(initial_width).
Функция принимает целое число initial_width (от 1 до 128) — начальную ёмкость окна — и возвращает неинициализированную нативную сопрограмму (генератор).
Правила жизненного цикла и обработки сообщений:
- Первый запуск генератора через
next(coro)илиcoro.send(None)выполняет инициализацию (прайминг) и возвращаетNone. Автоматической инициализации внутри генератора быть не должно. - После прайминга сопрограмма ожидает сообщения через
.send(): - Числовые замеры: конечное целое или вещественное число (
intилиfloat) в диапазоне от -1 000 000 до 1 000 000. Поступивший замер сразу помещается в скользящее окно с сохранением хронологического порядка. Если размер окна превышает текущую предельную ёмкость, самое старое измерение удаляется. Из текущего поступившего значения вычитается среднее арифметическое всех точек, находящихся в окне на данный момент (включая текущую точку). Результат возвращается как вещественное числоfloat. Для самого первого замера результат всегда равен0.0. - Настроечные директивы: кортеж строго вида
("resize", new_width), гдеnew_width— целое число от 1 до 128. Команда не добавляет измерение и не очищает историю. Если новое значение меньше текущего количества накопленных точек, самые старые избыточные замеры немедленно отбрасываются. При увеличении ёмкости сохраняются все текущие точки, а окно расширяется по мере поступления новых измерений (ранее отброшенные точки не восстанавливаются). В ответ на директиву генератор возвращает целое числоint— фактическое количество точек, оставшихся в окне (в том числе0, если замеров ещё не было). - Вызов
coro.close()завершает работу сопрограммы штатно без дополнительногоyield. - Каждая созданная сопрограмма хранит собственное независимое состояние.
- Каждая сопрограмма рассчитана на обработку от 0 до 1000 операций; в тестах может одновременно использоваться от 1 до 3 независимых генераторов с чередующимися вызовами.
Ввод и вывод
Стандартные потоки ввода stdin и вывода stdout в решении не используются: считывать ввод и вызывать print() не нужно. После выполнения кода учащегося проверяющая система считывает из пространства имён модуля функцию верхнего уровня centering_window и вызывает её с проверочными аргументами.
Пример использования
coro = centering_window(3)
print(next(coro))
print(coro.send(10))
print(coro.send(20))
print(coro.send(('resize', 1)))
print(coro.send(40))
coro.close()
Вывод:
None 0.0 5.0 1 0.0
Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.
Отправьте решение, чтобы увидеть результаты тестов.
Связанные задачи
- Send() до первого next(): ошибка запуска генератора Python
- Генератор с send() на Python: накопление порций и смена лимита
- Учёт трафика через генератор Python: сумма и динамический лимит
- Генератор Python: фильтрация выбросов с изменяемым порогом
- Генератор с состоянием Python: реализуйте переключатель с гистерезисом
- Send() в Python: накопление импульсов и квантование смещения
