✅ Решения

⚡ Кратко

Генераторы отличаются от функций yield и сохранением состояния. for не выводит StopIteration. yield from работает со списками. JSON с не-ASCII символами экранируется по умолчанию.

Ответы на квиз

  1. a — генератор использует yield, а не return. (Утверждение c тоже верное: генератор запоминает состояние.)
  2. a — 0, 1, 4, 9. Цикл for сам обрабатывает StopIteration и не выводит его.
  3. a, c, d — генератор вычисляет элементы по запросу, работает в for и занимает меньше памяти, чем список. Вариант b неверен: один и тот же объект генератора нельзя перезапустить.
  4. b и d — оба варианта создают генератор. Вариант b — генераторная функция, d — генераторное выражение.
  5. c — A, B, C, StopIteration. После исчерпания списка генератор поднимает StopIteration.
  6. a, d, e — все три варианта создают бесконечные генераторы.
  7. c — будет выведен отсортированный и отформатированный JSON. sort_keys и indent можно использовать вместе.
  8. Строка будет содержать символы в кодировке \uXXXX, потому что по умолчанию ensure_ascii=True.
  9. 1-b, 2-e, 3-a, 4-c, 5-a, 6-d.
  10. b — 09-02-2025.
  11. 1-b, 2-a, 3-d, 4-c.
  12. b — 14:30.

Решение практической работы

# overdue_tasks.py
import json
from datetime import datetime
from pathlib import Path


def parse_date(date_str: str) -> datetime:
    return datetime.strptime(date_str, "%d-%m-%Y")


def load_tasks(path: str = "tasks_with_deadline.json") -> list[dict]:
    raw = Path(path).read_text(encoding="utf-8")
    return json.loads(raw)


def get_overdue_tasks(tasks: list[dict], check_date: datetime):
    for task in tasks:
        if task["status"] != "pending":
            continue
        deadline = parse_date(task["deadline"])
        if deadline < check_date:
            yield task


def main() -> None:
    user_input = input("Введите дату проверки (dd-mm-yyyy) или нажмите Enter для текущей: ")
    check_date = parse_date(user_input) if user_input else datetime.now()

    tasks = load_tasks()
    overdue = list(get_overdue_tasks(tasks, check_date))

    if overdue:
        print("Просроченные задачи:")
        for task in overdue:
            print(f"- {task['title']} ({task['deadline']})")
    else:
        print("Просроченных задач нет.")


if __name__ == "__main__":
    main()

Логика решения: генератор get_overdue_tasks фильтрует задачи по статусу и дедлайну без создания промежуточных списков. Даты разбираются через strptime с форматом dd-mm-yyyy, а сравнение выполняется напрямую между объектами datetime.