🏠 Домашнее задание 31

⚡ Кратко

Генератор Фибоначчи, генератор уникальных элементов и анализ курсов студентов через JSON.

Задача 1. Генератор Фибоначчи

Создайте генератор, который генерирует последовательность Фибоначчи бесконечно, возвращая по одному числу за раз.

0
1
1
2
3
5
8
13
21
34

Решение

# fibonacci_generator.py
def fibonacci():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b


if __name__ == "__main__":
    gen = fibonacci()
    for _ in range(10):
        print(next(gen))

Задача 2. Генератор уникальных элементов

Создайте генератор, который принимает список элементов и выдаёт только уникальные значения, сохраняя порядок их появления.

data = [3, 1, 2, 3, 4, 1, 5, 2, 6, 7, 5, 8]
# 3, 1, 2, 4, 5, 6, 7, 8

Решение

# unique_generator.py
from typing import Iterable, Any


def unique_elements(items: Iterable[Any]):
    seen = set()
    for item in items:
        if item not in seen:
            seen.add(item)
            yield item


if __name__ == "__main__":
    data = [3, 1, 2, 3, 4, 1, 5, 2, 6, 7, 5, 8]
    for value in unique_elements(data):
        print(value)

Задача 3. Анализ курсов студентов

Реализуйте программу, которая:

  1. Читает файл student_courses.json, содержащий:
    • имя студента;
    • дату рождения (birth_date) в формате дд.мм.гггг;
    • дату поступления (enrollment_date) в том же формате;
    • список курсов.
  2. Вычисляет:
    • общее количество студентов;
    • средний возраст на момент поступления;
    • количество студентов на каждом курсе.
  3. Сохраняет отчёт в student_courses_report.json.

Пример входных данных

[
  {"name": "Diana Williams", "birth_date": "12.06.1983", "enrollment_date": "29.04.2023", "courses": ["Physics", "Chemistry"]},
  {"name": "Tina Miller", "birth_date": "06.07.2004", "enrollment_date": "18.04.2020", "courses": ["Biology", "Business"]}
]

Решение

# student_courses_analysis.py
import json
from datetime import datetime
from pathlib import Path
from collections import Counter


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


def age_at_enrollment(birth_date: str, enrollment_date: str) -> int:
    birth = parse_date(birth_date)
    enrollment = parse_date(enrollment_date)
    age = enrollment.year - birth.year
    if (enrollment.month, enrollment.day) < (birth.month, birth.day):
        age -= 1
    return age


def analyze_students(input_path: str = "student_courses.json",
                     output_path: str = "student_courses_report.json") -> None:
    students = json.loads(Path(input_path).read_text(encoding="utf-8"))

    total = len(students)
    ages = [
        age_at_enrollment(s["birth_date"], s["enrollment_date"])
        for s in students
    ]
    average_age = round(sum(ages) / total, 2) if total else 0
    course_counts = Counter(
        course for student in students for course in student["courses"]
    )

    report = {
        "total_students": total,
        "average_age_at_enrollment": average_age,
        "course_counts": dict(course_counts),
    }

    Path(output_path).write_text(
        json.dumps(report, ensure_ascii=False, indent=2),
        encoding="utf-8"
    )
    print(f"Отчёт сохранён в {output_path}")


if __name__ == "__main__":
    analyze_students()

Как проверить в VS Code

  1. Создайте файл student_courses.json с тестовыми данными.
  2. Создайте файл с решением.
  3. Запустите: python student_courses_analysis.py
  4. Проверьте файл student_courses_report.json.
Проверить по документации: в production-коде для работы с файлами рекомендуется использовать pathlib.Path вместо строковых путей и оборачивать чтение JSON в try-except json.JSONDecodeError.