# Why won't this code display the fibonacci sequence

This code only displays 5 ones (with calculation limit being 5)

``````
calculationLimit = int(input("Type in limit"))

def fibonacciSequence(current, previous):
next = current + previous
previous = current
current = next
print(next)

for i in range(0, calculationLimit):
fibonacciSequence(1, 0)
i =+ 1

``````

How do I make it display the fibonacci sequence?
Thanks,
zm476

You either need to iterate (for or while loop) or use recursion within your function. The way youâ€™re calling `fibonacciSequence` now, the only arguments it ever sees are zero and one.

Skip has pointed out the core problem with your code (always calling the
function with 0 and 1).

However there are a few other remarks worth making:

`````` def fibonacciSequence(current, previous):
next = current + previous
previous = current
current = next
print(next)
``````

Another thing to note is that variable in functions are local, and
vanish when the function returns. This means that when you update
`previous` and `current` in the middle of this function, those updates
are discarded when the function finishes (because the variables

If this code was inline in the loop body it would be effective, because
youâ€™d be using the same variables throughout.

`````` for i in range(0, calculationLimit):
fibonacciSequence(1, 0)
i =+ 1
``````

The `range()` function returns values for `i` and the for-loop assigns
them to `i`. Thereâ€™s no need to increment `i` at the bottom of the
loop.

Now, in normal code it is very common to break operations out into
functions. But because functions discard their local variables on
return, in order to have those functions change state (eg `current` and
`previous`) the usual thing is to have the function `return` the updated
values. The calling code (your loop body) would pass in the values for
function so that they can be used in the next call.

Cheers,
Cameron Simpson cs@cskk.id.au

Because `fibonacciSequence(1, 0)` means to start over again, using `1` as the value of `current` and `0` as the value of `previous`, no matter what happened any other time that the function was called. Assigning inside the `fibonacciSequence` back to `current` and `previous` doesnâ€™t change anything outside the function. It wouldnâ€™t even if we used variable names for the call - the function only â€śseesâ€ť values, not variables, being passed in.

In order to have an effect outside the function like that, we would need to pass an object that can be modified, and modify it. There is no way to modify an integer - `1` means `1` no matter what math you do, and if you calculate another number, itâ€™s a different object.

To fix the problem, the natural way is to either use the loop inside the function, or else return them for the outside code to use.

As an aside, the code `i =+ 1` doesnâ€™t do what you presumably want, and is also not relevant. There is no `=+` operator; this means the same thing as `i = +1`, which is the same as `i = 1`. But it also doesnâ€™t matter that we change `i` here; the `for` loop will change it back each time. Itâ€™s important to understand that `range` is not part of the `for` loop syntax; it makes an object that actually â€ścontainsâ€ť the values that the loop will use. (But in a special way, that doesnâ€™t need to actually store them all in memory at once.) `for i in` means that `i` will be set to another value from the source, each time through the loop.

It quite normal for neebee to get into troubles. So you should get a little bit debug skill.
The most basic skill is print every thing like this

``````calculationLimit = int(input("Type in limit"))

def fibonacciSequence(current, previous):
next = current + previous
print('next: ', next)
previous = current
print('previous: ', previous)
current = next
print('current: ', current)
print(next)

for i in range(0, calculationLimit):
fibonacciSequence(1, 0)
i =+ 1
print('i: ', i)
``````

And you can see `i =+ 1` not working actually, and the params for function `fibonacciSequence ` not change.

the correct version is below

``````def fibonacciSequence(current_num, previous_num):
next_num = current_num + previous_num
return next_num

previous_num = 0
current_num = 1
for i in range(0, calculationLimit):
next_num = fibonacciSequence(current_num, previous_num)
print('next_num: ', next_num)
previous_num = current_num
current_num = next_num
``````

PS: The reason I change next to next_num is that next is a keyword in python.

You could also slightly simplify such expressions by using formatted strings instead:

``````print(f'{previous= }')
``````

Then you wouldnâ€™t need to repeat the variable names twice (and also could debug arbitrary custom expressions).

Thanks! I donâ€™t know this kind of f-string before.
It seems it works on python3.9 but not on python3.7.
What is the proper name of this kind of f-string?

Self-documenting expressions. They were introduced in 3.8: Whatâ€™s New In Python 3.8 â€” Python 3.12.0 documentation

2 Likes

This can all be simplified a bit by using tuple assignment to avoid temporary variables, as well as a few other tweaks (and using proper Python code style):

``````def fibonacci_sequence(previous, current):
return current + previous

previous, current = 0, 1
for __ in range(calculation_limit):
previous, current = current, fibonacci_sequence(previous, current)
print(current)
``````

Or, if you want `previous` and `current` to be â€śrememberedâ€ť within `fibonacci_sequence`, as your original example seems to expect, make it a generator using the `yield` keyword instead of `return`:

``````def fibonacci_sequence(calculation_limit):
previous, current = 0, 1
for __ in range(calculation_limit):
previous, current = current, current + previous
yield current
``````

Now, you can construct a generator that will iterate over the fibonacci sequence to the limit you set:

``````fibonacci_generator = fibonacci_sequence(calculation_limit)
for n in fibonacci_generator:
print(n)
``````

This works much the same way as before, but the real power of this approach is it allows `fibonacci_sequence` to generate values infinitely, if you remove the limit, while not storing anything but the current and previous value in memoryâ€¦

``````def fibonacci_sequence():
previous, current = 0, 1
while True:
previous, current = current, current + previous
yield current
``````

while being able to be started and stopped as you wish:

``````fibonacci_generator = fibonacci_sequence()
while True:
n = int(input("How many more Fibonacci values to print? "))
for __ in range(n):
print(next(fibonacci_generator))
``````
1 Like

Your code is neat and clean, pretty pythonic!

The reason I avoid to use tuple assignment and generator is that it seems the OP seems fresh to Python, I donâ€™t what to invoke too much knowledge beyond the original post.
As you see, theirâ€™s only functions and variables.

1 Like

Yeah, its smart to limit the concepts to only those required and usually I try to do so; in this case I introduced tuple assignment mostly as a fairly concise, intuitive way to swap two variables, but the generator approach is definitely more advanced then it seems they actually need; I mentioned it more to simply illustrate the point that one can write a function that remembers its state, as they seemed to expect, rather than to suggest they actually use it here.

2 Likes