""" Урок 59. Summary session 15 — весь код примеров одним файлом. Источник: subjects/python-fundamentals/course/lessons/59-summary-session-15/examples.html Файл собран автоматически (tools/build_lesson_examples.py): правьте страницу урока. Запуск: python lesson-59.py """ # ==================================================================== # Пример 1. Генератор с yield # ==================================================================== # generator_01_basic.py def count_up_to(n: int): count = 1 while count <= n: yield count count += 1 gen = count_up_to(5) print(type(gen)) for number in gen: print(number) # генератор одноразовый: второй проход ничего не даст print(list(gen)) # # 1 # 2 # 3 # 4 # 5 # [] # ==================================================================== # Пример 2. Бесконечный генератор и явная остановка # ==================================================================== # generator_02_infinite.py def infinite_counter(start: int = 1): count = start while True: yield count count += 1 gen = infinite_counter() for number in gen: if number > 5: break print(number) # 1 # 2 # 3 # 4 # 5 # ==================================================================== # Пример 3. yield from — делегирование другому генератору # ==================================================================== # generator_03_yield_from.py def process_values(data: list[int]): for value in data: yield value * 2 def main_generator(*sequences: list[int]): for seq in sequences: yield from process_values(seq) for result in main_generator([1, 2, 3], [10, 15]): print(result) # 2 # 4 # 6 # 20 # 30 # ==================================================================== # Пример 4. Принудительное закрытие генератора # ==================================================================== # generator_04_close.py def sensor_data(data: list[int]): for value in data: yield value numbers = [10, 20, 30, 40, 50] gen = sensor_data(numbers) for element in gen: print("Получено значение:", element) if element >= 30: print("Значение найдено, закрываем генератор.") gen.close() break try: next(gen) except StopIteration as error: print("StopIteration после close():", repr(error)) # Получено значение: 10 # Получено значение: 20 # Получено значение: 30 # Значение найдено, закрываем генератор. # StopIteration после close(): StopIteration() # ==================================================================== # Пример 5. Почему генератор экономит память # ==================================================================== # generator_05_memory.py import sys million = range(1_000_000) as_list = [x * x for x in million] as_generator = (x * x for x in million) print("list:", sys.getsizeof(as_list), "байт") print("generator:", sys.getsizeof(as_generator), "байт") total_list = sum(as_list) total_gen = sum(as_generator) print("Суммы совпадают:", total_list == total_gen, total_list) # list: 8448728 байт # generator: 208 байт # Суммы совпадают: True 333332833333500000 # ==================================================================== # Пример 6. Файлы: режимы, кодировка и with # ==================================================================== # file_01_read_write.py lines = ["Первая строка\n", "Вторая строка\n", "Третья строка\n"] with open("demo.txt", "w", encoding="utf-8") as file: file.writelines(lines) with open("demo.txt", "r", encoding="utf-8") as file: content = file.read() print(repr(content)) with open("demo.txt", "r", encoding="utf-8") as file: for line in file: print(line.strip().upper()) with open("demo.txt", "a", encoding="utf-8") as file: file.write("Добавленная строка\n") with open("demo.txt", "r", encoding="utf-8") as file: print(file.readlines()) # 'Первая строка\nВторая строка\nТретья строка\n' # ПЕРВАЯ СТРОКА # ВТОРАЯ СТРОКА # ТРЕТЬЯ СТРОКА # ['Первая строка\n', 'Вторая строка\n', 'Третья строка\n', 'Добавленная строка\n'] # ==================================================================== # Пример 7. Генератор для ленивого чтения файла # ==================================================================== # file_02_lazy_reading_generator.py def read_non_empty_lines(path: str): with open(path, "r", encoding="utf-8") as file: for line in file: stripped = line.strip() if stripped: yield stripped with open("log.txt", "w", encoding="utf-8") as file: file.write("Строка 1\n\nСтрока 2\n \nСтрока 3\n") for entry in read_non_empty_lines("log.txt"): print(entry) # Строка 1 # Строка 2 # Строка 3 # ==================================================================== # Пример 8. JSON: сериализация, десериализация и форматирование # ==================================================================== # json_01_basic.py import json person = {"name": "Alice", "age": 25, "is_student": False, "pet": None} json_string = json.dumps(person, ensure_ascii=False, indent=2) print(json_string) loaded = json.loads(json_string) print(loaded["name"], type(loaded)) city = {"country": "Беларусь", "city": "Минск"} print(json.dumps(city)) print(json.dumps(city, ensure_ascii=False)) print(json.dumps(city, ensure_ascii=False, sort_keys=True)) # { # "name": "Alice", # "age": 25, # "is_student": false, # "pet": null # } # Alice # {"country": "\u0411\u0435\u043b\u0430\u0440\u0443\u0441\u044c", "city": "\u041c\u0438\u043d\u0441\u043a"} # {"country": "Беларусь", "city": "Минск"} # {"city": "Минск", "country": "Беларусь"} # ==================================================================== # Пример 9. JSON: файл и обработка JSONDecodeError # ==================================================================== # json_02_file_and_errors.py import json data = {"tasks": ["Купить билеты", "Сдать отчёт"], "count": 2} with open("data.json", "w", encoding="utf-8") as file: json.dump(data, file, ensure_ascii=False, indent=2) with open("data.json", "r", encoding="utf-8") as file: restored = json.load(file) print(restored) broken_json = "{'x': 1}" try: json.loads(broken_json) except json.JSONDecodeError as error: print("JSONDecodeError:", error) # {'tasks': ['Купить билеты', 'Сдать отчёт'], 'count': 2} # JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1) # ==================================================================== # Пример 10. datetime: текущее время, форматы и разница дат # ==================================================================== # datetime_01_basic.py from datetime import datetime, timedelta now = datetime.now() print(type(now)) print(now.strftime("%d.%m.%Y %H:%M:%S")) deadline = datetime.strptime("01.12.2026", "%d.%m.%Y") days_left = (deadline - now).days print(f"До дедлайна осталось дней: {days_left}") print(deadline > now) future = now + timedelta(weeks=2) print(future.strftime("%Y-%m-%d")) # # 13.08.2026 21:01:02 (у вас будет другое время — используется текущий момент) # До дедлайна осталось дней: 109 (у вас будет другое число — зависит от сегодняшней даты) # True # 2026-08-27 (у вас будет другая дата — это "через 2 недели от сегодня") # ==================================================================== # Пример 11. Капстоун: просроченные задачи из JSON через генератор # ==================================================================== # capstone_overdue_tasks.py import json from datetime import datetime tasks_json = """ [ {"title": "Audit finances", "deadline": "23-12-2025", "status": "done"}, {"title": "Plan event", "deadline": "15-09-2025", "status": "pending"}, {"title": "Team meeting", "deadline": "15-04-2025", "status": "pending"}, {"title": "Backup server", "deadline": "19-03-2025", "status": "pending"}, {"title": "Sign contract", "deadline": "28-07-2025", "status": "pending"} ] """ def load_tasks(raw_json: str): return json.loads(raw_json) def overdue_tasks(tasks: list[dict], check_date: datetime): for task in tasks: if task["status"] != "pending": continue deadline = datetime.strptime(task["deadline"], "%d-%m-%Y") if deadline < check_date: yield task tasks = load_tasks(tasks_json) check_date = datetime.strptime("01-08-2025", "%d-%m-%Y") for task in overdue_tasks(tasks, check_date): print(f"- {task['title']} ({task['deadline']})") # - Team meeting (15-04-2025) # - Backup server (19-03-2025) # - Sign contract (28-07-2025)