Основная часть
Эту часть практических вопросов нужно успеть сделать на занятии.
Проверять правильность ответов на ПСП-вопросы можно и нужно из терминала вот таким образом:
Если что-то не так, будет выведено сообщение об ошибке с указанием функции и номера строки в файле. |
Вопрос 1: Лямбда-выражения (ПСП)
Подумай и запиши, что выведет Python
при обработке следующих выражений.
Если значение выражения является функцией, то вывод интерпретатора будет примерно такой:
|
>>> lambda x: x
______
>>> a = lambda x: x
>>> a(5)
______
>>> b = lambda: 3
>>> b()
______
>>> c = lambda x: lambda: print('123')
>>> c(88)
______
>>> c(88)()
______
>>> d = lambda f: f(4)
>>> def square(x):
... return x * x
>>> d(square)
______
>>> z = 3
>>> e = lambda x: lambda y: lambda: x + y + z
>>> e(0)(1)()
______
>>> f = lambda z: x + z
>>> f(3)
______
>>> higher_order_lambda = lambda f: lambda x: f(x)
>>> g = lambda x: x * x
>>> higher_order_lambda(2)(g)
______
>>> higher_order_lambda(g)(2)
______
>>> call_thrice = lambda f: lambda x: f(f(f(x)))
>>> call_thrice(lambda y: y + 1)(0)
______
>>> print_lambda = lambda z: print(z)
>>> print_lambda
______
>>> one_thousand = print_lambda(1000)
______
>>> one_thousand
______
Помнишь?
|
Вопрос 2: Функции высшего порядка (ПСП)
>>> def even(f):
... def odd(x):
... if x < 0:
... return f(-x)
... return f(x)
... return odd
>>> janet = lambda x: x
>>> brad = even(janet)
>>> brad
______
>>> brad(61)
______
>>> brad(-4)
______
>>> def cake():
... print('гадость')
... def pie():
... print('сладость')
... return 'торт'
... return pie
>>> chocolate = cake()
______
>>> chocolate
______
>>> chocolate()
______
>>> more_chocolate, more_cake = chocolate(), cake
______
>>> more_chocolate
______
>>> def snake(x, y):
... if cake == more_cake:
... return lambda: x + y
... else:
... return x + y
>>> snake(10, 20)
______
>>> snake(10, 20)()
______
>>> cake = 'торт'
>>> snake(10, 20)
______
Не забывай.
|
Вопрос 3: Каррирование лямбдой
Проверять правильность кода в следующих вопросах нужно так:
|
Функцию множества аргументов можно превратить в цепочку функций высшего порядка, каждая из которых — функция одного аргумента.
Напиши функцию lambda_curry2
, которая будет производить такое преобразование для функции двух аргументов. Посмотри на доктест, если задание не очень понятно. Решение должно занимать всего одну строку.
Можешь сначала решить задачу без ограничения по размеру кода, а потом, когда логика будет понятна, переписать как требуется. |
def lambda_curry2(func):
"""
Возвращает каррированную версию функции func от двух аргументов.
>>> from operator import add
>>> x = lambda_curry2(add)
>>> y = x(3)
>>> y(5)
8
"""
return ______
Обязательно.
|
Вопрос 4: Лямбды на диаграммах окружения
Попробуй нарисовать диаграмму окружения для следующего фрагмента кода и предугадать, что получится в итоге.
Решение этого задания не нужно заносить в файл lab_02.py
. Просто нарисуй диаграмму окружения на листе бумаги, а потом проверь себя с помощью сайта Online Python Tutor.
>>> a = lambda x: x * 2 + 1
>>> def b(b, x):
... return b(x + a(x))
>>> x = 3
>>> b(a, x)
______
Дополнительная часть
Эту часть, если есть время, можно поделать и дома.
Вопрос 5: Равенство композиции
Напиши функцию, которая принимает две функции одного аргумента — f
и g
— и возвращает другую функцию одного аргумента x
. Эта функция должна возвращать True
, если f(g(x))
и g(f(x))
равны. Можешь считать, что результат g(x)
можно использовать аргументом для f
и наоборот.
Попробуй в решении использовать compose1 , приведённую ниже для справки.
|
def compose1(f, g):
"""
Возвращает функцию h такую, что h(x) = f(g(x)).
>>> add_one = lambda x: x + 1 # прибавляет единицу к x
>>> square = lambda x: x**2
>>> a1 = compose1(square, add_one) # (x + 1)^2
>>> a1(4)
25
>>> mul_three = lambda x: x * 3 # умножает 3 на x
>>> a2 = compose1(mul_three, a1) # ((x + 1)^2) * 3
>>> a2(4)
75
>>> a2(5)
108
"""
return lambda x: f(g(x))
def composite_identity(f, g):
"""
Возвращает функцию одного аргумента, которая возвращает True,
если f(g(x)) равно g(f(x)). Можешь считать, что результат g(x)
может быть аргументом f, и наоборот.
>>> add_one = lambda x: x + 1 # прибавляет единицу к x
>>> square = lambda x: x**2
>>> b1 = composite_identity(square, add_one)
>>> b1(0) # (0 + 1)^2 == 0^2 + 1
True
>>> b1(4) # (4 + 1)^2 != 4^2 + 1
False
"""
"*** ТВОЙ КОД ЗДЕСЬ ***"
Уже надоело напоминать.
|
Вопрос 6: Считать-непересчитать
Рассмотри две функции count_factors
и count_primes
.
def count_factors(n):
"""Возвращает количество положительных целых делителей n."""
i, count = 1, 0
while i <= n:
if n % i == 0:
count += 1
i += 1
return count
def count_primes(n):
"""Возвращает число простых чисел, встречающихся до и включая n."""
i, count = 1, 0
while i <= n:
if is_prime(i):
count += 1
i += 1
return count
Код этих функций сильно похож. Нужно обобщить логику подсчёта и написать функцию count_cond
, которая принимает функцию двух аргументов condition(n, i)
. Функция count_cond
должна вернуть функцию одного аргумента n
, которая подсчитывает количество целых чисел от 1
до n
, которые удовлетворяют условию condition
.
def count_cond(condition):
"""
Возвращает функцию одного аргумента N, которая подсчитывает все числа от 1 до N,
для которых выполняется предикат condition — функция двух аргументов.
>>> count_factors = count_cond(lambda n, i: n % i == 0)
>>> count_factors(2) # 1, 2
2
>>> count_factors(4) # 1, 2, 4
3
>>> count_factors(12) # 1, 2, 3, 4, 6, 12
6
>>> is_prime = lambda n, i: count_factors(i) == 2
>>> count_primes = count_cond(is_prime)
>>> count_primes(2) # 2
1
>>> count_primes(3) # 2, 3
2
>>> count_primes(4) # 2, 3
2
>>> count_primes(5) # 2, 3, 5
3
>>> count_primes(20) # 2, 3, 5, 7, 11, 13, 17, 19
8
"""
"*** ТВОЙ КОД ЗДЕСЬ ***"
Вошло в привычку?
|
Вопрос 7: Тебе же правда нравятся функции
Напиши функцию cycle
, которая принимает три функции — f1
, f2
и f3
. Функция cycle
должна вернуть другую функцию, которая принимает единственный аргумент n
и возвращает ещё более другую функцию. Последняя должна принимать аргумент x
и циклически применять к нему функции f1
, f2
и f3
столько раз, каково значение n
.
Вот что должно получаться:
-
n = 0
→ возвращаетx
; -
n = 1
→ возвращаетf1(x)
; -
n = 2
→ возвращаетf2( f1(x) )
; -
n = 3
→ возвращаетf3( f2( f1(x) ) )
; -
n = 4
→ (цикл начинается сначала), возвращаетf1( f3( f2( f1(x) ) ) )
; -
и так далее.
def cycle(f1, f2, f3):
"""Возвращает функцию, которая является функцией высшего порядка.
>>> def add1(x):
... return x + 1
>>> def times2(x):
... return x * 2
>>> def add3(x):
... return x + 3
>>> my_cycle = cycle(add1, times2, add3)
>>> identity = my_cycle(0)
>>> identity(5)
5
>>> add_one_then_double = my_cycle(2)
>>> add_one_then_double(1)
4
>>> do_all_functions = my_cycle(3)
>>> do_all_functions(2)
9
>>> do_more_than_a_cycle = my_cycle(4)
>>> do_more_than_a_cycle(2)
10
>>> do_two_cycles = my_cycle(6)
>>> do_two_cycles(1)
19
"""
"*** ТВОЙ КОД ЗДЕСЬ ***"
Не забудь отправить работу на проверку:
|