""" Урок 69. Практикум 17 — весь код примеров одним файлом. Источник: subjects/python-fundamentals/course/lessons/69-practice-17/examples.html Файл собран автоматически (tools/build_lesson_examples.py): правьте страницу урока. Запуск: python lesson-69.py """ # ==================================================================== # Полный рабочий код класса Student # ==================================================================== from datetime import datetime, date class Student: current_id: int = 1 MIN_AGE: int = 16 def __init__(self, name: str, birth_date: str) -> None: self.birth_date = datetime.strptime(birth_date, "%Y-%m-%d").date() if not self.is_valid_birthdate(): raise ValueError("Student must be at least 16 years old.") self.name = name self.student_id = Student.current_id Student.current_id += 1 def __str__(self) -> str: return f"Student: {self.name}, birth_date: {self.birth_date}, ID: {self.student_id}" def __repr__(self) -> str: return ( f"Student(name={self.name!r}, birth_date={self.birth_date!r}, " f"student_id={self.student_id!r})" ) def show_info(self) -> None: print( f"Student:\n\tName: {self.name}\n\tAge: {self.calculate_age()}\n\tID: {self.student_id}" ) def calculate_age(self) -> int: today = date.today() return self.calculate_age_on(today) def calculate_age_on(self, target_date: date) -> int: age = target_date.year - self.birth_date.year if (target_date.month, target_date.day) < (self.birth_date.month, self.birth_date.day): age -= 1 return age def is_valid_birthdate(self) -> bool: return self.calculate_age() >= self.MIN_AGE @classmethod def from_string(cls, data: str) -> "Student": name, date_string = map(str.strip, data.split(",")) return cls(name, date_string) @staticmethod def filter_by_min_age(students: list["Student"], min_age: int) -> list["Student"]: return [s for s in students if s.calculate_age() >= min_age] # Создание студентов разными способами s1 = Student("Alice", "2005-05-10") s2 = Student.from_string("Bob, 2001-12-03") print(s1) s1.show_info() print(s2) s2.show_info() # Возраст на конкретную дату some_date = date(2030, 5, 10) print(f"Alice will be {s1.calculate_age_on(some_date)} on {some_date}") # Фильтрация по возрасту print("Min age 21:") for student in Student.filter_by_min_age([s1, s2], 21): print("\t", student) # Проверка валидации try: Student("Bill", "2009-05-15") except ValueError as error: print(f"ValueError: {error}") # ==================================================================== # Пример 1. Парсинг даты # ==================================================================== from datetime import datetime birth_date = datetime.strptime("2005-05-10", "%Y-%m-%d").date() print(birth_date) # 2005-05-10 print(type(birth_date)) # # ==================================================================== # Пример 2. Корректный подсчёт возраста # ==================================================================== from datetime import date birth_date = date(2005, 5, 10) today = date(2026, 3, 8) age = today.year - birth_date.year if (today.month, today.day) < (birth_date.month, birth_date.day): age -= 1 print(age) # 20, а не 21, потому что день рождения ещё не наступил # ==================================================================== # Пример 3. Альтернативный конструктор # ==================================================================== class Student: def __init__(self, name: str, birth_date: str) -> None: self.name = name self.birth_date = birth_date @classmethod def from_string(cls, data: str) -> "Student": name, date_string = map(str.strip, data.split(",")) return cls(name, date_string) s = Student.from_string("Bob, 2001-12-03") print(s.name) # Bob print(s.birth_date) # 2001-12-03 # ==================================================================== # Пример 4. Статический метод фильтрации # ==================================================================== class Student: def __init__(self, name: str, age: int) -> None: self.name = name self.age = age @staticmethod def filter_by_min_age(students: list["Student"], min_age: int) -> list["Student"]: return [s for s in students if s.age >= min_age] s1 = Student("Alice", 19) s2 = Student("Bob", 23) print(Student.filter_by_min_age([s1, s2], 21)) # [Bob]