""" Урок 45. Практикум 11 — весь код примеров одним файлом. Источник: subjects/python-fundamentals/course/lessons/45-practice-11/examples.html Файл собран автоматически (tools/build_lesson_examples.py): правьте страницу урока. Запуск: python lesson-45.py """ # ==================================================================== # Пример 1. Предикат и фильтрация # ==================================================================== # predicate_filter.py from typing import Callable def is_even(n: int) -> bool: return n % 2 == 0 def filter_numbers( predicate: Callable[[int], bool], numbers: list[int] ) -> list[int]: return [n for n in numbers if predicate(n)] nums = [1, 2, 3, 4, 5, 6] print(filter_numbers(is_even, nums)) # [2, 4, 6] # ==================================================================== # Пример 2. Фильтрация с lambda # ==================================================================== # lambda_filter.py nums = [1, 2, 3, 4, 5, 6] evens = list(filter(lambda x: x % 2 == 0, nums)) print(evens) # [2, 4, 6] raw = filter(lambda x: x % 2 == 0, nums) print(raw) # # ==================================================================== # Пример 3. Агрегирование через reduce # ==================================================================== # reduce_product.py from functools import reduce def product(numbers: list[int]) -> int: return reduce(lambda acc, x: acc * x, numbers, 1) numbers = [1, 2, 3, 4, 5] print(product(numbers)) # 120 print(product([])) # 1 — начальное значение спасает пустой список # ==================================================================== # Пример 4. Сортировка по длине # ==================================================================== # sort_by_length.py def sort_by_length(words: list[str]) -> list[str]: return sorted(words, key=len) words = ["apple", "banana", "kiwi", "grape"] print(sort_by_length(words)) # ['kiwi', 'apple', 'grape', 'banana'] print(words) # ['apple', 'banana', 'kiwi', 'grape'] — исходный список не тронут # ==================================================================== # Пример 5. Сортировка по сумме кодов символов # ==================================================================== # sort_by_ord_sum.py words = ["banana", "kiwi", "grapefruit", "apple"] sorted_words = sorted(words, key=lambda word: sum(ord(c) for c in word)) print(sorted_words) # ['kiwi', 'apple', 'banana', 'grapefruit'] for word in words: print(word, sum(ord(c) for c in word)) # banana 609 # kiwi 436 # grapefruit 1081 # apple 530 # ==================================================================== # Пример 6. Композиция функций для шифрования # ==================================================================== # encryption_chain.py from typing import Callable def to_uppercase(text: str) -> str: return text.upper() def shift_encrypt(text: str, shift: int = 5) -> str: return "".join(chr(ord(c) + shift) for c in text) def reverse_string(text: str) -> str: return text[::-1] def encrypt( text: str, functions: list[Callable[[str], str]] ) -> str: result = text for func in functions: result = func(result) return result sentence = "Functional programming is powerful" functions = [to_uppercase, shift_encrypt, reverse_string] print(encrypt(sentence, functions)) # QZKWJ\TU%XN%LSNRRFWLTWU%QFSTNYHSZK # ==================================================================== # Пример 7. Фабрика типизированных предикатов # ==================================================================== # predicate_factory.py from typing import Callable def make_min_length_predicate(min_len: int) -> Callable[[str], bool]: def predicate(word: str) -> bool: return len(word) >= min_len return predicate def filter_words( predicate: Callable[[str], bool], words: list[str] ) -> list[str]: return [word for word in words if predicate(word)] words = ["hi", "Hello", "a", "python", "Ok"] at_least_two = make_min_length_predicate(2) at_least_five = make_min_length_predicate(5) print(filter_words(at_least_two, words)) # ['hi', 'Hello', 'python', 'Ok'] print(filter_words(at_least_five, words)) # ['Hello', 'python'] # ==================================================================== # Пример 8. Типичная ошибка: вызов предиката вместо передачи ссылки # ==================================================================== # common_mistakes.py def is_even(n: int) -> bool: return n % 2 == 0 nums = [1, 2, 3, 4, 5, 6] try: bad = list(filter(is_even(), nums)) # ошибка: is_even() вызван без аргумента except TypeError as error: print("TypeError:", error) # TypeError: is_even() missing 1 required positional argument: 'n' good = list(filter(is_even, nums)) # верно: передаём ссылку, вызовет сам filter print(good) # [2, 4, 6] forgot_list = filter(is_even, nums) print(forgot_list) # — забыли list() print(list(forgot_list)) # [2, 4, 6] # ==================================================================== # Пример 9. Готовые инструменты вместо lambda: itemgetter и partial # ==================================================================== # partial_itemgetter.py from functools import partial from operator import itemgetter students_avg = {"Charlie": 92.33, "Alice": 87.67, "Diana": 84.67, "Bob": 78.0} by_score = sorted(students_avg.items(), key=itemgetter(1), reverse=True) print(by_score) # [('Charlie', 92.33), ('Alice', 87.67), ('Diana', 84.67), ('Bob', 78.0)] # itemgetter(1) делает то же, что lambda item: item[1] round_to_1 = partial(round, ndigits=1) print(list(map(round_to_1, [92.33, 87.666, 84.674]))) # [92.3, 87.7, 84.7] # ==================================================================== # Пример 10. Очередь задач с ограничением времени (задание 5) # ==================================================================== # task_queue_limit.py def schedule_within_limit( tasks: dict[str, int], time_limit: int ) -> dict[str, int]: ordered = sorted(tasks.items(), key=lambda item: item[1], reverse=True) selected: dict[str, int] = {} total = 0 for name, duration in ordered: if total + duration <= time_limit: selected[name] = duration total += duration return selected tasks = {"task1": 5, "task2": 3, "task3": 7, "task4": 2} print(schedule_within_limit(tasks, 10)) # {'task3': 7, 'task2': 3}