4

I think below two function result will be same, but it is not.

def fib2(n):
  return n and n < 2 or fib2(n-1) + fib2(n-2)

def fib3(m):
  return m if m < 2 else fib3(m-1) + fib3(m-2)

When argument value is 4, fib2's output is 7, fib3's output is 3. Why this situation happen? I don't know about this.
My Python version is 2.7.9 and os is osX 10.11.1

vaultah
  • 36,713
  • 12
  • 105
  • 132

1 Answers1

1

I tried to be more verbose and write your functions like this:

def fib2(n):
    ret = n and n < 2 or fib2(n-1) + fib2(n-2)
    print "fib2({}) = {}".format(n, ret)
    return ret

print fib2(4)

def fib3(m):
    ret = m if m < 2 else fib3(m-1) + fib3(m-2)
    print "fib3({}) = {}".format(m, ret)
    return ret

print fib3(4)

It appears that fib2 tries to add boolean values to numbers, and that's why it's not correct. fib3 handles only numbers and is correct. But notice that it's not a recommended way to calculate Fibonacci numbers! If you try fib3(1000) it will run infinitely. It's better to start from 0 and 1 upwards, and not use recursion to calculate Fibonacci numbers.

I wrote a short function that calculates Fibonacci number #n for you:

def fib4(n):
    a = 0
    b = 1
    for i in range(1, n + 1):
        a, b = (b, a + b)
    return a

print fib4(0)
print fib4(1)
print fib4(2)
print fib4(3)
print fib4(4)
print fib4(1000)

Notice it also works for n==1000.

Uri
  • 1,974
  • 7
  • 33
  • 63
  • The problem is actually only that for `n = 2` it is `0 and 0 < 2 or fib2(-1) + fib2(-2)`. Since `0` is falseish, `(0 and 0 < 2) == 0` so the result is `0 or fib2(-1) + fib2(-2)`. Since `0` is still falseish, the result is `fib2(-1) + fib2(-2)`. – poke Nov 18 '15 at 13:16
  • @poke Run this program and you will see that `fib2(1)` is True, and so are `fib2(-1)` and `fib2(-2)`. All the other numbers are arbitrary, because they are results of adding True with an integer. They don't make any sense. But of course you can define such a function if it makes sense for you! Or actually, it seems that True is equal to 1 so `fib2(n)` is actually `fib3(n+2)` (because `True + True` is 2 and `True + 2` is 3. – Uri Nov 18 '15 at 13:24
  • Yes, I know, but you can calculate with `True`. It’s `1`! (Know that `bool` is actually a subtype of `int`) And `fib2(1)` should be `1` so it giving `True` is actually an *“acceptable”* result. The real problem is that it breaks for `n = 0` (mistyped that in the comment above) which causes the big problems. If it was working for `0`, you wouldn’t notice the weird result of `True` for `fib2(1)` if you didn’t ask for exactly `fib2(1)`. (btw. this was not criticism of your answer—your answer is just fine—it was just some additional information) – poke Nov 18 '15 at 13:28
  • @poke Yes, I noticed. Please see my updated comment. Only `fib2(1)`, `fib2(-1)` and `fib2(-2)` are defined and `True`, all the other calls call to recursion. So from `n==2` on (not including `n==1`), this is Fibonacci sequence for `n+2`. Anyway, one should never write Python code that adds numbers to Boolean values. – Uri Nov 18 '15 at 13:29
  • I'm sorry, it's a new Fibonacci sequence, starting with 2 and 1. – Uri Nov 18 '15 at 14:18