How to write Fibonacci with generator without stop number - python

I went through Beginning Python fibonacci generator
How to write with out stop number where we want to stop.
My Code of FIbnocci is below
def Fibonnaci(n):
if n == 0:
return 0
if n == 1:
return 1
else:
return (Fibonnaci(n-1)+ Fibonnaci(n-2))
n = int(input())
print(Fibonnaci(n))
I wrote with yield statement but its infinite loop running
def fib(n):
a, b = 0, 1
while True:
yield a
a, b = b, a + b
fib(7)
Desired out >
13

You don't want to loop infinitely; you need to keep track of how many times you've performed an operation.
Hold the state of a counter in your loop while you generate elements. Keep going until count >= n.
def fib(n):
count = 0
a, b = 0, 1
while count < n:
yield a
a, b = b, a + b
count += 1
You can then leverage this in a list comprehension to get all of the values up to that Fibonacci number if you so desire.
[i for i in fib(10)]

The yield statement is used to iterate over some data, yielding one value at a time.
So: iterate over it
f = fib()
fibs = [next(f) for _ in range(7)]
fib_7 = fibs[-1]
note as you start with yield a you get a 0 as first number. so shift to yield b which will work as expected

n = int(input())
def fibonacci():
a, b = 0, 1
while True:
yield a
a, b = b, a + b #swap the values, sum
def firstn(g, n):
for i in range(n):
yield g.__next__() # take the next value for the generator
t = (list(firstn(fibonacci(), n+1))) # Put in a list
print (t[-1]) #take the last element

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)

Trying to print the factorial of natural numbers using generators .Getting the output as 1 1 1 1 1 instead of 1 1 2 6 24 120 ......?

def my_gen():
number = 1
fact = 1
fact = fact * number //Trying to calculate factorial
yield fact
number = number + 1
a = my_gen()
print(next(a))
print(next(a))
print(next(a))
print(next(a))
print(next(a))
Trying to print the output for the first five natural numbers.
Expected output: 1 1 2 6 24
obtained output: 1 1 1 1 1
How can i do this??.Any help is appreciated
If you want to write this as a generator, you might want to look up how that works. The generator somehow has to to repeatedly yield a value, your function just provides a single yield, i.e. there is no "next". A fix, working for arbitrarily sized factorials, could involve itertools.count like so:
from itertools import count
def factorial():
res = 1
for x in count(1):
res = x*res
yield res
This starts with the value 1, after each iteration multiplying with the next higher number, and yielding that result.
Should you want to get the first value, 1, twice, then insert another yield res before entering the for-loop.
This may help you to solve your problem.
def my_gen(num):
if num < 0:
return 0
elif num == 0:
return 1
else:
for i in range(1,num + 1):
factorial = factorial*i
return factorial
a = 1
print(my_gen(a))
a = a+1
print(my_gen(a))
a = a+1
print(my_gen(a))
a = a+1
print(my_gen(a))
a = a+1
print(my_gen(a))
Here is the tested code
from itertools import count
def factorial():
res = 1
for x in count(1):
yield res
res = x*res
fs = factorial()
for item in range(10):
print(next(fs))
def factorial(x):
start = 0
fact = 1
while start <= x:
yield fact
start = start + 1
fact = fact * start
fact = factorial(5)
print(next(fact))
print(next(fact))
print(next(fact))
print(next(fact))

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

How is this list index out of range? (Fibonacci numbers exercice)

