Odd behavior in Fibonacci series in python 3? - python

This does not print the correct Fibonacci series i.e. 1 1 2 3 5 8...
print ('Fibonacci series...')
a,b = 0,1
while b<50:
print(b)
a = b
b = a + b
Please let me know if there is a better way to do this.

Firstly, there is an indentation error in the first code snippet. The last two lines should be indented so they are executed within the while loop.
print ('Fibonacci series...')
a,b = 0,1
while b<50:
print(b)
a = b
b = a+b
However, this still won't produce the correct result. Let's look at why these two code snippets are different.
a, b = b, a + b: This will assign a to b and b to a + b, with the evaluation of the right-hand side before the left-hand side. This means before looking at what variables to assign new values to, Python will first see what b and a + b are. This means the old value of a will be used for setting b = a + b. You can read more about this here.
a = 1
b = 2
a, b = b, a + b # set a to 2, set b to 1 + 2
print(a) # 2
print(b) # 3
a = b; b = a + b: This does assignment sequentially, such that a is first set to b, then used in the assignment calculation.
a = 1
b = 2
a = b # set a to 2
b = a + b # set b to 2 + 2
print(a) # 2
print(b) # 4

a=b
b = a+b
in the first code sample is equivalent to b = b * 2. Instead you want b += original_value(a). So you either need to do tuple assignment, as in the second code sample (a,b = b, a+b), or use a temp variable:
temp = a
a = b
b += temp
to get the desired value changes.

Related

I am trying to figure out what these temporary variables mean

def genfibon(n): #fib sequence until n
a=1
b=1
for i in range n:
yield a
t=a
a=b
b=t+b
Can someone explain the t variable? It seems like t=a so then a=b and then b=t because a=b and a=t. How does b=t+b?
Let's say a = 2 and b = 3.
t = a # now t = 2
a = b # now a = 3, but t is unchanged
b = t + b # now b = 5
The key is that second part. t = a means t gets the same value as a. It does not mean that t and a are now both the same thing.
You might try this in a Python prompt:
a = 3
b = a
a = 5
print(b) # still 3
It's called swapping of variables. how do you replace the values of variables?
as #smarx said, when a = 2 and b = 3, how do you make it a = 3 and b = 2?
when you do a = 3, the old value of a(2) is lost so you wont know what to set b with. so we store this in a temporary variable(t).
so,
t = a //(saves 2 in t)
a = b //(now both a and b have same values)
b = t //(b gets the old value of a)
// now a = old value of b
// and b = old value of a.
voila, the variables are swapped.
Well, that goes for swapping. which is only partly used in this code. the last statement b = t + b what the code is doing is, adding the old value of a with b(rather than replacing it). why? you get the next number in a fibonacci sequence by adding the previous 2.
2, 3, 5 is a fibonacci sequence since 5 = 2 + 3(given 2 and 3 are seed values). that's exactly what this code is doing.
In your first run
yield a # will return 1
t = a # which is 1
a = b # which is 1
b = t + b # which is 2 as t = 1 and b = 1
In your 2nd run
yield a # will return 1
t = a # which is 1
a = b # which is 2
b = t + b # which is 3 as t = 1 and b = 2
In your 3rd run
yield a # will return 2
t = a # which is 2
a = b # which is 3
b = t + b # which is 5 as t = 2 and b = 3
In your 4th run
yield a # will return 3
t = a # which is 3
a = b # which is 5
b = t + b # which is 8 as t = 3 and b = 5
And so on...
Let us go statement by statement.
t=a means value of a is stored in t.
a=b means value of b is stored in a. (Thus a now contains the next element in the series)
b=t+b means value of b is now t + b which means a+b since t now contains the value of a (According to first step).

Why do these two python functions return different results?

