Fibonacci sequence calculator python - python

Hi I'm fairly new to python and trying to create a Fibonacci calculator function that prints all values up to a given number, if the number entered is not in the sequence then it adds the next Fibonacci number to the list. For example, if 10 is entered it should return [0, 1, 1, 2, 3, 5, 8, 13]. The function has to be recursive. Here is my current code:
def fibonacci(n):
n = int(n)
# The nested sub_fib function computes the Fibonacci sequence
def sub_fib(n):
if n < 2:
return n
else:
return (sub_fib(n-1) + sub_fib(n-2))
#This aspect of the main fib function applies the condition if the number
# input is not in the sequence then it returns the next value up
fib_seq= [sub_fib(i) for i in range(0,n) if sub_fib(i)<=n]
if fib_seq[-1] < n:
fib_seq.append(fib_seq[-1] + fib_seq[-2])
return fib_seq
else:
return fib_seq
print(fibonacci(input("Input a number to print sequence up to: ")))
I've managed to get it to work but it is incredibly slow (I assume due to the recursion) is there anyway I can speed it up without massively changing the program?

The two main reasons why your program is slow:
you calculate each Fibonacci number separately, you do not reuse the effort you have invested in finding the previous number;
you calculate the first n Fibonacci numbers, but from the moment the condition fails, you can stop.
You can change the program to still be recursive, but reuse the work to compute the previous number, and stop from the moment you have constructed the list.
You simply have to use the following function:
def fibon(a,b,n,result):
c = a+b
result.append(c)
if c < n:
fibon(b,c,n,result)
return result
and we initialize it with: fibon(0,1,n,[]). In each iteration, it will calculate the next Fibonacci number c = a+b and append it to the result. In case that number is still smaller than c < n then we need to calculate the next number and thus perform the recursive call.
def fibonacci(n):
n = int(n)
def fibon(a,b,n,result):
c = a+b
result.append(c)
if c < n:
fibon(b,c,n,result)
return result
return fibon(0,1,n,[])
print(fibonacci(input("Input a number to print sequence up to: ")))

This uses recursion but much faster than naive recursive implementations
def fib(n):
if n == 1:
return [1]
elif n == 2:
return [1, 1]
else:
sub = fib(n - 1)
return sub + [sub[-1] + sub[-2]]

Here are some examples of how you can improve the speed:
"""
Performance calculation for recursion, memoization, tabulation and generator
fib took: 27.052446
mem_fib took: 0.000134
tabular_fib took: 0.000175
yield_fib took: 0.000033
"""
from timeit import timeit
LOOKUP_SIZE = 100
number = 30
lookup = [None] * LOOKUP_SIZE
def fib(n):
return 1 if n <= 2 else fib(n - 1) + fib(n - 2)
def mem_fib(n):
"""Using memoization."""
if n <= 2:
return 1
if lookup[n] is None:
lookup[n] = mem_fib(n - 1) + mem_fib(n - 2)
return lookup[n]
def tabular_fib(n):
"""Using Tabulation."""
results = [1, 1]
for i in range(2, n):
results.append(results[i - 1] + results[i - 2])
return results[-1]
def yield_fib(n):
"""Using generator."""
a = b = 1
yield a
yield b
while n > 2:
n -= 1
a, b = b, a + b
yield b
for f in [fib, mem_fib, tabular_fib, yield_fib]:
t = timeit(stmt=f"f({number})", number=10, globals=globals())
print(f"{f.__name__} took: {t:.6f}")

Related

program to find fibonacci sequence of a number

how do i find the fibonacci sequence of a number . Here Is The code
def fib(n):
for i in range(n):
b = 1
b+=i
print(b)
p = fib(9)
the program just returns the normal sum. how to do this in the easy way
The fibonacci sequence is built by adding the last two values of the sequence, starting with 1,1 (or 0,1 for the modern version). A recursive function does it elegantly:
def fib(n,a=1,b=1):
return a if n==1 else fib(n-1,b,a+b)
n = 10
a, b = 0, 1
while a <= n:
print(a)
a, b = b, a + b
try this using recursion
def fibonacci(n):
if n <= 0:
return 0
elif n == 1:
return 1
else:
return fibonacci(n-1) + fibonacci(n-2)

Write a program that writes every other of the first 100 Fibonacci numbers.(Python)

