2

I came across the following homework problem:

enter image description here

My code for this problem was marked wrong and when I viewed the suggested solution, I couldn't understand where I went wrong. I ran the codes of both functions in Python IDLE compiler only to see that both functions return the same output as seen below:

>>> def dual_function(f,g,n): #Suggested solution
    def helper(x):
        f1,g1 = f,g
        if n%2==0:
            f1,g1=g1,f1
        for i in range(n):
            x=f1(x)
            f1,g1=g1,f1
        return x
    return helper

>>> def dual_function_two(f,g,n): #My solution
    def helper(x):
        if n%2==0:
            for i in range (n):
                if i%2==0:
                    x = g(x)
                else:
                    x = f(x)
        else:
            for i in range(n):
                if i%2==0:
                    x = f(x)
                else:
                    x = g(x)
        return x
    return helper

>>> add1 = lambda x: x+1
>>> add2 = lambda x: x+2
>>> dual_function(add1,add2,4)(3)
9
>>> dual_function_two(add1,add2,4)(3)
9
>>> 

I would appreciate it if someone could identify the mistake in my solution. Thank you.

6
  • 2
    Do you know the test cases used to grade your problem? I can't find any case where the two functions differ. Commented Mar 27, 2019 at 4:26
  • 2
    Those aren't good test functions, since addition is commutative -- if you called them in the wrong order you wouldn't notice the difference. But I tried mixing addition and multiplication, and I couldn't find a difference, either. Commented Mar 27, 2019 at 4:57
  • 1
    It's probably much slower than the suggested solution due to the constant modulo operations. Swapping is going to be much faster. Commented Mar 27, 2019 at 5:02
  • @Sebastian Unfortunately, I do not have the test cases :( Commented Mar 27, 2019 at 6:19
  • @Barmar Thank you for letting me know about using commutative operators in such functions, will remember them when working on similar problems in the future. Commented Mar 27, 2019 at 6:20

1 Answer 1

2

The suggested solution is needlessly complex. Countless reassignments of variables and a loop are a recipe for a headache. Here's a simplified alternative -

def dual (f, g, n):
  if n == 0:
    return lambda x: x
  else:
    return lambda x: f(dual(g, f, n - 1)(x))

add1 = lambda x: 1 + x
add2 = lambda x: 2 + x

print(dual(add1,add2,4)(3))
# 9
# (1 + 2 + 1 + 2 + 3)

print(dual(add1,add2,9)(3))
# 16
# (1 + 2 + 1 + 2 + 1 + 2 + 1 + 2 + 1 + 3)

print(dual(add1,add2,0)(3))
# 3

The reason this works is because in the recursive branch, we call dual with swapped arguments, dual(g,f,n-1). So f and g change places each time as n decrements down to 0, the base case, which returns the identity (no-op) function.

A slightly less readable version, but works identically -

def dual (f, g, n):
  return lambda x: \
    x if n == 0 else f(dual(g, f, n - 1)(x))
Sign up to request clarification or add additional context in comments.

1 Comment

Great, never knew I could be this simple. Thanks for the explanation! :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.