Генератор с send() на Python: накопление порций и смена лимита

Напишите решение на Python и проверьте его на странице.

Другие упражнения по этой теме: Генератор send в Python: задачи на состояние и управление потоком.

Дозатор сыпучих смесей

Фасовочный автомат наполняет тару сыпучим компонентом, добавляя его последовательными порциями. Целевая норма веса пачки задаётся при запуске механизма, однако в процессе работы её значение может измениться.

Управляет процессом сопрограмма, которая отслеживает общую массу текущей упаковки. Пока накопленный вес строго меньше действующей нормы, автомат продолжает наполнение и при каждой добавленной порции сообщает, сколько ещё не хватает до цели. Как только очередная порция доводит массу до нормы или превышает её, генератор возвращает величину перевеса — ноль или положительное число — и сразу же сбрасывает счётчик пачки в ноль, готовясь к следующей таре.

Если же поступает команда изменить норму веса, уже насыпанный в открытую пачку объём сохраняется. Автомат лишь пересчитывает оставшуюся нехватку до новой цели — либо возвращает ноль, если текущий вес уже достиг её или превзошёл, — а проверку на готовность откладывает до следующей порции продукта.

Реализуйте сопрограмму дозатора, которая удерживает накопленную массу, своевременно обновляет норму фасовки и точно сообщает статус наполнения на каждом шаге.

Что уже дано

В редакторе объявлена функция-генератор fill_batches(initial_target), которую необходимо реализовать. Вспомогательные функции тестирования и окружения доступны во время выполнения тестов и не требуют изменения.

Что нужно сделать

Реализуйте функцию fill_batches(initial_target).

Функция принимает положительное целое число initial_target (от 1 до 1 000 000) — начальную целевую норму веса пачки. Функция должна возвращать неинициализированную сопрограмму (генератор).

Правила работы сопрограммы:

  • При первичном запуске через next(coro) или coro.send(None) генератор выполняет инициализацию (прайминг) и возвращает None.
  • Наполнение новой пачки всегда начинается с массы 0.
  • Сопрограмма последовательно принимает от 0 до 1000 сообщений одного из двух типов:
  1. Порция продукта — неотрицательное целое число (от 0 до 1 000 000). Число прибавляется к текущей накопленной массе пачки:
  • Если итоговая масса строго меньше текущей цели, возвращается кортеж ('filling', shortage), где shortage (int) — положительная нехватка до целевой нормы (цель - масса).
  • Если итоговая масса равна текущей цели или превышает её, возвращается кортеж ('ready', overfill), где overfill (int) — неотрицательный перевес сверх нормы (масса - цель). Сразу после этого накопленная масса пачки сбрасывается в 0, а излишек перевеса не переносится в следующую тару.
  1. Команда калибровки нормы — словарь ровно с одним ключом {'set_target': new_target}, где new_target — положительное целое число (от 1 до 1 000 000). Сопрограмма обновляет текущую целевую норму, сохраняя накопленную массу пачки без изменений. В ответ возвращается целое число max(new_target - current_mass, 0). Даже если текущая масса уже равна новой норме или превышает её, пачка не считается готовой и масса не сбрасывается: проверка готовности и сброс происходят только при получении следующей числовой порции.
  • Каждый созданный экземпляр сопрограммы работает независимо от других.
  • При вызове метода coro.close() работа сопрограммы корректно завершается, а последующий вызов next(coro) возбуждает исключение StopIteration.

Ввод и вывод

Стандартные потоки stdin и stdout не используются: считывать ввод и вызывать print() в решении не требуется. Проверяющая система импортирует функцию верхнего уровня fill_batches из состояния скрипта после его выполнения и отправляет сообщения напрямую через метод .send().

Пример использования

coro = fill_batches(10)
next(coro)
print(coro.send(8))
print(coro.send({'set_target': 5}))
print(coro.send(0))
print(coro.send(1))
coro.close()

Вывод:

('filling', 2)
0
('ready', 3)
('filling', 4)
РешениеPython

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

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

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