I'm pretty new to Python and I'm not even sure where to start. If someone could help, that would be much appreciated :)
Well, I'll just quickly tell you the answer.
# First two numbers of fibonacci sequence
fib = [0, 1]
# Generate the fibonacci sequence
for i in range(98):
# Sum the last two numbers and append it to fib
fib.append(fib[-1] + fib[-2])
# for i in (0, 2, 4, 6...)
for i in range(0, 100, 2):
print fib[i]
The most basic method (though not the most efficient) would be as follows. First define a function that calculates the Fibonacci number at a certain place. There are 2 approaches to this iterative and recursive.
Recursive (example):
def fib(n):
if n < 0:
raise Exception("Invalid Fib Input")
elif n == 0:
return 0
elif n == 1:
return 1
return fib(n - 1) + fib(n - 2)
Iterative (example):
def fib(n):
x = 0
y = 1
z = 1
for i in range(0, n):
x = y;
y = z;
z = x + y;
return x;
Both implementations of the Fibonacci series will work. Now, we can run the following code to print every other Fibonacci number.
for i in range(1, 100, 2):
print(fib(i))
And we are now done. Feel free to ask if you need more clarification. If you want to know how to implement a more efficient solution, look into dynamic programming and storing intermediate values.

Sum of N numbers in Fibonacci

I am trying to implement the total sum of N whole numbers in Fibonacci
def fibo(n):
if n<2:
return 1
else:
res = fibo(n-1) + fibo(n-2)
sum = sum + res
return res, sum
n=7
sum = 0
for i in range(1, n):
print(fibo(i))
print("Suma", sum)
#example: if n=7 then print : 1,1,2,3,5,8,13 and sum is 32
The error I have is, when I put sum = sum + res
Doesnt print & run the program
Currently, how could you implement the total sum?
You simply need to calculate sum in the for loop, not in the fibo(n).
Here take a look:
def fibo(n):
if n<2:
return 1
else:
res = fibo(n-1) + fibo(n-2)
return res
n=7
sum = 0
for i in range(0, n):
r = fibo(i)
sum += r
print(r)
print("Suma", sum)
I used r in order to call fibo once in each loop.
Let me first point out that the sum of the first 7 terms of the Fibonacci sequence is not 32. That sum is 33. Now to the problem. Here is how I would solve the problem. I would first define the function that calculates the n th term of the Fibonacci sequence as follows:
def fibo(n):
if n in [1,2]:
return 1
else:
res = fibo(n-1) + fibo(n-2)
return res
Then I would define a function to calculate the sum of the first n terms of the Fibonacci sequence as follows.
def sum_fibo(n):
res = [fibo(i) for i in range(1, n+1)]
print(res)
return sum(res)
So if I do
[In] sum_fibo(7)
I get
[1, 1, 2, 3, 5, 8, 13]
out >>> 33
NOTE: In defining the functions above, I have assumed that the input of the function is always going to be a positive integer though the Fibonacci can be extended to cover all real and complex numbers as shown on this wiki page.
actually i don't think this needs to be that complicated the fibonacci sequence is very interesting in a maltitude of ways for example, if you want the sum up the 7th fibonacci number, then have checked what the 9th fibonacci number - 1 is? Now how do we find the n'th fibonacci number?
p = (1+5**.5)/2
q = (1-5**.5)/2
def fibo(n):
return 1/5**.5*(p**n-q**n)
and now we can can find the sum up to any number in one calculation! for example for 7
fibo(9)- 1
output
33
and what is the actual answer
1+1+2+3+5+8+13=33
summa summarum: the fibonachi number that is two places further down the sequence minus 1 is the sum of the fibonachi numbers up to the number
def sumOfNFibonacciNumbers(n):
# Write your code here
i = 1
sum = 2
fib_list = [0, 1, 1]
if n == 1:
return 0
if n == 2:
return 1
if n == 3:
return 2
for x in range(1,n-2):
m = fib_list[-1] + fib_list[-2]
fib_list.append(m)
sum = sum + m
return sum
result = sumOfNFibonacciNumbers(10)
print(result)
Made some modifications to your code:
def fibo(n):
print(1)
counter = 1
old_num = 0
new_num = 1
sum_fib = 1
while counter < n:
fib = old_num + new_num
print(fib)
if counter < n:
old_num = new_num
new_num = fib
sum_fib = sum_fib + fib
counter = counter + 1
print('sum:' + str(sum_fib))
#fibo(5)
First of all, the line sum = sum + res makes no sense because you never defined sum in the first place.
So, your function should look like
def fibo(n):
if n<2:
return 1
else:
return fibo(n-1) + fibo(n-2)
Second, you can get the sum by simply
sum_ = 0
for i in range(0, n):
sum_ += fibo(i)
Or maybe
sum_ = sum(fibo(i) for i in range(0, n))
Notice that the latter would only work if you have not overridden the built-in function named sum
You are referring the variable sum before assignment.
You may want to use the variable sum inside the for loop and assign the fibo to it.
def fibo(n):
if n<2:
return 1
else:
return fibo(n-1) + fibo(n-2)
n=7
sum = 0
for i in range(1, n):
sum += fibo(i)
print(fibo(i))
print("suma", sum)
Considering the start of the Fibonacci series with 1 rather than 0.
def fib(no_of_elements):
elements, start = [], 1
while start <= no_of_elements:
if start in [1, 2]:
elements.append(1)
elif start >= 3:
elements.append(elements[start-2]+elements[start-3])
start += 1
return elements, sum(elements)
print(fib(8))
Output:
([1, 1, 2, 3, 5, 8, 13, 21], 54)

