🐍 Python: Практические задания

Глава 3.3: Параметры и аргументы

📊 Прогресс:

0/0

🟢 Уровень 1: Базовые операции с параметрами

Задача 1.1: Простая функция с позиционными параметрами
Напишите функцию format_test_result(test_name, status, time), которая принимает название теста, статус ("PASS" или "FAIL") и время выполнения. Вызовите её с аргументами: "LoginTest", "PASS", 2.5
💡 Подсказка:
Используйте обычные позиционные параметры
✅ Решение:
def format_test_result(test_name, status, time):
    print(f"Тест: {test_name} | Статус: {status} | Время: {time}с")

format_test_result("LoginTest", "PASS", 2.5)
# Вывод: Тест: LoginTest | Статус: PASS | Время: 2.5с
Задача 1.2: Именованные аргументы
Используя функцию из задачи 1.1, вызовите её с именованными аргументами в обратном порядке для теста "RegistrationTest", статус "FAIL", время 5.3
💡 Подсказка:
Используйте имя_параметра=значение
✅ Решение:
def format_test_result(test_name, status, time):
    print(f"Тест: {test_name} | Статус: {status} | Время: {time}с")

format_test_result(time=5.3, status="FAIL", test_name="RegistrationTest")
# Вывод: Тест: RegistrationTest | Статус: FAIL | Время: 5.3с
Задача 1.3: Простая лямбда-функция
Создайте лямбда-функцию is_passed, которая принимает статус теста и возвращает True, если статус равен "PASS". Проверьте на значениях: "PASS", "FAIL", "SKIP"
💡 Подсказка:
lambda параметр: выражение
✅ Решение:
is_passed = lambda status: status == "PASS"

print(is_passed("PASS"))   # True
print(is_passed("FAIL"))   # False
print(is_passed("SKIP"))   # False

🟡 Уровень 2: Работа с параметрами по умолчанию

Задача 2.1: Функция с параметром по умолчанию
Создайте функцию log_message(message, level="INFO"), которая выводит сообщение с уровнем логирования. Вызовите с сообщениями: "Тест запущен" (без уровня), "Ошибка авторизации" (уровень "ERROR")
💡 Подсказка:
Параметры по умолчанию указываются после обязательных
✅ Решение:
def log_message(message, level="INFO"):
    print(f"[{level}] {message}")

log_message("Тест запущен")
log_message("Ошибка авторизации", "ERROR")
# Вывод:
# [INFO] Тест запущен
# [ERROR] Ошибка авторизации
Задача 2.2: Смешанные аргументы
Создайте функцию create_bug_report(title, priority, assignee="QA Team", status="Open"). Вызовите для бага "Кнопка не работает" с приоритетом "High", используя только позиционные аргументы для обязательных и меняя status на "In Progress"
💡 Подсказка:
Позиционные аргументы всегда перед именованными
✅ Решение:
def create_bug_report(title, priority, assignee="QA Team", status="Open"):
    print(f"Bug: {title}")
    print(f"Priority: {priority}")
    print(f"Assignee: {assignee}")
    print(f"Status: {status}")

create_bug_report("Кнопка не работает", "High", status="In Progress")
# Вывод:
# Bug: Кнопка не работает
# Priority: High
# Assignee: QA Team
# Status: In Progress
Задача 2.3: Ловушка изменяемых значений
Исправьте функцию add_test_case(name, test_suite=[]), которая добавляет тест в набор. Используйте None вместо пустого списка. Добавьте тесты: "test_login", "test_logout", "test_register" в разные вызовы
💡 Подсказка:
Проверяйте if test_suite is None
✅ Решение:
def add_test_case(name, test_suite=None):
    if test_suite is None:
        test_suite = []
    test_suite.append(name)
    return test_suite

suite1 = add_test_case("test_login")
suite2 = add_test_case("test_logout")
suite3 = add_test_case("test_register")

print(suite1)  # ['test_login']
print(suite2)  # ['test_logout']
print(suite3)  # ['test_register']

🟠 Уровень 3: Лямбда-функции и функции высшего порядка

Задача 3.1: Сортировка с лямбдой
Дан список тестов: [("test_api", 3.2), ("test_ui", 1.5), ("test_db", 2.7)]. Отсортируйте по времени выполнения (второй элемент кортежа)
💡 Подсказка:
Используйте sorted() с параметром key и лямбдой
✅ Решение:
tests = [("test_api", 3.2), ("test_ui", 1.5), ("test_db", 2.7)]
sorted_tests = sorted(tests, key=lambda x: x[1])
print(sorted_tests)
# [('test_ui', 1.5), ('test_db', 2.7), ('test_api', 3.2)]
Задача 3.2: Map для преобразования данных
Дан список времён выполнения тестов в секундах: [1.5, 2.3, 0.8, 3.1]. Преобразуйте в миллисекунды (умножить на 1000) используя map и лямбду
💡 Подсказка:
list(map(lambda x: ..., список))
✅ Решение:
times_sec = [1.5, 2.3, 0.8, 3.1]
times_ms = list(map(lambda x: x * 1000, times_sec))
print(times_ms)
# [1500.0, 2300.0, 800.0, 3100.0]
Задача 3.3: Filter для отбора тестов
Дан список результатов: [("test1", "PASS"), ("test2", "FAIL"), ("test3", "PASS"), ("test4", "SKIP")]. Отфильтруйте только проваленные тесты (статус "FAIL")
💡 Подсказка:
filter проверяет условие для каждого элемента
✅ Решение:
results = [("test1", "PASS"), ("test2", "FAIL"), 
          ("test3", "PASS"), ("test4", "SKIP")]
