Генератор пачек Python: подтверждение обработки после yield
Напишите решение на Python и проверьте его на странице.
Другие упражнения по этой теме: Генераторы Python: задачи на ленивые конвейеры и закрытие ресурсов.
Подтверждение пачек замеров
Модуль пакетной отправки читает поток замеров из закрываемого источника и нарезает его на пачки фиксированного размера . Каждая полностью набранная группа отдаётся наружу в виде кортежа. Подтверждение выдачи записывается в журнал источника строго после того, как управление возвращается в генератор на следующем шаге — при запросе новой порции. Поэтому если получатель закрывает генератор сразу после взятия очередной пачки, она остаётся неподтверждённой.
Когда источник штатно исчерпывается по StopIteration, генератор передаёт наружу оставшийся неполный хвост и отмечает статус финализации источника как завершённый. Если же потребитель вызывает close() до того, как генератор физически получил StopIteration, статус фиксации источника должен быть отмечен как досрочно прерванный, даже если данных в источнике больше нет.
Реализуйте генератор пачек, который подтверждает выдачу только при возобновлении и корректно выставляет флаг завершённости источника при его закрытии.
Что уже дано
В среде выполнения доступен класс AcknowledgedSource, предоставляющий итерируемый источник элементов с методами ack(batch) и close(completed: bool). Реализовывать этот класс не нужно: в редакторе требуется написать только функцию-генератор acknowledged_batches.
Что нужно сделать
Реализуйте функцию-генератор acknowledged_batches(source, batch_size).
Функция принимает два аргумента:
source— объект источника данных (экземплярAcknowledgedSourceили совместимый тип), являющийся итератором произвольных объектов;batch_size— положительное целое число от 1 до 1000 (включая пользовательские подклассыint), задающее размер полной пачки.
Функция должна возвращать обычный (нативный) ещё не запущенный генератор кортежей-пачек со следующим поведением:
- Чтение элементов из
sourceвыполняется строго по мере необходимости, без забегания вперёд за пределы текущей формируемой пачки. Все элементы и их исходный порядок сохраняются по идентичности. - Каждая сформированная полная пачка выдаётся наружу в виде кортежа размера
batch_size. Если перед концом потока остался непустой остаток меньшего размера, он также выдаётся наружу в виде кортежа. - Метод
source.ack(batch)вызывается для выданной пачки строго после того, как внешний потребитель возобновил генератор вызовомnext()илиsend(None). Если потребитель сразу после получения пачки прерывает генератор черезclose()илиthrow(), эта пачка подтверждаться не должна. - Источник считается завершённым (
completed=True), только если генератор реально получил исключениеStopIterationот самогоsourceпри попытке чтения. Если генератор выдал последнюю полную пачку и был закрыт потребителем до следующего обращения к источнику,StopIterationещё не произошёл, поэтому статус завершения остаётсяFalse. Если же генератор уже выдал неполный хвост, факт наступления конца потока уже подтверждён, и даже при немедленном вызовеclose()после хвоста статус финализации считаетсяTrue. - После запуска генератора метод
source.close(completed)должен быть вызван ровно один раз в блоке очистки с вычисленным булевым значением флагаcompleted. Если генератор был закрыт потребителем ещё до первого обращения (до первогоnext()), его тело не выполняется, аsourceостаётся нетронутым.
Ввод и вывод
Стандартные потоки ввода stdin и вывода stdout в решении не используются: считывать ввод и вызывать print() не нужно. После выполнения кода учащегося проверяющая система считывает из пространства имён модуля функцию верхнего уровня acknowledged_batches и вызывает её с проверочными аргументами.
Пример использования
source = AcknowledgedSource([1, 2, 3])
stream = acknowledged_batches(source, 2)
print(next(stream))
print(source.acknowledgements)
print(next(stream))
print(source.acknowledgements)
stream.close()
print(source.closed, source.close_flags[-1]['completed'])
Вывод:
(1, 2)
[]
(3,)
[(1, 2)]
True True
Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.
Отправьте решение, чтобы увидеть результаты тестов.
Связанные задачи
- GeneratorExit и yield при close(): вопрос по генераторам Python
- Генераторы Python: синхронизация потоков после фильтрации
- Генераторы Python: разделите поток между двумя потребителями
- Исправьте остановку генераторного конвейера Python
- Генератор скользящего среднего на Python со сбросом окна
- Генераторы Python: закройте второй источник при ошибке первого
