I am looking at this code challenge:
Define a function cycle that takes in three functions
f1
,f2
,f3
, as arguments. cycle will return another function that should take in an integer argument n and return another function. That final function should take in an argumentx
and cycle through applyingf1
,f2
, andf3
tox
, depending on whatn
was.Here's what the final function should do to
x
for a few values ofn
:
n
= 0, returnx
n
= 1, applyf1
tox
, or returnf1(x)
n
= 2, applyf1
tox
and thenf2
to the result of that, or returnf2(f1(x))
n
= 3, applyf1
tox
,f2
to the result of applyingf1
, and thenf3
to the result of applyingf2
, orf3(f2(f1(x)))
n
= 4, start the cycle again applyingf1
, thenf2
, thenf3
, thenf1
again, orf1(f3(f2(f1(x))))
And so forth.
Below is my code, but the following error occurs for the case add_one_then_double
:
RecursionError: maximum recursion depth exceeded
Could anybody help me on this? Thank you!
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
"""
def cycle_func(n):
i=1
result=lambda x:x
while i<n 1:
if i%3==1:
result=lambda x: f1(result(x))
elif i%3==2:
result=lambda x: f2(result(x))
else:
result=lambda x: f3(result(x))
i=i 1
return result
return cycle_func
CodePudding user response:
The problem is statements like this one:
result=lambda x: f1(result(x))
When this assignment is executed, result
will be assigned this new lambda function. When later it is executed, result(x)
will be a reference to this same function, and thus there is an infinite recursion. Here you intended to have a reference to the previous value of result
, but as you can see, that was lost at the moment this assignment took place.
The solution, is to not create those "little" lambda functions there, but to create one inner function that gets the value of x
, and will then go through this logic of determining what to execute next.
Here is the corrected code:
def cycle(f1, f2, f3):
def cycle_func(n):
def inner(x):
i = 1
result = x
while i < n 1:
if i % 3 == 1:
result = f1(result)
elif i % 3 == 2:
result = f2(result)
else:
result = f3(result)
i = i 1
return result
return inner
return cycle_func
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)
print(identity(5)) # 5
add_one_then_double = my_cycle(2)
print(add_one_then_double(1)) # 4
do_all_functions = my_cycle(3)
print(do_all_functions(2)) # 9
do_more_than_a_cycle = my_cycle(4)
print(do_more_than_a_cycle(2)) # 10
do_two_cycles = my_cycle(6)
print(do_two_cycles(1)) # 19