Trouble changing a global variable in a while loop

Viewed 1877

I'm trying to work out the last digit of a bar code however I'm having trouble with the second and last while loops.

They don't assign any new values to the variables total or mOf10. It instead leaves them as 0 and I don't understand why.

while True:

    number = input("Enter a 7 digit number please.")
    if len(number) == 7:
        try:
            number = int(number)
        except ValueError:
            print("Please enter a number")
        else:
            break
    else:
        print("Please enter a valid number.")

print(number) #DELETE THIS BIT LATER!
i = 0
total = 0

while (i < 7 == True):
    global total
    f = str(number)[i]
    if int(f) % 2 == 1:
        total = total + int(f) * 3
    else:
        total = total + int(f)
    i += 1

print(total)

mOf10 = 0

while True:
    global mOf10
    if mOf10 >= total:
        break
    else:
        mOf10 += 10

finalD = mOf10 - total
print(finalD)

It prints out what ever 7 digit number you put in however it doesn't output the total or multiple of 10 as anything. They just come out as 0.

My teachers only solution to this was a lot of if/else statements.

2 Answers

I am not sure what exactly you are trying to do here, but I can tell you what the problem is for which the value of total is not changing. The problem here is in the condition for the while loop. ie, the while (i < 7 == True).

>>> i<7
True 
>>> i<7 == True
False

As you can see, the control never enters the while loop as the condition returns False.

Instead just do while(i<7) . That should solve it.

Note : the use of global in the code is wrong, as the scope of the total and mOf10 are local itself.

Edit : The reason for the odd behaviour is due to comparison operators having the same precedence and due to the chaining of the operators, where in for python something like x < y <= z is equivalent to x < y and y <= z.

According to Python docs :

Formally, if a, b, c, …, y, z are expressions and op1, op2, …, opN are comparison operators, then a op1 b op2 c ... y opN z is equivalent to a op1 b and b op2 c and ... y opN z, except that each expression is evaluated at most once.

We know here :

>>> i < 7
True
>>> 7 == True
False

And due to the chaining of operators the whole condition in turn becomes i < 7 and 7 == True . And since 7==True is False, the condition in the end evaluates to False .

Comparisons are of equal precedence..

a<b<c are evaluated as a<b and b<c

So in your case i<7==True is evaluated as i<7 and 7==True implying either
1. True and False => False OR
2. False and False => False

So it is always False

For reference see... https://docs.python.org/3/reference/expressions.html#comparisons

And please do the needful for the usage of global

Related