Генератор с состоянием Python: реализуйте переключатель с гистерезисом
Напишите решение на Python и проверьте его на странице.
Другие упражнения по этой теме: Генератор send в Python: задачи на состояние и управление потоком.
Компаратор гистерезиса
Терморегулятор промышленной печи управляет нагревателем с помощью гистерезиса, защищающего систему от постоянных переключений из-за колебаний показаний. Изначально нагреватель выключен. Его статус меняется только при выходе за пределы рабочего диапазона: если температура падает строго ниже нижнего порога, включается нагрев, а когда поднимается строго выше верхнего — нагреватель выключается. Любые значения внутри диапазона, а также равенство пороговым отметкам сохраняют прежнее состояние системы без изменений.
В процессе работы компаратор может принимать калибровочные сообщения с новой парой температурных границ. Новые пороги вступают в силу немедленно, если нижняя граница строго меньше верхней; при этом текущее состояние нагревателя сразу не пересчитывается и остаётся прежним. Если же предложенная нижняя граница оказалась больше либо равна верхней, калибровка отклоняется с сигналом ошибки, а регулятор продолжает работу со старыми порогами.
Реализуйте сопрограмму компаратора, которая сообщает актуальное состояние нагревателя в ответ на замеры температуры и подтверждает либо отклоняет применение порогов при получении калибровочных данных.
Что уже дано
В заготовке объявлена функция-генератор hysteresis_switch(lower, upper), тело которой вам предстоит написать. Во время исполнения решения доступна вспомогательная функция observe_coroutine_calls(generators, actions), используемая проверяющей системой для контроля состояния сопрограмм.
Что нужно сделать
Реализуйте функцию-сопрограмму hysteresis_switch(lower, upper).
Функция принимает начальные числовые пороги lower и upper (вещественные или целые числа в диапазоне от -1 000 000 до 1 000 000, гарантируется lower < upper). Функция возвращает нативный неинициализированный генератор (сопрограмму).
Правила работы сопрограммы:
- Инициализация: первый вызов
next()илиsend(None)запускает генератор и возвращаетNone. Автоматической инициализации внутри функции быть не должно. - Начальное состояние нагревателя —
False(выключен). - Числовые измерения: если через метод
.send(temperature)передано число (в диапазоне от -1 000 000 до 1 000 000): - при значении строго меньше текущего
lowerнагреватель включается (True); - при значении строго больше текущего
upperнагреватель выключается (False); - при значении внутри диапазона или равном любой из границ сохраняется текущее состояние нагревателя;
- генератор возвращает текущее состояние нагревателя в виде булева значения (
TrueилиFalse). - Сообщения калибровки: передаются в виде кортежа
("calibrate", new_lower, new_upper)с числовыми порогами из того же диапазона: - если
new_lower < new_upper, калибровка считается успешной: пороги немедленно обновляются, генератор возвращаетTrue. Текущее состояние нагревателя при этом не меняется и заново по предыдущим замерам не пересчитывается; - если
new_lower >= new_upper, калибровка отклоняется: сохраняются прежние пороги и текущее состояние нагревателя, генератор возвращаетFalseи продолжает обычную работу без возбуждения исключений. - Каждая созданная сопрограмма независима от других и корректно поддерживает штатное завершение методом
.close()без выдачи дополнительных значений. - В тестах на каждую сопрограмму приходится от 0 до 1000 операций, а количество одновременно работающих сопрограмм составляет от 1 до 3.
Ввод и вывод
Стандартные потоки ввода stdin и вывода stdout в решении не используются: считывать ввод и вызывать print() не нужно. После выполнения кода учащегося проверяющая система считывает из пространства имён модуля функцию верхнего уровня hysteresis_switch и вызывает её с проверочными аргументами.
Пример использования
control = hysteresis_switch(10, 20)
print(next(control))
print(control.send(9))
print(control.send(20))
print(control.send(21))
print(control.send(('calibrate', 30, 40)))
print(control.send(35))
print(control.send(('calibrate', 40, 30)))
print(control.send(29))
control.close()
Вывод:
None True True False True False False True
Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.
Отправьте решение, чтобы увидеть результаты тестов.
Связанные задачи
- Send() до первого next(): ошибка запуска генератора Python
- Генератор с send() на Python: накопление порций и смена лимита
- Учёт трафика через генератор Python: сумма и динамический лимит
- Генератор Python: фильтрация выбросов с изменяемым порогом
- Генератор Python: центрирование данных в скользящем окне
- Send() в Python: накопление импульсов и квантование смещения
