I am trying to figure out what these temporary variables mean - python

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).

Related

Odd behavior in Fibonacci series in python 3?

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.

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.

How do you read loops?

What is the thought process when evaluating a loop? I really have no idea how the shell gets these answers (A: 12, B: 2, C: 4, D: 6).
A, B, C, D = 0, 0, 0, 0
while A <= 10:
A += 2
if A%3 == 0:
B += 1
else:
C += 1
D += 1
Perhaps you can read it more easily if you break it down:
A = 0
while A <= 10:
A += 2
Can you read this? Do you understand how it gets to 12?
A, D = 0, 0
while A <= 10:
A += 2
D += 1
Also including D should not make it any harder.
Can you read and understand the if-statement by itself?
if A%3 == 0:
B += 1
else:
C += 1
How about when it is inside the loop?
A, B, C, D = 0, 0, 0, 0
while A <= 10:
A += 2
if A%3 == 0:
B += 1
else:
C += 1
D += 1
B and C are related; exactly one of them are incremented in each iteration, so they should add up to the same as D, which they do.
Do you have any specific problems reading and understanding this now? :)
The other answers are good. I would highly recommend going through things with a pen and paper to make sure you understand what's going on.
Using print inside the loop is also useful to see what is going on while your program runs.
A,B,C,D = 0,0,0,0
while A <= 10:
A += 2
if A%3 == 0:
B += 1
else:
C += 1
D += 1
print "A =", A, " B =", B, " C =", C, " D =", D
The output shows you the values of A, B, C, D at the end of every loop iteration.
A = 2 B = 0 C = 1 D = 1
A = 4 B = 0 C = 2 D = 2
A = 6 B = 1 C = 2 D = 3
A = 8 B = 1 C = 3 D = 4
A = 10 B = 1 C = 4 D = 5
A = 12 B = 2 C = 4 D = 6
You can see that:
A gets incremented by 2 every loop iteration
B gets incremented by 1 IF A is divisible by 3, that is A%3 == 0
C gets incremented by 1 IF A is NOT divisible by 3
D gets incremented by 1 every loop iteration
When it comes to loops, you can think of the collection of indented code as a single "chunk" of code that gets executed once for every repetition of the loop. The formal term for this code chunk is a block. It also applies to if/else statements.
The body of the while loop will execute 6 times (for A=0,2,4,6,8,10).
At each iteration, A is incremented by 2, so after the first statement
within the loop it has values 2,4,6,8,10,12.
B is incremented by one twice (when A=6 and A=12);
C is incremented by one for the remaining values of A.
D is incremented every time round the loop.
Hence, after the loop, A=12, B=2, C=4 and D=6.

Categories