While-loop Python Fibonacci - python

I am new to python and I have really poor expiriences with other codes.
For the most of you a stupid question but somewhere I should start.
def fib(n):
a, b = 0, 1
while a < n:
print(a, end=' ')
a, b = b, a+b
print()
I don't understand why one should enter a, b = b, a+b
I see and understand the result and I can conclude the basic algorithm but I don't get the real understanding of what is happening with this line and why we need it.
Many thanks

This line is executed in the following order:
New tuple is created with first element equal to b and second to a + b
The tuple is unpacked and first element is stored in a and the second one in b
The tricky part is that the right part is executed first and you do not need to use temporary variables.

The reason you need it is because, if you update a with a new value, you won't be able to calculate the new value of b. You could always use temporary variables to keep the old value while you calculate the new values, but this is a very neat way of avoiding that.
It's called sequence unpacking.
In your statement:
a, b = b, a + b
the right side b, a + b creates a tuple:
>>> 8, 5 + 8
(8, 13)
You then assign this to the left side, which is also a tuple a, b.
>>> a, b = 8, 13
>>> a
8
>>> b
13
See the last paragraph the documentation on Tuples and Sequences:
The statement t = 12345, 54321, 'hello!' is an example of tuple packing: the values 12345, 54321 and 'hello!' are packed together in a tuple. The reverse operation is also possible:
>>> x, y, z = t
This is called, appropriately enough, sequence unpacking and works for any sequence on the right-hand side. Sequence unpacking requires the list of variables on the left to have the same number of elements as the length of the sequence. Note that multiple assignment is really just a combination of tuple packing and sequence unpacking.

Related

Re-assigning values to tuple?

Since tuple is a immutable object, following code gives an Error.
tup = (1,2,3)
tup[0] = 3
But the following code runs without an Error
a = 10
b = 20
c = 30
(a,b,c) = (b,c,a)
Why?
What you're doing is tuple assignment. The left hand side is just grouping of variables and would work without the parenthesis too.
It is similar to:
a, b, c = (b, c, a);
Using () doesn't necessarily always mean that it is a tuple. () can also be used for grouping an expression which is the case here.

Variable assignment query in python

I am writing Fibonacci code in python. The below solution is mine.
While the other below solution is from python.org.
Can anyone tell me why it yields a different answer even though the logic of assigning the variables is the same?
Those two programs are not equivalent. The right hand side of the equals (=) is evaluated all together.
Doing:
a=b
b=a+b
Is different from:
a,b = b,a+b
This is in reality the same as:
c = a
a = b
b = b + c
Your example is actually covered on the Python documentation:
The first line contains a multiple assignment: the variables a and b simultaneously get the new values 0 and 1. On the last line this is used again, demonstrating that the expressions on the right-hand side are all evaluated first before any of the assignments take place. The right-hand side expressions are evaluated from the left to the right.
The lines
a = b # Assigns the value of 'b' to 'a'
b = a + b # Adds the new value of 'a' to 'b'
whereas,
a, b = b, a+b Assigns the value of b to a. Adds the existing value of a to b.
The reason it works in the second example is becasue the a=b doesn't evaluate until both are done. So when it gets to the b=a+b part, a is still its previous value. In your first example you are overwriting a before using it. In python when you declare variables in this way you are actually using them as tuples. This means that until the whole line is completed they retain their original values. Once the tuple is unpacked they are overwritten.
I see extra tabs in your solution and also logic of your program is wrong. As far as I understood by writing fib(5) you want 5th fibonacci in the series (which is 5) not a number which is less than 5 (which is 3).
a=b
b=a+b
and
a,b = b,a+b
are not equal.
Look at the code below.
def fibonacci(num):
a,b=0,1;
counter = 2;
while(a<=):
a,b = b,a+b
counter += 1
return b
print fibonacci(5)

Understanding Basic Python Logic and Flow of Operations (a, b = b, a+b)

