Учёт трафика через генератор Python: сумма и динамический лимит
Напишите решение на Python и проверьте его на странице.
Другие упражнения по этой теме: Генератор send в Python: задачи на состояние и управление потоком.
Учёт сетевого трафика и лимитов
Контроллер сетевого шлюза следит за объёмом переданных данных, принимая размеры пакетов один за другим. Сначала он работает в режиме свободного аудита: ограничений нет, и сопрограмма просто накапливает суммарный расход трафика, сообщая о текущей сумме и отсутствии действующей квоты.
В любой момент шлюз может получить команду с новым абсолютным потолком. Установка лимита не сбрасывает уже подсчитанный объём и не прибавляется к нему, а сразу задаёт общую границу допустимого расхода. Все последующие пакеты продолжают целиком суммироваться с прежними данными. При активном ограничении контроллер в ответ на каждое число сообщает текущее состояние: либо положительный остаток квоты, либо величину перерасхода в виде нуля или отрицательного числа.
Вспомогательная функция-фабрика должна сразу отдавать готовую к работе сопрограмму, в которую можно передавать данные через метод send без предварительного ручного запуска. Реализуйте генератор учёта сетевого трафика и функцию для его создания.
Что уже дано
В редакторе представлены заготовки двух функций: генератора traffic_counter() и фабрики make_traffic_counter(). Вспомогательные проверочные средства доступны при выполнении, реализовывать их не требуется.
Что нужно сделать
Реализуйте функцию-генератор traffic_counter() и фабрику make_traffic_counter().
Функция traffic_counter() не принимает аргументов и возвращает неинициализированную сопрограмму (генератор). Вызывающий код выполняет первичную инициализацию (прайминг) вызовом next() или .send(None); значение первого выхода не регламентируется.
Функция make_traffic_counter() не принимает аргументов и возвращает уже инициализированную сопрограмму, сразу готовую принимать рабочие сообщения через .send(...) без предварительного next().
После старта сопрограмма принимает от 0 до 1000 сообщений одного из двух видов:
- Числовой пакет — целое неотрицательное число от
0до1 000 000(размер переданного пакета). - Команда установки лимита — словарь ровно с одним ключом:
{'set_limit': limit}, гдеlimit— целое неотрицательное число от0до1 000 000.
Правила подсчёта и ответов:
- Начальный суммарный расход равен
0. Каждый поступивший пакет полностью прибавляется к суммарному расходу, включая пакеты, вызвавшие превышение квоты. - До поступления первой команды
{'set_limit': ...}лимит отсутствует. В ответ на каждый числовой пакет сопрограмма возвращает кортеж вида('unlimited', cumulative_spent), гдеcumulative_spent— накопленный суммарный расход. - Команда
{'set_limit': limit}устанавливает абсолютную верхнюю границуlimit. Она не сбрасывает и не увеличивает накопленный расход. Значение, возвращаемое генератором в ответ на саму команду установки лимита, не регламентируется и не проверяется. - После установки лимита в ответ на каждый числовой пакет сопрограмма возвращает целое число
limit - cumulative_spent. Это значение может быть строго положительным (остаток квоты), нулём или отрицательным (величина перерасхода). - Каждая созданная сопрограмма ведёт полностью независимый учёт.
- При вызове метода
.close()сопрограмма завершает работу; последующий вызовnext()на ней возбуждаетStopIteration.
Ввод и вывод
Стандартные потоки stdin и stdout не используются: считывать ввод и вызывать print() не требуется. Тестирующая система после выполнения кода решения считывает функции верхнего уровня traffic_counter и make_traffic_counter и взаимодействует с их сопрограммами напрямую через метод .send().
Пример использования
coro = make_traffic_counter()
print(coro.send(8))
coro.send({'set_limit': 10})
print(coro.send(3))
coro.send({'set_limit': 20})
print(coro.send(0))
coro.close()
Вывод:
('unlimited', 8)
-1
9
Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.
Отправьте решение, чтобы увидеть результаты тестов.
Связанные задачи
- Send() до первого next(): ошибка запуска генератора Python
- Генератор с send() на Python: накопление порций и смена лимита
- Генератор Python: фильтрация выбросов с изменяемым порогом
- Генератор Python: центрирование данных в скользящем окне
- Генератор с состоянием Python: реализуйте переключатель с гистерезисом
- Send() в Python: накопление импульсов и квантование смещения
