'Why I cannot change index inside the while loop?

I want to implement basic calculator only includes numbers, '+' and '-' in Python. But I found that I cannot change index i inside the while loop.

def basicCalculator(expression):
    res = 0
    sign = 1
    i = 0
    while i < len(expression): # using while loop here
        if expression[i] == '+':
            sign = 1
        elif expression[i] == '-':
            sign = -1
        elif '0' <= expression[i] <= '9':
            temp = int(expression[i])
            while i + 1 < len(expression) and '0' <= expression[i + 1] <= '9':
                i += 1             # want to increase i, but failed
                temp = temp * 10 + int(expression[i])
            res += sign * temp
    return res

s = "2+3-999"
print(basicCalculator(s))    # ouput should be -994, but infinite

Then I tried another way: using for loop instead of while loop, get incorrect answer.

def basicCalculator(expression):
    res = 0
    sign = 1
    for i in range(len(expression)):  # using for loop
        if expression[i] == '+':
            sign = 1
        elif expression[i] == '-':
            sign = -1
        elif '0' <= expression[i] <= '9':
            temp = int(expression[i])
            while i + 1 < len(expression) and '0' <= expression[i + 1] <= '9':
                i += 1                    # increase i
                temp = temp * 10 + int(expression[i])
            res += sign * temp
    return res

s = "2+3-999"
print(basicCalculator(s))    # ouput should be -994, but got -1102

I don't know why I cannot change the index inside the while loop or for loop. It is not a good idea to change i in for loop. What is the best way to fix the bug? (I wrote the same code in Java using approach 2, everything is good, any difference?)



Solution 1:[1]

Rather than incrementing the index in a loop within the loop, I suggest just accumulating the current number in the main loop so you have less to keep track of:

def basicCalculator(expression):
    res = 0
    sign = 1
    num = ""
    for c in expression:
        if c.isdecimal():
            num += c
            continue
        res += int(num) * sign
        num = ""
        if c == "+":
            sign = 1
        elif c == "-":
            sign = -1
        else:
            raise ValueError(f"Invalid operator {c}")
    return res + int(num) * sign

print(basicCalculator("2+3-999"))  # -994

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Samwise