Python - strategie Jiří Znamenáček Fibonacci numbers 2015-04-30

Print out the first thirteen elements of Fibonacci sequence `1, 1, 2, 3, 5, 8...` .

If you don't know what Fibonacci sequence is consult Wikipedia ^_~ As you can see the n-th element of this sequence is defined by the recurrence relation from the two immediately preceding elements:

` an = an-1 + an-2 `

Therefore before we start computing the sequence we have to know two starting numbers. It's easy in our case – Fibonacci sequence starts with two ones.

So what we know so far?

• We already know the first two elements of the sequence – two ones.
• We know how to compute another element of the seqence from the last two already known.

Therefore let's follow this way of reasoning more:

• We will write a function for computing the next element from the previous two.
• All already computed elements will be stored in a list, which keeps order of its elements.

Let's create a program fragment for the ideas we envisioned:

posloupnost = [1, 1] def ntý_člen(x, y): return x + y

As you can see we have a list (in Python they are denoted with `[]` brackets) with the first two elements of the Fibonacci sequence and we wrote a function (via a keyword `def`) for computing the next element.

Now how to jumpstart the computation? Theoretically the Fibonacci sequence is unlimited. We need just the first thirteen elements but let's create it in this unlimited way via `while` loop:

posloupnost = [1, 1] def ntý_člen(x, y): return x + y while True: nový_člen = ntý_člen( posloupnost[-2], posloupnost[-1] ) posloupnost.append( nový_člen )

Our function is computing the new element from the last two known thanks to the subindexing via `[]` bracket notation with negative indexes for the list. In the next line we are appending the newly computed element to the end of our list via the list method `append()`. Therefore after this line our list will be one more element longer and the the function in the next loop will use this new element (and the previous last one) in the computation.

PS: Since the condition for this `while` loop is always `True`, the program would run out of memory long after the first thirteen elements would have been known already. So we have to break from the loop somehow in the right moment.

Our goal is to get the first thirteen elements of the Fibonacci sequence. Since we have a list to hold all computed values (plus the two starting ones) let's make a test for the right length of this list into the driving condition of the `while` loop:

posloupnost = [1, 1] def ntý_člen(x, y): return x + y while len(posloupnost) < 13: nový_člen = ntý_člen( posloupnost[-2], posloupnost[-1] ) posloupnost.append( nový_člen ) The test "`< 13`" works because:
• We start with the list of length two (those ones) therefore the condition is satisfied and the code inside `while` loop block is run.
• For the list of length twelve the condition still holds therefore the codeblock inside `while` loop will compute another – the thirteenth – element of the sequence. However the next iteration will not occure because now there are precisely thirteen elements in the list and the condition will not hold anymore.

Our program runs, computes the required first thirteen elements of Fibonacci sequence and ends itself after the computation. However there is no output yet. Let's supply it:

posloupnost = [1, 1] def ntý_člen(x, y): return x + y while len(posloupnost) < 13: nový_člen = ntý_člen( posloupnost[-2], posloupnost[-1] ) posloupnost.append( nový_člen ) print(posloupnost)

Now all is nice.

Computing the next element in the Fibonacci sequence is so easy task that there's almost no reason to keep a dedicated function just for this one task (it keeps its name on global name table and has to be look up every time it is called; not counting overhead associated with function definition and calling itself). So let's remove it. Similarly there's no need for our temporary variable holding the last computed element for the same reasons, so let's remove it also:

posloupnost = [1, 1] while len(posloupnost) < 13: posloupnost.append( posloupnost[-2] + posloupnost[-1] ) print(posloupnost)

However we can find a solution in a completely different way:

• Since we know the precise number of element to compute we can use a `for-in` loop for the task.
• There's no reason to keep track of all elements because we don't use them anywhere in the program. Only the last two are important. Instead we can simply print every element directly to the output.
n2, n1 = 0, 1 for i in range(13): print(n1, end=', ') n2, n1 = n1, n2 + n1 You can't use subs in Python (and probably in any other programming language) therefore we used ni for ni.

PS: Think over the "trick" with the starting settings `n-2, n-1 = 0, 1` . (By the way you can learn more about these kinds of multiple assignments in Python via searching for "tuple unpacking".)

The "translation" of the mathematical problem to the programming language was almost straightforward – a function for the recurrence relation and a list for the sequence elements. However:

• We asked for a limited subset of the unlimited sequence and therefore we created the first thirteeen elements and printed them afterwards. (And we did it in a general way at first and in a more condensed one later.)
• In the end we provided yet another solution which had not needed any function and any list to hold all computed elements (since we had no use for them).

Although the first solution (via `while` loop) could be modified to print elements in every step and likewise we could store the computed values in the second one (the one with `for` loop), there are gravely different from the theoretical standpoint. Think over it.