Файл: Решение n 1 while n2 n 1 print("Искомое число", n 1) 2.docx

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 08.11.2023

Просмотров: 537

Скачиваний: 3

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

Решение.


import time

def decorator_time(fn):

def wrapper():

print(f"Запустилась функция {fn}")

t0 = time.time()

result = fn()

dt = time.time() - t0

print(f"Функция выполнилась. Время: {dt:.10f}")

return dt # задекорированная функция будет возвращать время работы

return wrapper

def pow_2():

return 10000000 ** 2

def in_build_pow():

return pow(10000000, 2)

pow_2 = decorator_time(pow_2)

in_build_pow = decorator_time(in_build_pow)
pow_2()

# Запустилась функция

# Функция выполнилась. Время: 0.0000011921
in_build_pow()

# Запустилась функция

# Функция выполнилась. Время: 0.0000021458

Итераторы и генераторы, оператор yield

1.


Создать функцию-генератор, возвращающую бесконечную последовательность натуральных чисел. По умолчанию, она начинается с единицы и шагом 1, но пользователь может указать любой шаг и любое число в качестве аргумента функции, с которого будет начинаться последовательность.

Решение.


def count(start=1, step=1):

counter = start

while True:

yield counter

counter += step

2.


Создайте генератор, который по переданному списку создаёт последовательность, в которой элементы этого списка бесконечно циклично повторяются.

Например, для списка [1, 2, 3] генератор создаст бесконечную последовательность 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, ... .

Решение.


def repeat_list(list_):

list_values = list_.copy()

while True:

value = list_values.pop(0)

list_values.append(value)

yield value
for i in repeat_list([1, 2, 3]):

print(i)

 Замыкания и декораторы

1.


Возьмите из предыдущего примера декорированные функции, которые возвращают время работы основной функции. Найдите среднее время выполнения для 100 выполнений каждой функции.

import time

def decorator_time(fn):

def wrapper():

print(f"Запустилась функция {fn}")

t0 = time.time()

result = fn()

dt = time.time() - t0

print(f"Функция выполнилась. Время: {dt:.10f}")

return dt # задекорированная функция будет возвращать время работы

return wrapper

def pow_2():

return 10000000 ** 2

def in_build_pow():

return pow(10000000, 2)

pow_2 = decorator_time(pow_2)

in_build_pow = decorator_time(in_build_pow)
pow_2()

# Запустилась функция

# Функция выполнилась. Время: 0.0000011921
in_build_pow()

# Запустилась функция

# Функция выполнилась. Время: 0.0000021458

Решение.


import time
N = 100

def decorator_time(fn):

def wrapper():

t0 = time.time()

result = fn()

dt = time.time() - t0

return dt

return wrapper

def pow_2():

return 10000000 ** 2

def in_build_pow():

return pow(10000000, 2)

pow_2 = decorator_time(pow_2)

in_build_pow = decorator_time(in_build_pow)
mean_pow_2 = 0

mean_in_build_pow = 0

for _ in range(N):

mean_pow_2 += pow_2()

mean_in_build_pow += in_build_pow()
print(f"Функция {pow_2} выполнялась {N} раз. Среднее время: {mean_pow_2 / N:.10f}")

print(f"Функция {in_build_pow} выполнялась {N} раз. Среднее время: {mean_in_build_pow / N:.10f}")

2.


Напишите декоратор, который будет подсчитывать количество вызовов декорируемой функции. Для хранения переменной содержащей, количество вызовов, используйте nonlocal область декоратора.

Решение.


def counter(func):

count = 0

def wrapper(*args, **kwargs):

nonlocal count

func(*args, **kwargs)

count += 1

print(f"Функция {func} была вызвана {count} раз")

return wrapper
@counter

def say_word(word):

print(word)
say_word("Oo!!!")

# Oo!!!

# Функция была вызвана 1 раз
say_word("Oo!!!")

# Oo!!!

# Функция была вызвана 2 раз

3.


Напишите декоратор, который будет сохранять результаты выполнения декорируемой функции в словаре. Словарь должен находиться в nonlocal области в следующем формате: по ключу располагается аргумент функции, по значению результат работы функции, например, {n: f(n)}.

И при повторном вызове функции будет брать значение из словаря, а не вычислять заново. То есть словарь можно считать промежуточной памятью на время работы программы, где будут храниться ранее вычисленные значения. Исходная функция, которую нужно задекорировать имеет следующий вид и выполняет простое умножение на число 123456789.:

def f(n):

return n * 123456789

Решение.


def cache(func):

cache_dict = {}

def wrapper(num):

nonlocal cache_dict

if num not in cache_dict:

cache_dict[num] = func(num)

print(f"Добавление результата в кэш: {cache_dict[num]}")

else:

print(f"Возвращение результата из кэша: {cache_dict[num]}")

print(f"Кэш {cache_dict}")

return cache_dict[num]

return wrapper