0

I'm trying to run this code:

number = input("Number: ")
valid = False
sumOfOdd = 0

def validation(credit_num):
    for i in range(len(credit_num)):
        if i % 2 != 0:
            sumOfOdd += i


def main():
    print(f"Your credit card number is {number}, it's third digit is {number[2]}")
    print(f'sum of odds: {sumOfOdd}')

validation(number)
main()

But I get this error:

Traceback (most recent call last):
  File "credit.py", line 15, in <module>
    validation(number)
  File "credit.py", line 8, in validation
    sumOfOdd += i
UnboundLocalError: local variable 'sumOfOdd' referenced before assignment

I'm able to run, but when I input any number it gives me this error

John Rayburn
  • 176
  • 4
  • 12

2 Answers2

1

This error occurs because the variable sumOfOdd is not accessible from within the function. You could declare the variable global in the function, but you should be careful using the global statement.

In my opinion, a better way to do this is to supply sumOfOdd as an argument to the function and return the updated variable:

def validation(credit_num, sumOfOdd):
    for i in range(len(credit_num)):
        if i % 2 != 0:
            sumOfOdd += i
    return sumOfOdd

validation(number, 0)
# Returns the correct sum.

Or, if you know that the sumOfOdd should always be initialized by zero, you could define the variable locally:

def validation(credit_num):
    sumOfOdd = 0
    for i in range(len(credit_num)):
        if i % 2 != 0:
            sumOfOdd += i
    return sumOfOdd
mabergerx
  • 1,216
  • 7
  • 19
0

Here's a working version of your code.

Note that it now iterates through credit_num as for num in credit_num. If you use for i in range(len(credit_num)) you are iterating through a list of indexes and would need to use if int(credit_num[i]) % 2 != 0, reason being that range(N) returns a list [0, 1, 2... N-1] where for num in credit_num iterates through [1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4] if your input string was 1111222233334444

number = input("Number: ")
valid = False
sumOfOdd = 0

def validation(credit_num):
    global sumOfOdd
    for num in credit_num:
        if int(num) % 2 != 0:
            sumOfOdd += 1


def main():
    print(f"Your credit card number is {number}, it's third digit is {number[2]}")
    print(f'sum of odds: {sumOfOdd}')

validation(number)
main()

Note that validation(number) is called in global scope along with main(), hence the global sumOfOdd declaration inside to allow def validation to gain access to that variable.

A different way to write this code to make it more readable would be:

if __name__ == "__main__":
    number = input("Number: ")
    valid = False
    sumOfOdd = 0
    
    def validation(credit_num):
        sumOfOddToReturn = 0
        for num in credit_num:
            if int(num) % 2 != 0:
                sumOfOddToReturn += 1
        return sumOfOddToReturn
    
    sumOfOdd = validation(number)
    
    print(f"Your credit card number is `{number}`, its third digit is `{number[2]}`.")
    print(f'sum of odds: {sumOfOdd}')
razodactyl
  • 364
  • 4
  • 9