-3

I wrote a program to find the sum of the first N fibonacci numbers but it returned an UnboundLocalError

def fib_list(x):
 if x == 1:
    li = [1]
 if x == 2:
    li = [1,2]
 else:
    num1 = li[-1]
    num2 = li[-2]
    li = [1,2]
    for n in range(2,x):
     li.append(num1+num2)
 return li

def fib_sum(x):
 sum = 0
 listy = fib_list(x)
 for n in listy:
    sum += n
 return sum

print("You want the sum of how many fib numbers?")
num = int(input())
print(fib_sum(num))
mo.rashadddd
  • 1
  • 1
  • 2
  • write this `li = [1,2]` as first statement is `else` your logic also wrong you not updating `num1` and `num2` – deadshot Sep 12 '20 at 10:14
  • and start values should be `[1, 1`] not `[1, 2]`. you are making simple program very complicated with your incorrect logic – deadshot Sep 12 '20 at 10:16
  • @HeapOverflow this will help https://stackoverflow.com/a/29337929/9050514 – deadshot Sep 12 '20 at 10:25
  • @deadshot thanks for going through my code. Sorry if i wasn't clear earlier. though the num1 and num2 doesn't get updated directly, after each iteration in range(2, x) the list has 1 more item in it(gets appended) and so num1 and num2 gets updated indirectly. The error im getting is UnboundLocalError and I cant find where I got my code wrong. Thanks :) – mo.rashadddd Sep 12 '20 at 10:31
  • see my first comment – deadshot Sep 12 '20 at 10:32
  • @deadshot If you agree with that answer, which says "starting with 0 totally arbitrary. Why not start with -1 and go -1, 1, 0, 1, 1, 2...?", then why did you say "should be [1,1] not [1,2]"? – Kelly Bundy Sep 12 '20 at 10:41
  • @HeapOverflow OP just want to find sum so zero doesn't matter even if we consider – deadshot Sep 12 '20 at 10:42
  • @deadshot It matters because including zero *excludes* another (e.g., sum([0, 1, 1]) vs sum([1, 1, 2]). – Kelly Bundy Sep 12 '20 at 10:43
  • @HeapOverflow it' based on implementation if you consider zero as first number then it differs – deadshot Sep 12 '20 at 10:46

2 Answers2

1

A few issues:

  • The error is caused by num1 = li[-1]: at that time you have not given li a value yet (except in the erroneous case where x is 1).

  • The inner loop does not modify num1 or num2, so you would keep adding the same values. Combined with the first issue, you should move the assignments to num1 and num2 into the loop.

  • The first two Fibonacci numbers are not 1 and 2, but 0 and 1. So initialise with li = [0, 1]. See also In the Fibonacci sequence, is fib(0) 0 or 1 ?

  • When x is 1, the execution also continues into the else block. If you change the second if with elif this will not happen.

  • You should probably also deal with the case when x is 0.

Taking all that together you get:

def fib_list(x):
    if x == 0:
        li = []
    elif x == 1:
        li = [0]
    elif x == 2:
        li = [0,1]
    else:
        li = [0,1]
        for n in range(2,x):
            num1 = li[-1]
            num2 = li[-2]
            li.append(num1+num2)
    return li

It is of course possible to write this more succinctly:

def fib_list(x):
    li = [0,1]
    if x <= 2:
        return li[:x]
    for n in range(x-2):
        li.append(sum(li[-2:]))
    return li

And when you consider that you only need the sum, there is no reason to actually build a list:

def fib_sum(x):
    if x < 2:
        return 0
    a = 0
    b = total = 1
    for n in range(x-2):
        a, b = b, a + b 
        total += b
    return total

The results are as expected:

 x | sum | Fib
---+-----+-----------------
 0 |   0 | []
 1 |   0 | [0]
 2 |   1 | [0,1]
 3 |   2 | [0,1,1]
 4 |   4 | [0,1,1,2]
 5 |   7 | [0,1,1,2,3]
 6 |  12 | [0,1,1,2,3,5]
 7 |  20 | [0,1,1,2,3,5,8]
 8 |  33 | [0,1,1,2,3,5,8,13]
trincot
  • 317,000
  • 35
  • 244
  • 286
1

You could use a generator function for Fibonacci numbers, which for large inputs performs better than appending to a list. The sum function can be easily made using the generator.

def fibonacci(n):
    x, y = 0, 1
    for _ in range(n):
        yield x
        x, y = y, x + y

def fib_sum(n):
    return sum(fibonacci(n))

print("You want the sum of how many fib numbers?")
num = int(input())
print(fib_sum(num))

When run, with an input of 6, this outputs:

You want the sum of how many fib numbers?
6
12
solid.py
  • 2,782
  • 5
  • 23
  • 30
  • As im still learning I havent come across the generator yet, but I will definitely try this method after I learn it. Thanks for your time :) – mo.rashadddd Sep 12 '20 at 18:44