Генератор 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
РешениеPython

Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.

Отправьте решение, чтобы увидеть результаты тестов.

Связанные задачи