🏠 Домашнее задание

⚡ Суть задания

Написать декоратор measure_time: сначала без аргументов — 5 вызовов, затем с параметром repeats. Декоратор измеряет среднее время выполнения функции.

Результат: один файл measure_time.py, который можно запустить в VS Code.

📋 Задание 1. Среднее время выполнения

Исходное задание из LMS:

Создайте декоратор measure_time, который измеряет и выводит среднее время выполнения функции за 5 вызовов. Функция может быть любой: например, сортировка списка, чтение из файла или расчёты.

Пример применения:

@measure_time
def compute():
    total = 0
    for i in range(10_000_000):
        total += i
    return total

Пример вывода:

Среднее время выполнения для 5 вызовов: 0.21 секунд
Результат: 49999995000000

✅ Полное решение

import time
import functools


def measure_time(func):
    """Измеряет среднее время выполнения за 5 вызовов."""
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        repeats = 5
        total = 0.0
        for _ in range(repeats):
            start = time.perf_counter()
            result = func(*args, **kwargs)
            total += time.perf_counter() - start
        average = total / repeats
        print(f"Среднее время выполнения для {repeats} вызовов: {average:.2f} секунд")
        return result
    return wrapper


@measure_time
def compute() -> int:
    total = 0
    for i in range(10_000_000):
        total += i
    return total


if __name__ == "__main__":
    result = compute()
    print(f"Результат: {result}")

📋 Задание 2. Среднее время с количеством вызовов

Исходное задание из LMS:

Доработайте декоратор measure_time, чтобы он принимал параметр repeats — количество вызовов функции. Декоратор должен выполнять функцию указанное число раз и выводить среднее время выполнения.

Пример применения:

@measure_time(10)
def compute():
    total = 0
    for i in range(10_000_000):
        total += i
    return total

Пример вывода:

Среднее время выполнения для 10 вызовов: 0.21 секунд
Результат: 49999995000000

✅ Полное решение

import time
import functools


def measure_time(repeats: int = 5):
    """Декоратор-фабрика для измерения среднего времени выполнения."""
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            total = 0.0
            for _ in range(repeats):
                start = time.perf_counter()
                result = func(*args, **kwargs)
                total += time.perf_counter() - start
            average = total / repeats
            print(f"Среднее время выполнения для {repeats} вызовов: {average:.2f} секунд")
            return result
        return wrapper
    return decorator


@measure_time(10)
def compute() -> int:
    total = 0
    for i in range(10_000_000):
        total += i
    return total


if __name__ == "__main__":
    result = compute()
    print(f"Результат: {result}")

🔧 Подготовка окружения

  1. Создайте папку python-fundamentals-practice/lesson-64/.
  2. Создайте файл measure_time.py и скопируйте в него решение второго задания.
  3. Убедитесь, что виртуальное окружение активировано.

🧪 Как проверить решение

  1. Активируйте venv: venv\Scriptsctivate (Windows) или source venv/bin/activate (Mac/Linux).
  2. Запустите: python measure_time.py
  3. Убедитесь, что в консоли появилось сообщение о среднем времени и результат функции.
  4. Проверьте синтаксис: python -m py_compile measure_time.py

💡 Советы и типичные ошибки

  • Не забудьте @functools.wraps(func), иначе имя функции будет wrapper.
  • Всегда возвращайте result из обёртки.
  • Используйте time.perf_counter() вместо time.time() для точных замеров.
  • Для первого задания достаточно двух уровней вложенности; для второго — три.