views:

206

answers:

8

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 cant 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(),
+15  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).

unutbu
+2  A: 

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.

Ashish
+1  A: 

python is a dynamically typed language. the type of a variable is determined at run time 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 argument to range() function which expects and int arg but you have in effect provided a function variable as argument.

the corrected code shoud 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

appusajeev
A: 

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.

Mzialla
A: 

I would use this method:

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))
rubik
A: 

Also you can use enumerate infinite generator:

for i,f  in enumerate(fib()):
    print i, f
    if i>=n: break
Tony Veijalainen
A: 

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)
Patrick Krecker
A: 

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 = 1,0
    while True:
        yield a
        b = a+b
        yield b
        a = a+b

for x in it.islice(fib(), num_iterations):
    print x
gnibbler