Python Pure recursion - Divisor - One input

What is the recursive call (or inductive steps) for a function that returns the number of integers from 1 to N, which evenly divide N. The idea is to concieve a pure recursive code in python for this function. No 'for' or 'while' loops, neither modules can be used. The function num_of_divisors(42) returns 8, representing 1, 2, 3, 6, 7, 14, 21, and 42 as divisors of 42.
def num_of_divisors(n):
return sum(1 if n % i==0 else 0 for i in range(((n+1)**0.5)//1)
Good luck explaining it to your teacher!
If you really can't use for loops (?????????) then this is impossible without simulating one.
def stupid_num_of_divisors_assigned_by_shortsighted_teacher(n, loop_num=1):
"""I had to copy this from Stack Overflow because it's such an
inane restriction it's actually harmful to learning the language
"""
if loop_num <= (n+1) ** 0.5:
if n % loop_num == 0:
return 2 + \
stupid_num_of_divisors_assigned_by_shortsighted_teacher(n, loop_num+1)
else:
return stupid_num_of_divisors_assigned_by_shortsighted_teacher(n, loop_num+1)
else:
if n % loop_num == 0:
return 1
Bonus points: explain why you're adding 2 in the first conditional, but only 1 in the second conditional!
Here you go buddy your teacher'll be happy.
def _num_of_divisors(n, k):
if (k == 0):
return 0
return _num_of_divisors(n, k-1) + (n % k == 0)
def num_of_divisors(n):
return _num_of_divisors(n, n)
It's easier than you think to convert such a simple problem from a loop to a recursive function.
Start with a loop implementation:
n = 42
result = []
for i in range(n+1):
if n % i == 0:
result.append(i)
then write a function
def num_of_divisors_helper(i, n, result):
if <condition when a number should be added to result>:
result.append(n)
# Termination condition
if <when should it stop>:
return
# Recursion
num_of_divisors_helper(i+1, n, result)
Then you define a wrapper function num_of_divisors that calls num_of_divisors_helper. You should be able to fill the gaps in the recursive function and write the wrapper function yourself.
It's a simple, inefficient solution, but it matches your terms.
Without using %
def is_divisible(n, i, k):
if k > n:
return False
if n - i*k == 0:
return True
else:
return is_divisible(n, i, k+1)
def num_of_divisors(n, i=1):
if i > n/2:
return 1
if is_divisible(n, i, 1):
return 1 + num_of_divisors(n, i+1)
else:
return num_of_divisors(n, i+1)
num_of_divisors(42) -> 8
def n_divisors(n,t=1):
return (not n%t)+(n_divisors(n,t+1) if t < n else 0)
good luck on the test later ... better hit those books for real, go to class and take notes...
with just one input i guess
t=0
def n_divisors(n):
global t
t += 1
return (not n%t)+(n_divisors(n) if t < n else 0)

Fibonacci list how do i make a conditional that excludes a number

fib = [0,1]
a = 1
b = 0
i = 0
while i < n:
i = a+b
a,b = i, a
fib.append(i)
This works in cases where 'n' (which is a given variable) is a number in an actual Fibonacci sequence, like 21 or 13. However, if the number is something like six, it adds one more number than it should. The list should not contain a number that is greater than n.
You could always add a to the list first, then do your incrementing.
fib = [0]
a, b = 1, 0
while a <= n:
fib.append(a)
a,b = a+b, a
Using the classic shnazzy recursive Fibonacci function (which took me a few tries to remember and get right):
def fib(num):
if ((num == 0) or (num == 1)): return 1
fib_num = fib(num - 1) + fib(num - 2)
return fib_num
x, n, i = 2, 15, []
while (fib(x) < n):
i.append(fib(x))
x += 1

Categories