""" Урок 47. Summary session 12 — весь код примеров одним файлом. Источник: subjects/python-fundamentals/course/lessons/47-summary-session-12/examples.html Файл собран автоматически (tools/build_lesson_examples.py): правьте страницу урока. Запуск: python lesson-47.py """ # ==================================================================== # Пример 1. Docstring и help() # ==================================================================== # docstring_example.py def greet(name: str) -> str: """Возвращает строку приветствия. :param name: Имя пользователя. :return: Приветственное сообщение. """ return f"Hello, {name}!" print(greet("Alice")) # Hello, Alice! print(greet.__doc__) # Возвращает строку приветствия. # # :param name: Имя пользователя. # :return: Приветственное сообщение. help(greet) # Help on function greet in module __main__: # # greet(name: str) -> str # Возвращает строку приветствия. # # :param name: Имя пользователя. # :return: Приветственное сообщение. # ==================================================================== # Пример 2. Аннотации типов # ==================================================================== # type_hints_example.py def add(a: int, b: int) -> int: """Возвращает сумму двух целых чисел.""" return a + b def convert_to_celsius(fahrenheit: float) -> float: """Конвертирует температуру из Фаренгейта в Цельсий.""" return (fahrenheit - 32) * 5 / 9 def is_even(number: int) -> bool: """Определяет, является ли число чётным.""" return number % 2 == 0 def log_message(message: str) -> None: """Выводит сообщение в консоль.""" print(f"LOG: {message}") print(add(3, 5)) # 8 print(convert_to_celsius(68.0)) # 20.0 print(is_even(4)) # True log_message("start") # LOG: start # ==================================================================== # Пример 3. Инверсия словаря # ==================================================================== # invert_dict.py original_dict = {"a": 1, "b": 2, "c": 3} inverted_dict = {value: key for key, value in original_dict.items()} print("Инверсированный словарь:", inverted_dict) # Инверсированный словарь: {1: 'a', 2: 'b', 3: 'c'} # ==================================================================== # Пример 4. Замена чисел на слова # ==================================================================== # numbers_to_words.py number_to_word = {1: "один", 2: "два", 3: "три"} data = {"x": 1, "y": 2, "z": 3} translated = { key: number_to_word.get(value, value) for key, value in data.items() } print(translated) # {'x': 'один', 'y': 'два', 'z': 'три'} # ==================================================================== # Пример 5. Факториал # ==================================================================== # factorial.py def factorial(n: int) -> int: """Возвращает факториал неотрицательного целого числа.""" if n == 0 or n == 1: return 1 return n * factorial(n - 1) print(factorial(5)) # 120 # ==================================================================== # Пример 6. Бинарный поиск # ==================================================================== # binary_search.py from typing import Optional def binary_search( arr: list[int], target: int, left: int, right: int ) -> Optional[int]: """Ищет target в отсортированном списке arr. Возвращает индекс или None.""" if left > right: return None mid = (left + right) // 2 if arr[mid] == target: return mid if arr[mid] < target: return binary_search(arr, target, mid + 1, right) return binary_search(arr, target, left, mid - 1) array = [1, 3, 5, 7, 9, 11, 13] print(binary_search(array, 5, 0, len(array) - 1)) # 2 print(binary_search(array, 13, 0, len(array) - 1)) # 6 print(binary_search(array, 8, 0, len(array) - 1)) # None # ==================================================================== # Пример 7. Хвостовая рекурсия и итерация # ==================================================================== # tail_vs_iterative.py def factorial_tail(n: int, accumulator: int = 1) -> int: """Хвостовая рекурсия (не оптимизируется в Python).""" if n == 0 or n == 1: return accumulator return factorial_tail(n - 1, n * accumulator) def factorial_iterative(n: int) -> int: """Итеративный факториал.""" accumulator = 1 while n > 1: accumulator *= n n -= 1 return accumulator print(factorial_tail(5)) # 120 print(factorial_iterative(5)) # 120 # ==================================================================== # Пример 8. Собственный аналог deepcopy # ==================================================================== # custom_deepcopy.py def deep_copy(data): """Рекурсивно копирует списки, кортежи, множества и словари.""" if isinstance(data, list): return [deep_copy(item) for item in data] if isinstance(data, dict): return {key: deep_copy(value) for key, value in data.items()} if isinstance(data, set): return {deep_copy(item) for item in data} if isinstance(data, tuple): return tuple(deep_copy(item) for item in data) return data original = [[1, 2], (4, [5, 6], {7, 8}), {"a": 9, "b": [10, 11]}] copied = deep_copy(original) original[1][1][0] = 0 print("Оригинал:", original) # Оригинал: [[1, 2], (4, [0, 6], {8, 7}), {'a': 9, 'b': [10, 11]}] print("Копия: ", copied) # Копия: [[1, 2], (4, [5, 6], {8, 7}), {'a': 9, 'b': [10, 11]}] # ==================================================================== # Пример 9. Guard clause и что происходит без базового случая # ==================================================================== # factorial_guard.py def factorial_safe(n: int) -> int: """Возвращает факториал неотрицательного целого числа. :raises ValueError: если n отрицательное. """ if n < 0: raise ValueError("n must be >= 0") if n == 0 or n == 1: return 1 return n * factorial_safe(n - 1) def factorial_broken(n: int) -> int: """Без базового случая — рекурсия никогда не остановится.""" return n * factorial_broken(n - 1) print(factorial_safe(5)) # 120 try: factorial_safe(-3) except ValueError as error: print("ValueError:", error) # ValueError: n must be >= 0 try: factorial_broken(5) except RecursionError as error: print("RecursionError:", error) # RecursionError: maximum recursion depth exceeded # ==================================================================== # Пример 10. Сумма цифр числа (рекурсия по разрядам) # ==================================================================== # sum_digits.py def sum_digits(n: int) -> int: """Возвращает сумму цифр неотрицательного целого числа.""" if n < 10: return n return n % 10 + sum_digits(n // 10) print(sum_digits(43197)) # 24 # ==================================================================== # Пример 11. Сумма чисел во вложенных списках # ==================================================================== # sum_nested.py def sum_nested(numbers: list) -> int: """Рекурсивно суммирует числа во вложенных списках.""" total = 0 for item in numbers: if isinstance(item, list): total += sum_nested(item) else: total += item return total nested_numbers = [1, [2, 3], [4, [5, 6]], 7] print(sum_nested(nested_numbers)) # 28