failed_tests = list(filter(lambda x: x[1] == "FAIL", results))
print(failed_tests)
# [('test2', 'FAIL')]
Задача 3.4: Функция как аргумент
Создайте функцию apply_to_tests(test_list, operation), которая применяет операцию ко всем тестам. Список тестов: ["login", "logout", "register"]. Примените функции: str.upper (в верхний регистр) и lambda x: f"test_{x}" (добавить префикс)
💡 Подсказка:
Внутри используйте цикл и вызывайте operation(test)
✅ Решение:
def apply_to_tests(test_list, operation):
    result = []
    for test in test_list:
        result.append(operation(test))
    return result

tests = ["login", "logout", "register"]

# Применяем upper
upper_tests = apply_to_tests(tests, str.upper)
print(upper_tests)  # ['LOGIN', 'LOGOUT', 'REGISTER']

# Применяем добавление префикса
prefixed_tests = apply_to_tests(tests, lambda x: f"test_{x}")
print(prefixed_tests)  # ['test_login', 'test_logout', 'test_register']

🔴 Уровень 4: Функции как объекты и *args

Задача 4.1: Словарь валидаторов
Создайте словарь валидаторов для проверки паролей. Ключи: "length", "uppercase", "digits". Значения - лямбда-функции. Проверьте пароль "Test123!" всеми валидаторами
💡 Подсказка:
validators = {"length": lambda p: len(p) >= 8, ...}
✅ Решение:
validators = {
    "length": lambda p: len(p) >= 8,
    "uppercase": lambda p: any(c.isupper() for c in p),
    "digits": lambda p: any(c.isdigit() for c in p)
}

password = "Test123!"

for check_name, check_func in validators.items():
    result = check_func(password)
    print(f"{check_name}: {'✓' if result else '✗'}")

# Вывод:
# length: ✓
# uppercase: ✓
# digits: ✓
Задача 4.2: Функция с *args
Создайте функцию run_tests(*test_names), которая принимает любое количество названий тестов и выводит их с номерами. Вызовите с тестами: "test_auth", "test_profile", "test_logout"
💡 Подсказка:
Используйте enumerate для нумерации
✅ Решение:
def run_tests(*test_names):
    print(f"Запускаю {len(test_names)} тестов:")
    for i, test in enumerate(test_names, 1):
        print(f"{i}. Выполняется {test}")

run_tests("test_auth", "test_profile", "test_logout")
# Вывод:
# Запускаю 3 тестов:
# 1. Выполняется test_auth
# 2. Выполняется test_profile
# 3. Выполняется test_logout
Задача 4.3: Комбинирование map и filter
Дан список баг-репортов: [("Bug1", "Low"), ("Bug2", "High"), ("Bug3", "Critical"), ("Bug4", "Low")]. Найдите только критичные баги ("High" или "Critical") и преобразуйте в формат "⚠️ НАЗВАНИЕ"
💡 Подсказка:
Сначала filter, потом map
✅ Решение:
bugs = [("Bug1", "Low"), ("Bug2", "High"), 
        ("Bug3", "Critical"), ("Bug4", "Low")]

# Фильтруем важные баги
important = filter(lambda x: x[1] in ["High", "Critical"], bugs)

# Преобразуем в нужный формат
formatted = list(map(lambda x: f"⚠️ {x[0]}", important))

print(formatted)
# ['⚠️ Bug2', '⚠️ Bug3']

🟣 Уровень 5: **kwargs и комбинированные техники

Задача 5.1: Функция с **kwargs
Создайте функцию generate_test_report(test_name, **metrics), которая принимает название теста и произвольные метрики. Вызовите для теста "LoginTest" с метриками: duration=2.5, assertions=15, coverage=85
💡 Подсказка:
Итерируйтесь по metrics.items()
✅ Решение:
def generate_test_report(test_name, **metrics):
    print(f"=== Отчёт для {test_name} ===")
    for metric, value in metrics.items():
        print(f"{metric}: {value}")
    print("=" * 30)

generate_test_report("LoginTest", duration=2.5, 
                     assertions=15, coverage=85)