1-
def fib1(n):
a = 0
b = 1
while a < n:
print b
a = b
b = a+b
2-
def fib2(n):
a, b = 0,1
while a < n:
print b
a,b = b, b+a
On execution:
fib1(10) I got the wrong answer: 0 1 2 4 8
fib2(10) I got the right answer: 0 1 1 2 3 5 8
In fib 1
a = b
overwrites the value of a,
which means a is no longer the right value for the statement
b = a+b
However, in your second example both those things happen at the same time on the line a,b = a, b+a which means a is the right value still.
here's a quick answer:
the basic difference is the way the values of a and b are reassigned.
In fib1(), you have
a = b
b = a + b
while in fib2(), you have
a, b = b, b + a
Now, these two looks equal statements but they are not.
Here's why:
In fib2(), you assign the values of the tuple (b, b + a) to the tuple (a, b). Hence, reassignment of values are simultaneous.
However, with fib1(), you first assign value of b to a using a = b and then assign the value a + b to b. Since you have already changed value of a, you are in effect doing
b = a + b = b + b = 2b
In other words, you are doing a, b = b, 2b and that is why you are getting multiples of 2 rather than the fibonacci sequence.
fib1 contains a classic bug. It is in the same realm as that of swapping values of two variables. Think about how you would have done that in C or C++.
int a = 3;
int b = 5;
int temp;
temp = a; /* 3 */
a = b; /* 5 */
b = temp; /* 3, hence swapped */
There is a way to do without temp, although there are intermediate calculations involved. Now in Python, if you are not going to exploit the tuple unpacking feature, you have to involve a temp variable.
a = 3
b = 5
temp = a
a = b
b = temp
OR
a = 3
b = 5
a_ = (a+b)/2 - (a-b)/2 # 5.0
b_ = (a+b)/2 + (a-b)/2 # 3.0
Better use the tuple unpacking as in fib2.

Why One Liner Result Is Different

While working with Fibonacci sequence:
a = 1
b = 3
a, b = b, a + b
print a, b
This properly results to a = 3 and b = 4
Now if I would re-code it as:
a = 1
b = 3
a = b
b = a + b
print a, b
the resulting variable b is 6 instead of 4.
What happens "behind of scenes" when one-liner a, b = b, a + b is used?
This is a combination of tuple packing and sequence unpacking. It is parsed the same way as
(a, b) = (b, a + b)
The tuple on the right side is evaluated before the assignment, which is why the "old" values are used.
You said
b = 3
and then
a = b
and then
b = a + b
which is the same as
b = b + b
or, in other words,
b = 3 + 3,
so b = 6.
The first one is like a, b = 3, 1 + 3 or a, b = 3, 4 so b = 4.
( ) don't make the sequence a tuple, rather ,s do.
a, b = b, a + b # => (a,b) = (a, a+b) if written with brackets
So, it's standard tuple unpacking. But the thing with names a and b on the lest is they are names of different objects now, namely those known as b and result of a+b previously. This behavior is partly due to the fact that variable names in python are names, not boxes,like in C, that store values.

difference between single and multiple assignments

I want to calculate the Fibonacci series in Python 3.5
If I do:
a = 0
b = 1
while b < 100:
print(b)
a, b = b, a + b
I get the right result, but if I do:
a = 0
b = 1
while b < 100:
print(b)
a = b
b = a + b
It simply does not work.
Why is this?
When you do this
a = b
b = a + b
then the assignment to a is executed first, and then the assignment to b, but at this time, a already has a new value. In effect, this is the same as
a = b
b = b + b # now a is the same as b
With the "double assignment", the two variables are updated at the same time
a, b = b, a + b
This assigns the tuple (b, a + b) to the tuple (a, b), using tuple-unpacking to distribute the values to a and b. You could think of this as being roughly equivalent to
temp = b, a + b
a = temp[0]
b = temp[1]
In the first iteration, the value of a changes to 1 which calculates b differently than in the second, where a + b = 2. In the first example, a + b = 1. At least, that's what it looks like to me.
In the first instance, inside the loop during the first run,
a, b = 1, 0+1
Leading a and b to be 1 and 1
In the second instance,
a = 1
b = 1 + 1
Leading a and b to be 1 and 2
The difference is that in the second instance, you're updating the value of b with an already updated value of a. Whereas in the first instance you're updating the value of b using the old value of a.

Why is this Fibonacci sequence not working?

I can't seem to get this to work; can anyone help?
def mystery(n):
a, b = 0, 1
while a < n:
print(a)
a, b = b, a + b
It just comes up blank when I run it.
For this to do anything, you need to call the function, for example
mystery(10)
This prints out
0
1
1
2
3
5
8
def mystery (n):
a, b = 0, 1
while a < n:
print (a)
a, b = b, a + b
mystery (10)
yeah it took me some time but I have figured it out and also how to input a number as well I will give you the answer.
def mystery(n):
a, b = 0, 1
while a < n:
print (a)
a, b = b, a + b
mystery(int(input("Insert A Number: ")))
there you go.

Categories