Генераторы Python: синхронизация потоков после фильтрации

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

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

Синхронизация потоков датчиков

Контрольный модуль сопоставляет показания двух независимых источников: поток первичных телеметрических замеров и поток контрольных калибровок. Оба канала представлены генераторами с ленивым вытягиванием, поэтому диспетчер запрашивает данные только по мере необходимости.

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

Сессия завершается успехом, как только зафиксировано первое схождение — абсолютная разность между первичным замером и калибровкой не превышает допустимой погрешности. Если же любой из источников исчерпается раньше, работа прерывается. При любой остановке модуль обязан закрыть оба генератора.

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

Что уже дано

В редакторе представлена заготовка функции synchronize_streams, которую необходимо реализовать.

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

Напишите функцию synchronize_streams(primary, control, threshold, tolerance).

Аргументы:

  • primary — одноразовый итератор целых чисел (канал первичных замеров) с методом close();
  • control — одноразовый итератор целых чисел (канал калибровок) с методом close();
  • threshold — целое число, порог чувствительности для первичного потока;
  • tolerance — неотрицательное целое число, допустимая погрешность схождения.

Правила синхронизации:

  • Значения из primary считываются по одному. Замер считается принятым, только если он строго больше порога: primary_val > threshold. Значения меньше либо равные порогу считаются шумом и отбрасываются.
  • Из канала control следующее значение запрашивается ровно один раз и только тогда, когда получено принятое значение из primary.
  • После получения контрольного значения проверяется условие схождения: abs(primary_val - control_val) <= tolerance. При первом же выполнении этого условия чтение немедленно прекращается.
  • Если любой из каналов исчерпался (StopIteration), чтение немедленно прекращается без дополнительных запросов к другому каналу.
  • При любом выходе из функции (при успешном схождении или при исчерпании любого из потоков) необходимо гарантированно вызвать метод .close() у обоих каналов (primary и control). Порядок вызова close() может быть любым. Не допускается преждевременный запуск неначатого генератора.

Функция должна вернуть кортеж из трёх элементов: (pair, primary_count, control_count):

  • pair — кортеж (primary_val, control_val) для первой сошедшейся пары значений, либо None, если схождение не было достигнуто до исчерпания хотя бы одного потока;
  • primary_count — общее число успешных чтений из канала primary (включая отброшенные шумовые замеры);
  • control_count — общее число успешных чтений из канала control.

Неудачные попытки чтения (вызвавшие StopIteration) в счётчики не включаются.

Диапазоны значений:

  • Длина каждого источника: от 0 до 1000 элементов;
  • Значения замеров и порог threshold: от -1 000 000 до 1 000 000;
  • Погрешность tolerance: от 0 до 2 000 000.

Ввод и вывод

Стандартный поток ввода stdin не используется. Печатать через print в stdout ничего не нужно: после выполнения кода учащегося проверяющая система напрямую вызывает функцию верхнего уровня synchronize_streams.

РешениеPython

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

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

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