commit 0a2681233c1d7ae87d140ba351d06b9468b24ecc Author: Aadhavan Srinivasan Date: Sun Nov 26 10:50:25 2023 -0500 First commit diff --git a/calculator.py b/calculator.py new file mode 100644 index 0000000..c84afea --- /dev/null +++ b/calculator.py @@ -0,0 +1,91 @@ +import re +from parse import * + +# Regular expression that checks for valid characters in an expression +valid_chars = '[0-9.\(\)+-\/*]' + +def raise_error(error_code): + + # List of error codes: + # 0 - Invalid characters found in expression + # 1 - Unclosed parantheses + + match error_code: + case 0: + print("You have invalid characters in your expression.") + case 1: + print("You have an unclosed parantheses in your expression.") + + main() # Re-enter main loop + +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: + num_open_pars += 1 if val == '(' + num_close_pars += 1 if val == ')' + if num_open_pars != num_close_pars: + raise_error(2) + + + +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() + check_for_errors(expr) + expr = find_inner(expr) + print(expr) + +main() diff --git a/parse.py b/parse.py new file mode 100644 index 0000000..3ca6e30 --- /dev/null +++ b/parse.py @@ -0,0 +1,38 @@ +def parse(expr): + + opers = ['+', '-', '*', '/'] + + num_par = 0 + tokenized = [] + temp_string = "" + index = 0 + while index < len(expr): + if expr[index] in opers: + tokenized.append(expr[index]) + + elif expr[index].isdigit() or expr[index] == '.': + while (index < len(expr)) and (expr[index].isdigit() or expr[index] == '.'): + temp_string += expr[index] + index += 1 + tokenized.append(temp_string) + temp_string = "" + + elif expr[index] == '(': + num_par = 1 + temp_string += expr[index] + index += 1 + while num_par != 0 and index < len(expr): + temp_string += expr[index] + if expr[index] == '(': + num_par += 1 + if expr[index] == ')': + num_par -= 1 + index += 1 + + tokenized.append(temp_string) + temp_string = "" + + + index += 1 + + return tokenized