I am trying to understand the code provided on the Python.org tutorial in section 3.2
a, b = 0, 1
>>> while b < 10:
... print(b)
... a, b = b, a+b
The code above results in the sequence as follows:
1
1
2
3
5
8
My questions are as follows:
Why do the numbers appear vertically and not horizontally like a print statement generally does? I know you can force the numbers to appear horizontally but want to understand why that is not the default.
Most importantly, how is the python logic working? I understand its the fibonacci sequence but you're only asking the code to print "b". It should just print a+b over and over again, should it not (resulting in 1 being printed over and over again)? I don't understand how the logic within python progresses the sequence.
Any help is much appreciated. Thank you.
The python print statement by default generates a newline after each print.
This causes each printed item to appear on its own line. If you print a literal newline, you get two blank lines:
>>> print "\n"
>>>
Most importantly, how is the python logic working? I understand its
the fibonacci sequence but you're only asking the code to print "b".
It should just print a+b over and over again, should it not (resulting
in 1 being printed over and over again)?
This line:
a, b = b, a+b
evaluates the expressions b and a+b. If b=1 and a=0, then this results in the tuple (1, 1). That tuple is then split into its two components and assigned respectively to the variables a and b. So at the end of the first iteration, a and b each get the value 1. This is ultimately equivalent to the successive operations
tmp = b
b = a + b
a = tmp
but notice that here we have to create a temp variable to hold the original value of b. This is because the one-liner evaluates both of the expressions on its right-hand side before it assigns to the variables named on the left-hand side.
First of all your code would be quite simple if you used parentheses. The code a,b is a tupel:
(a,b)=(0,1)
Let's interpret the code line per line:
While b<10: #b=1
print(b) #output:1
(a,b) = (a,a+b) # a=1, b=1
Now the next iteration:
While b<10: #b=1
print(b) #output:1
(a,b) = (a,a+b) # a=1, b=2
And the next:
While b<10: #b=1
print(b) #output:2
(a,b) = (a,a+b) # a=2, b=3
And so on....
You will get
1
1
2
3
5
8
But each number in a separate line because print function add '\n'. So the output is "vertical".

Assigning empty list

I don't really know how I stumbled upon this, and I don't know what to think about it, but apparently [] = [] is a legal operation in python, so is [] = '', but '' = [] is not allowed. It doesn't seem to have any effect though, but I'm wondering: what the hell ?
This is related to Python's multiple assignment (sequence unpacking):
a, b, c = 1, 2, 3
works the same as:
[a, b, c] = 1, 2, 3
Since strings are sequences of characters, you can also do:
a, b, c = "abc" # assign each character to a variable
What you've discovered is the degenerative case: empty sequences on both sides. Syntactically valid because it's a list on the left rather than a tuple. Nice find; never thought to try that before!
Interestingly, if you try that with an empty tuple on the left, Python complains:
() = () # SyntaxError: can't assign to ()
Looks like the Python developers forgot to close a little loophole!
Do some search on packing/unpacking on python and you will find your answer.
This is basically for assigning multiple variables in a single go.
>>> [a,v] = [2,4]
>>> print a
2
>>> print v
4

Python - Assigning 2 variables from one string

values is an array; eventTokens is a string (first element of values). What does the double assignment do? (What are the values of eventToken1 & eventToken2?)
values = data.split("\x01")
eventTokens = values.pop(0)
eventToken1, eventToken2 = eventTokens
I've done an output task (on the Python source) that resulted in the following:
eventTokens is →☹
eventToken1 is →
eventToken2 is ☹
I concluded that the vars somehow split the initial string. However, if I tried compiling an (apparently) similar thing:
arr = ["some", "elements", "inarray"]
c = arr.pop(0)
a, b = c
print c
print a
print b
It resulted in an exception: ValueError: too many values to unpack .
Note: print is not a parameterized method in the tested environment
Variable unpacking is the Python's ability of multiple variable assignment in a single line. The constraint is that the iterable on right side of the expression have to be the same lenght of the variables on the left side. Otherwise you get a too many or to little values to unpack exception.
If you have a string of size 2 like eventTokens is supposed to be, you can then:
>>>a,b = 'ab'
>>>a
'a'
>>>b
'b'
This is very unsafe code. If somehow eventTokens grows larger than two elements the code will raise an exception an your program will be shut down.
Hope this helps!
Since eventTokens is a string of length two, it can be unpacked into two single character strings:
>>> a, b = 'ab'
>>> a
'a'
>>> b
'b'
However, the number of characters in the string must match the number of variables being unpacked into:
>>> a, b = 'abcd'
ValueError: too many values to unpack
Note that you can unpack into one variable!
>>> a, = 'x'
>>> a
'x'
>>> a, = 'xyz'
ValueError: too many values to unpack
c = arr.pop(0) returns "some" here, but you are trying to assign the value to 2 variables in this step (where are there are 4 literals) hence, a, b = c is failing.
Try this instead
arr = ["some", "elements", "inarray"]
c = arr.pop(0)
a, b = arr
print c
print a
print b

Categories

Resources