so I'm currently trying to write a code that basically knows how to deal with mathematical expressions, it has some other little features such as calculating average, getting min number out of 2, getting max number out of 2, etc etc. Issue is, it currently missing the abillity to support parentheses. I need it to deal it even multiple parentheses, or parentheses inside parentheses. How would you suggesting achieving it in a "simple" and easy to understand way?
NOTE: I'm a beginnner, trying to climb my way up :) this is my code:
def parse_expression(expr):
elements = list(expr.replace(" ", ""))
exercise = []
operators = ('+', '-', '*', '/', '$', '&', '@') #### @ = Average, & = Min, $ = Max
i = 0
while i < len(elements):
if elements[i].isdigit() or (elements[i] == '-' and (i == 0 or elements[i - 1] in operators)):
num = elements[i]
while i + 1 < len(elements) and (elements[i + 1].isdigit() or elements[i + 1] == '.'):
i += 1
num += elements[i]
exercise.append(float(num))
elif elements[i] in operators:
exercise.append(elements[i])
i += 1
return exercise
def calculate_result(exercise):
k = 0
while k < len(exercise):
if exercise[k] == '$' or exercise[k] == '&' or exercise[k] == '@':
operator = exercise[k]
left_num = exercise[k - 1]
right_num = exercise[k + 1]
if operator == '$':
result = max(left_num, right_num)
elif operator == '&':
result = min(left_num, right_num)
elif operator == '@':
result = (left_num + right_num) / (2)
exercise[k] = result
exercise.pop(k + 1)
exercise.pop(k - 1)
else:
k += 1
k = 0
while k < len(exercise):
if exercise[k] == '*' or exercise[k] == '/':
operator = exercise[k]
left_num = exercise[k - 1]
right_num = exercise[k + 1]
if operator == '*':
result = left_num * right_num
elif operator == '/':
try:
result = left_num / right_num
except ZeroDivisionError:
print("ERROR: Can't divide by zero. ")
return None
exercise[k] = result
exercise.pop(k + 1)
exercise.pop(k - 1)
k -= 1
k += 1
k = 0
while k < len(exercise):
if exercise[k] == '+' or exercise[k] == '-':
operator = exercise[k]
left_num = exercise[k - 1]
right_num = exercise[k + 1]
if operator == '+':
result = left_num + right_num
elif operator == '-':
result = left_num - right_num
exercise[k] = result
exercise.pop(k + 1)
exercise.pop(k - 1)
else:
k += 1
return round(exercise[0], 2)
while True:
expr = input("calc> ")
if expr in ('EXIT', 'Exit', 'exit'):
print("Bye")
break
exercise = parse_expression(expr)
if len([s for s in exercise if isinstance(s, float)]) == 0:
print("Invalid input.")
else:
result = calculate_result(exercise)
if result is not None:
print(f"{expr} = {result}")
Inside
parse_expression(), whenever you see an opening parenthesis start a new expression, then when you see the closing parenthesis send then send that toparse_expression()expression = '2 + 3 * (4 + 5)'new_expression = '4 + 5'I'm assuming you're doing this for fun because python can interpret math strings with
eval(exp)so
eval('2 + 3 * (4 + 5)')outputs 29, not sure how complex it can parse though.Edit:
For a more advanced approach you can read on Shunting Yard algorithm, a method for parsing arithmetical or logical expressions, or a combination of both, specified in infix notation.