Created
July 25, 2022 22:08
-
-
Save asubramanian08/7b4daa58b039b2eeb84b9f8975de0d07 to your computer and use it in GitHub Desktop.
Evaluate a math expression with order of operations
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" Evaluates a math expression with the correct order of operations. """ | |
def editExpression(inputExpr): | |
""" Edit the math expression by removing spaces and enclosing it in parentheses. """ | |
expression = "(" | |
for ch in inputExpr: | |
if ch != ' ': | |
expression += ch | |
expression += ')' | |
return expression | |
def precedence(operator): | |
""" Return the given operators precedent to ensure the correct order of operations. """ | |
if operator == '(': | |
return 0 | |
elif operator == ')': | |
return 1 | |
elif operator == '+' or operator == '-': | |
return 2 | |
elif (operator == '*' or operator == 'x' or operator == '×') or \ | |
(operator == '/' or operator == '÷') or operator == '%': | |
return 3 | |
elif operator == '^': | |
return 4 | |
else: # not an operator | |
return -1 | |
def getNumber(expression, index): | |
""" Retrive a number from the expression string (and move the index accordingly). """ | |
is_neg = False | |
if expression[index] == '-': | |
is_neg = True | |
index += 1 | |
if expression[index] == '+': | |
index += 1 | |
num = 0 | |
divBy = 0 | |
while index < len(expression): | |
currChar = expression[index] | |
if currChar == '.': | |
# The "divBy *= 10" line must be written after the if block | |
divBy = 0.1 # divBy will be "1" by the end of this iteration | |
elif ord('0') <= ord(currChar) and ord(currChar) <= ord('9'): | |
num = (num * 10) + (ord(currChar) - ord('0')) | |
else: # not part of the number | |
break | |
divBy *= 10 | |
index += 1 | |
if divBy != 0: | |
num /= divBy | |
if is_neg: | |
num *= -1 | |
return num, index | |
def operate(operator, num2, num1): | |
""" Run the operator (operate) on the two given numbers; return the result. """ | |
if operator == '+': | |
return num1 + num2 | |
elif operator == '-': | |
return num1 - num2 | |
elif operator == '*' or operator == 'x' or operator == '×': | |
return num1 * num2 | |
elif operator == '/' or operator == '÷': | |
return num1 / num2 | |
elif operator == '%': | |
return num1 % num2 | |
elif operator == '^': | |
return pow(num1, num2) | |
else: # not an operator | |
return 0 | |
def evaluateExpression(expression): | |
""" Evaluates a given math expression and returns the result """ | |
operators = [] | |
numbers = [] | |
index = 0 | |
was_oper = True | |
while index < len(expression): | |
if was_oper and expression[index] != '(': | |
# read a number (could be negative and/or floating point) | |
num, index = getNumber(expression, index) | |
numbers.append(num) | |
was_oper = False | |
continue | |
prec = precedence(expression[index]) | |
if expression[index] == '(': | |
prec = 10 # ignoring the below while loop | |
while len(operators) > 0 and prec <= precedence(operators[-1]): | |
numbers.append(operate(operators.pop(-1), | |
numbers.pop(-1), numbers.pop(-1))) | |
if expression[index] == ')': | |
operators.pop(-1) # '(' | |
was_oper = False | |
else: # regular operator or '(' | |
operators.append(expression[index]) | |
was_oper = True | |
index += 1 | |
return numbers[0] | |
# Main code: handles the user interactions (input and output) | |
print("Welcome the my math expression calculator!") | |
print("If you want to stop evaluating expression enter \"q\".") | |
expression = editExpression(input("Enter a math expression: ")) | |
while expression != "(q)": # ask for user expressions until quit | |
print("Your expression evaluates to:", evaluateExpression(expression)) | |
expression = editExpression(input("Enter a new math expression: ")) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment