import re from parse import * # List of valid operators opers = ['+', '-', '*', '/'] # Regular expression that checks for valid characters in an expression valid_chars = '[ 0-9.\(\)+-\/*]' def print_error(error_code): # List of error codes: # 1 - Invalid characters found in expression # 2 - Unclosed parantheses match error_code: case 1: print("You have invalid characters in your expression.") case 2: print("You have an unclosed parantheses in your expression.") case 3: print("You have two operators next to each other.") def check_errors(expr): # Check if number of opening parantheses is equal to number of closing parantheses num_open_pars = 0 num_close_pars = 0 for val in expr: if not re.match(valid_chars, val): return 1 num_open_pars = num_open_pars+1 if val == '(' else num_open_pars num_close_pars = num_close_pars+1 if val == ')' else num_close_pars if val in opers: #Check if the next element is an operator. If it is, throw an error continue if num_open_pars != num_close_pars: return 2 return 0 def evaluate(subexpr): # Evaluate a tokenized expression, that contains no parantheses subexpr = [element for element in subexpr if element != ''] # Remove empty characters in the expression print(subexpr) if (len(subexpr) == 1): return float(subexpr[0]) if '/' in subexpr: index = subexpr.index('/') subexpr[index] = float(subexpr[index-1]) / float(subexpr[index+1]) subexpr[index-1] = '' subexpr[index+1] = '' elif '*' in subexpr: index = subexpr.index('*') subexpr[index] = float(subexpr[index-1]) * float(subexpr[index+1]) subexpr[index-1] = '' subexpr[index+1] = '' elif '+' in subexpr: index = subexpr.index('+') subexpr[index] = float(subexpr[index-1]) + float(subexpr[index+1]) subexpr[index-1] = '' subexpr[index+1] = '' elif '-' in subexpr: index = subexpr.index('-') subexpr[index] = float(subexpr[index-1]) - float(subexpr[index+1]) subexpr[index-1] = '' subexpr[index+1] = '' print(subexpr) return evaluate(subexpr) def find_inner(subexpr): print("expr: " + subexpr) subexpr = parse(subexpr) for index,val in enumerate(subexpr): if '(' in val or ')' in val: subexpr[index] = find_inner(val[1:len(val)-1]) subexpr_string = ''.join(subexpr) print("New expr: " + subexpr_string) if not '(' in subexpr_string and not ')' in subexpr_string: return str(evaluate(subexpr)) def main(): while True: expr = input() errno = check_errors(expr) if errno != 0: print_error(errno) continue # If an error was generated, print an error message and continue on to the next iteration of the loop expr = find_inner(expr) print(expr) main()