This code should print the sum of the even numbers in the first ten numbers of the Fibonacci sequence.
#Creates a list with the first ten Fibonacci numbers.
l = [1,2]
for i in range(10):
l.append(l[i]+l[i+1])
for i in l:
#If an element of the Fibonacci list is uneven, replace it with zero.
if l[i]%2 != 0:
l[i] = 0
#Print the sum of the list with all even Fibonacci numbers.
print sum(l)
When I execute this I get:
File "pe2m.py", line 6, in <module>
if l[i]%2 != 0:
IndexError: list index out of range
I don't get how its going out of range, could someone clarify?
Your problem is for i in l: it doesn't give you the indices, it gives you the list elements. As the elements are integers, they could be valid (and the first few will be) but they don't have the values you want -- you'll have to iterate over a range again.
You are looping over the values not the index positions!
Use the following code instead:
#Creates a list with the first ten Fibonacci numbers.
l = [1,2]
for i in range(10):
l.append(l[i]+l[i+1])
for i in range(len(l)):
#If an element of the Fibonacci list is uneven, replace it with zero.
if l[i]%2 != 0:
l[i] = 0
#Print the sum of the list with all even Fibonacci numbers.
print sum(l)
You cannot index a list with the value from the list as it is not guaranteed that the value will be within the list boundary
Seeing your code, I feel you are planning to do something as below
>>> for i,e in enumerate(l):
#If an element of the Fibonacci list is uneven, replace it with zero.
if e%2 != 0:
l[i] = 0
Interestingly you can do the same as below. (Edited after seeing glglgl's comment]
>>> print sum(e for e in l if e%2)
Python's for x in y construct returns the values/elements of a sequence in x, not their index.
As for the Fibonacci numbers: The sequence starts with 1, 1 and not 1, 2. And the sum can be done simpler like this:
a, b = 1, 1
s = 0
for i in range(10):
a, b = b, a+b
if b % 2 = 0:
s += b
print s
If you need to get the sum of the first N even numbers, you would do:
a, b = 1, 1
s = 0
count = 0
while count < 10:
a, b = b, a+b
if b % 2 = 0:
s += b
count += 1
print s
And just for fun the version with generators in a functional style:
from itertools import islice
def fib():
a, b = 1, 1
yield a
yield b
while True:
a, b = b, a+b
yield b
even_sum = reduce(lambda x, y: x+y if y % 2 == 0 else x, islice(fib(), 10), 0)

Python Fibonacci Generator

I need to make a program that asks for the amount of Fibonacci numbers printed and then prints them like 0, 1, 1, 2... but I can't get it to work. My code looks the following:
a = int(raw_input('Give amount: '))
def fib():
a, b = 0, 1
while 1:
yield a
a, b = b, a + b
a = fib()
a.next()
0
for i in range(a):
print a.next(),
I would use this method:
Python 2
a = int(raw_input('Give amount: '))
def fib(n):
a, b = 0, 1
for _ in xrange(n):
yield a
a, b = b, a + b
print list(fib(a))
Python 3
a = int(input('Give amount: '))
def fib(n):
a, b = 0, 1
for _ in range(n):
yield a
a, b = b, a + b
print(list(fib(a)))
You are giving a too many meanings:
a = int(raw_input('Give amount: '))
vs.
a = fib()
You won't run into the problem (as often) if you give your variables more descriptive names (3 different uses of the name a in 10 lines of code!):
amount = int(raw_input('Give amount: '))
and change range(a) to range(amount).
Since you are writing a generator, why not use two yields, to save doing the extra shuffle?
import itertools as it
num_iterations = int(raw_input('How many? '))
def fib():
a,b = 0,1
while True:
yield a
b = a+b
yield b
a = a+b
for x in it.islice(fib(), num_iterations):
print x
.....
Really simple with generator:
def fin(n):
a, b = 0, 1
for i in range(n):
yield a
a, b = b, a + b
ln = int(input('How long? '))
print(list(fin(ln))) # [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ...]
Python is a dynamically typed language. the type of a variable is determined at runtime and it can vary as the execution is in progress.
Here at first, you have declared a to hold an integer type and later you have assigned a function to it and so its type now became a function.
you are trying to apply 'a' as an argument to range() function which expects an int arg but you have in effect provided a function variable as argument.
the corrected code should be
a = int(raw_input('Give amount: '))
def fib():
a, b = 0, 1
while 1:
yield a
a, b = b, a + b
b = fib()
b.next()
for i in range(a):
print b.next(),
this will work
def fibonacci(n):
fn = [0, 1,]
for i in range(2, n):
fn.append(fn[i-1] + fn[i-2])
return fn
To get the fibonacci numbers till any number (100 in this case) with generator, you can do this.
def getFibonacci():
a, b = 0, 1
while True:
yield b
b = a + b
a = b - a
for num in getFibonacci():
if num > 100:
break
print(num)
def genFibanocciSeries():
a=0
b=1
for x in range(1,10):
yield a
a,b = b, a+b
for fib_series in genFibanocciSeries():
print(fib_series)
Your a is a global name so-to-say.
a = int(raw_input('Give amount: '))
Whenever Python sees an a, it thinks you are talking about the above one. Calling it something else (elsewhere or here) should help.
Also you can use enumerate infinite generator:
for i,f in enumerate(fib()):
print i, f
if i>=n: break
Also you can try the closed form solution (no guarantees for very large values of n due to rounding/overflow errors):
root5 = pow(5, 0.5)
ratio = (1 + root5)/2
def fib(n):
return int((pow(ratio, n) - pow(1 - ratio, n))/root5)
You had the right idea and a very elegant solution, all you need to do fix is your swapping and adding statement of a and b. Your yield statement should go after your swap as well
a, b = b, a + b #### should be a,b = a+b,a #####
`###yield a`
Simple way to print Fibonacci series till n number
def Fib(n):
i=a=0
b=1
while i<n:
print (a)
i=i+1
c=a+b
a=b
b=c
Fib(input("Please Enter the number to get fibonacci series of the Number : "))
a = 3 #raw_input
def fib_gen():
a, b = 0, 1
while 1:
yield a
a, b = b, a + b
fs = fib_gen()
next(fs)
for i in range(a):
print (next(fs))
I've build this a while ago:
a = int(raw_input('Give amount: '))
fab = [0, 1, 1]
def fab_gen():
while True:
fab.append(fab[-1] + fab[-2])
yield fab[-4]
fg = fab_gen()
for i in range(a): print(fg.next())
No that fab will grow over time, so it isn't a perfect solution.
It looks like you are using the a twice. Try changing that to a different variable name.
The following seems to be working great for me.
def fib():
a, b = 0, 1
while True:
yield a
a, b = b, a+b
f = fib()
for x in range(100):
print(f.next())
i like this version:
array = [0,1]
for i in range(20):
x = array[0]+array[1]
print(x)
array[0] = array[1]
array[1] = x
Below are two solution for fiboncci generation:
def fib_generator(num):
'''
this will works as generator function and take yield into account.
'''
assert num > 0
a, b = 1, 1
while num > 0:
yield a
a, b = b, a+b
num -= 1
times = int(input('Enter the number for fib generaton: '))
fib_gen = fib_generator(times)
while(times > 0):
print(next(fib_gen))
times = times - 1
def fib_series(num):
'''
it collects entires series and then print it.
'''
assert num > 0
series = []
a, b = 1, 1
while num > 0:
series.append(a)
a, b = b, a+b
num -= 1
print(series)
times = int(input('Enter the number for fib generaton: '))
fib_series(times)
Why do you go for complex here is one of my snippet to work on!!
n = int(input('Enter your number..: '))
a = 0
b = 1
c = 0
print(a)
print(b)
for i in range(3, n+1):
c = a+b
print(c)
a,b=b,c
check out my git - rohith-sreedharan
We can use it in a short way without through 'yield and 'next' statements
def fib(n):
return n if n <= 1 else fib(n - 1) + fib(n - 2)

Categories