daOnlyBG
daOnlyBG

Reputation: 601

Python: Nesting an "If" statement inside a "while" loop?

I'm new to Python, which is why I'm having trouble on a problem which others might find easy.

Background to this problem: Euler Project, question 2. The problem essentially asks us to add all the even terms in the Fibonacci sequence, so long that each term is under 4,000,000. I decided to do the problem a little differently than what many solutions online show, by calculating the nth Fibonacci term from a closed formula. For now, suppose this function is called Fibonacci(n).

What I'd essentially like to do is loop through an unknown amount of integers that represent the indexes of the Fibonacci set (i.e., 1, 2, 3, 4... etc) and plug each value into Fibonacci(n). If the result has no remainder when divided by 2, then add this Fibonacci number to some value initially set at 0.

Here's what I have so far:

def Fibonacci(n): 
    return (1/(5**0.5))*((((1+5**0.5)/2)**n)-(((1-5**0.5)/2)**n))

i=0
FibSum = 0
nFib = 0

while (nFib <= 10):

    nFib = Fibonacci(i)

    if(nFib%2==0):
        FibSum += nFib

    i += 1

print FibSum

(Yes, as you can see, I'm constraining the Fibonacci sequence to end at 10 as opposed to 4,000,000; this is done merely for testing's sake.)

Now, here's my problem: when I run this code, I get 2.0 instead of 10.0 (2 and 8 are the two Fibonacci numbers that should be added together).

How come? My guess is that the loop stops after it gets to the third Fibonacci number (2) and doesn't continue beyond that. Does anyone see something wrong with my code?

Please comment if you have any further questions. Thanks in advance.

Upvotes: 3

Views: 3231

Answers (3)

Swadhikar
Swadhikar

Reputation: 2210

The problem is with nFib%2==0 comparison. Here you try to compare the float LHS with integer 0. So either modify the if loop as below or modify the return as return int((1/(5**0.5))*((((1+5**0.5)/2)**n)-(((1-5**0.5)/2)**n))).

>>> def Fibonacci(n):
...     return (1/(5**0.5))*((((1+5**0.5)/2)**n)-(((1-5**0.5)/2)**n))
...
>>> i=0
>>> FibSum = 0
>>> nFib = 0
>>> while (nFib <= 10):
...     nFib = Fibonacci(i)
...     if(int(nFib%2)==0):
...             FibSum += nFib
...     i += 1
...
>>> print FibSum
10.0

Upvotes: 2

Muhammad Yaseen Khan
Muhammad Yaseen Khan

Reputation: 809

Solution provided by Gal Dreiman is fine but, conversion with in function is more better, below is your revised code:

def Fibonacci(n):
    return int((1/(5**0.5))*((((1+5**0.5)/2)**n)-(((1-5**0.5)/2)**n)))

Upvotes: 3

Gal Dreiman
Gal Dreiman

Reputation: 4009

You have a floating point problem (which you can read on here)- the returned value 'nFib' is not an integer and not a rounded value. I ran your code and added print for this value in every iteration and got:

0.0
1.0
1.0
2.0
3.0000000000000004
5.000000000000001
8.000000000000002
13.000000000000002

The solution for this is to modify your code as the following:

nFib = int(Fibonacci(i))

After that I got the output: 10

Upvotes: 2

Related Questions