Контекстный менеджер Python: временные настройки и сбор результатов

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

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

Сессия калибровки стенда

На испытательном стенде проверяют аналоговые датчики. Во время калибровки стенд временно подменяет свой глобальный рабочий профиль чувствительности на тестовый список параметров. За эту подмену и сбор данных отвечает специальный контекстный менеджер. При входе в блок with он запоминает исходный профиль стенда, устанавливает тестовый, обнуляет собственный внутренний список замеров и возвращает этот же свежий пустой список, куда тестовый скрипт напрямую записывает сырые показания.

При любом выходе из блока менеджер гарантированно возвращает стенду его первоначальный профиль и фиксирует итог в отчёте. Если сессия завершилась штатно, в отчёт заносится статус 'OK'. Если возник технологический сбой из-за нестабильности датчика (DriftError), менеджер подавляет это исключение, сохраняет все накопившиеся до аварии замеры и выставляет статус 'REJECTED'. Если же происходит любая непредвиденная системная ошибка, выставляется статус 'CRASH', а само исключение беспрепятственно пропускается наружу.

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

Что уже дано

В среде выполнения доступны класс исключения DriftError и класс CalibrationStand(profile) с изменяемым атрибутом .profile, содержащим список профиля. Реализовывать их заново не требуется.

В редакторе объявлен класс CalibrationSession, конструктор и методы протокола контекстного менеджера которого вам предстоит написать.

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

Реализуйте класс CalibrationSession(stand, test_profile) со следующими методами и атрибутами:

  • Конструктор __init__(self, stand, test_profile) принимает стенд stand и список test_profile, принадлежащий вызывающему коду.
  • Метод __enter__(self):
  • сохраняет текущий объект stand.profile;
  • устанавливает в stand.profile ссылку на test_profile;
  • создаёт новый пустой список в атрибуте self.measurements;
  • возвращает этот же созданный список self.measurements в качестве целевой переменной блока with.
  • Метод __exit__(self, exc_type, exc_val, exc_tb):
  • гарантированно возвращает исходный сохранённый объект профиля обратно в stand.profile;
  • сохраняет в self.measurements все собранные за время сессии сырые замеры в порядке их поступления;
  • при штатном выходе (без исключений) устанавливает атрибут self.report = 'OK';
  • если произошло исключение типа DriftError (или его подкласса), устанавливает self.report = 'REJECTED' и подавляет ошибку (возвращает истинное значение);
  • при возникновении любого другого исключения (экземпляра BaseException) устанавливает self.report = 'CRASH' и позволяет исходной ошибке всплыть наружу (возвращает ложное значение или None).

Ограничения:

  • Тестирование выполняет от 1 до 100 последовательных входов в контекстный менеджер (вложенные сессии не проверяются).
  • За одну сессию в возвращённый список замеров может быть добавлено от 0 до 1000 произвольных объектов.
  • Профили являются конечными списками.

Ввод и вывод

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

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

stand = CalibrationStand([1, 2])
session = CalibrationSession(stand, [8])
with session as readings:
    readings.extend([10, 11])
print(stand.profile, session.measurements, session.report)

Вывод:

[1, 2] [10, 11] OK
РешениеPython

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

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

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