# Вывод:
# === Отчёт для LoginTest ===
# duration: 2.5
# assertions: 15
# coverage: 85
# ==============================
Задача 5.2: Полный набор параметров
Создайте функцию create_test_suite(name, priority="medium", *tests, **config). Вызовите с именем "SmokeTests", добавьте тесты "test_login", "test_main_page" и конфигурацию browser="Chrome", timeout=30
💡 Подсказка:
Соблюдайте порядок параметров
✅ Решение:
def create_test_suite(name, priority="medium", *tests, **config):
    print(f"Test Suite: {name}")
    print(f"Priority: {priority}")
    print(f"Tests ({len(tests)}):")
    for test in tests:
        print(f"  - {test}")
    print("Configuration:")
    for key, value in config.items():
        print(f"  {key}: {value}")

create_test_suite("SmokeTests", "high", "test_login", 
                  "test_main_page", browser="Chrome", timeout=30)
# Вывод:
# Test Suite: SmokeTests
# Priority: high
# Tests (2):
#   - test_login
#   - test_main_page
# Configuration:
#   browser: Chrome
#   timeout: 30
Задача 5.3: Сложная сортировка с лямбдой
Дан список тестовых результатов: [{"name": "test_a", "time": 2.5, "status": "PASS"}, {"name": "test_b", "time": 1.2, "status": "FAIL"}, {"name": "test_c", "time": 1.2, "status": "PASS"}]. Отсортируйте сначала по времени, потом по статусу (FAIL первыми)
💡 Подсказка:
В key можно вернуть кортеж для множественной сортировки
✅ Решение:
results = [
    {"name": "test_a", "time": 2.5, "status": "PASS"},
    {"name": "test_b", "time": 1.2, "status": "FAIL"},
    {"name": "test_c", "time": 1.2, "status": "PASS"}
]

sorted_results = sorted(results, 
    key=lambda x: (x["time"], x["status"] == "PASS"))

for result in sorted_results:
    print(f"{result['name']}: {result['time']}s - {result['status']}")

# Вывод:
# test_b: 1.2s - FAIL
# test_c: 1.2s - PASS
# test_a: 2.5s - PASS

Уровень 6: Распаковка и продвинутые техники

Задача 6.1: Распаковка аргументов
Дана функция validate_input(min_length, max_length, required) и список параметров params = [5, 20, True]. Вызовите функцию, распаковав список
💡 Подсказка:
Используйте * при вызове
✅ Решение:
def validate_input(min_length, max_length, required):
    print(f"Валидация: длина {min_length}-{max_length}, "
          f"обязательное: {required}")

params = [5, 20, True]
validate_input(*params)
# Вывод: Валидация: длина 5-20, обязательное: True
Задача 6.2: Распаковка словаря
Дана функция из задачи 5.1 и словарь метрик test_metrics = {"duration": 3.7, "memory": 128, "cpu": 45}. Вызовите функцию для теста "PerformanceTest", распаковав словарь
💡 Подсказка:
Используйте ** при вызове
✅ Решение:
def generate_test_report(test_name, **metrics):
    print(f"=== Отчёт для {test_name} ===")
    for metric, value in metrics.items():
        print(f"{metric}: {value}")

test_metrics = {"duration": 3.7, "memory": 128, "cpu": 45}
generate_test_report("PerformanceTest", **test_metrics)
# Вывод:
# === Отчёт для PerformanceTest ===
# duration: 3.7
# memory: 128
# cpu: 45
Задача 6.3: Универсальный декоратор времени
Создайте функцию measure_time(func, *args, **kwargs), которая вызывает переданную функцию с аргументами и выводит "Функция {имя} выполнилась". Протестируйте на функциях print("Hello"), len("test"), sorted([3,1,2])
💡 Подсказка:
func.__name__ даёт имя функции
✅ Решение:
def measure_time(func, *args, **kwargs):
    result = func(*args, **kwargs)
    print(f"Функция {func.__name__} выполнилась")
    return result

# Тестируем
measure_time(print, "Hello")
# Hello
# Функция print выполнилась

length = measure_time(len, "test")
print(f"Длина: {length}")
# Функция len выполнилась
# Длина: 4

sorted_list = measure_time(sorted, [3, 1, 2])
print(f"Отсортировано: {sorted_list}")
# Функция sorted выполнилась
# Отсортировано: [1, 2, 3]

💡 Полезные советы

📌 Ключевые концепции главы:
  1. Параметры vs Аргументы
    • Параметры - в определении функции
    • Аргументы - при вызове функции
  2. Типы параметров (в правильном порядке)
    • Обязательные позиционные
    • Со значениями по умолчанию
    • *args (собирает позиционные в кортеж)
    • **kwargs (собирает именованные в словарь)
  3. Лямбда-функции
    • lambda параметры: выражение
    • Используйте для простых операций
    • Отлично работают с map(), filter(), sorted()
  4. Функции как объекты
    • Можно сохранять в переменные (без скобок!)
    • Можно передавать как аргументы
    • Можно хранить в словарях
  5. Распаковка
    • *список - распаковывает в позиционные аргументы
    • **словарь - распаковывает в именованные аргументы
⚠️ Частые ошибки: