From 53f305819439ae3809fdd934bff3f5f6c3fa0fdb Mon Sep 17 00:00:00 2001 From: Garritt McCune Date: Mon, 20 Apr 2020 02:13:01 -0500 Subject: [PATCH] Merged interactive code to the main program for an upcoming demo, will be reverted back after all that. --- calc_engine.py | 12 ++-- json_generator/tokenizer.py | 4 +- main.py | 117 +++++++++++++++++++++++++++++++++--- tokenizer.py | 5 +- 4 files changed, 120 insertions(+), 18 deletions(-) diff --git a/calc_engine.py b/calc_engine.py index 54c4e06..c4c1fba 100644 --- a/calc_engine.py +++ b/calc_engine.py @@ -1,6 +1,8 @@ import ptoken as token import copy +debug = False + def calculate_results(tokens): new_list = copy.deepcopy(tokens) new_list.reverse() @@ -244,19 +246,19 @@ def operate(n1, n2, tokenType): n2 = float(n2) if tokenType == token.TokenType.add: - #print("Adding %d and %d to get %d." %(n1, n2, n1 + n2)) + if debug: print("Adding %d and %d to get %d." %(n1, n2, n1 + n2)) return n1 + n2 elif tokenType == token.TokenType.subtract: - #print("Subtracting %d and %d to get %d." %(n1, n2, n1 - n2)) + if debug: print("Subtracting %d and %d to get %d." %(n1, n2, n1 - n2)) return n1 - n2 elif tokenType == token.TokenType.multiply: - #print("Multiplying %d and %d to get %d" %(n1, n2, n1 * n2)) + if debug: print("Multiplying %d and %d to get %d" %(n1, n2, n1 * n2)) return n1 * n2 elif tokenType == token.TokenType.divide: - #print("Dividing %d and %d to get %d" %(n1, n2, n1 / n2)) + if debug: print("Dividing %d and %d to get %d" %(n1, n2, n1 / n2)) return n1 / n2 elif tokenType == token.TokenType.power: - #print("Raising %d to the power of %d to get %d" %(n1, n2, n1**n2)) + if debug: print("Raising %d to the power of %d to get %d" %(n1, n2, n1**n2)) return n1 ** n2 else: raise TypeError("Invalid operator value " + str(tokenType) + ".", tokenType) diff --git a/json_generator/tokenizer.py b/json_generator/tokenizer.py index 759c7bb..4d1bd14 100644 --- a/json_generator/tokenizer.py +++ b/json_generator/tokenizer.py @@ -13,8 +13,8 @@ def get_tokens_from_expression_string(expression_string): for i in range(0, len(expression_string)): c = expression_string[i] if c == '.' or c.isdigit(): - if tmp.count('.') == 1: - raise SyntaxError("Invalid grammar, to many periods in number. Found at position " + str (i) + ".") + #if tmp.count('.') == 1: + #raise SyntaxError("Invalid grammar, to many periods in number. Found at position " + str (i) + ".") if len(tokens) > 1: lookBehind = tokens[-1] if lookBehind.type == token.TokenType.exp_end: diff --git a/main.py b/main.py index fa55aa4..6f4493b 100755 --- a/main.py +++ b/main.py @@ -5,19 +5,109 @@ import calc_engine import factors import jsonpickle import itertools +import copy base_list = [1, 2, 4, 6, 12] +tolerance = .28 +variables = {} +def print_vars(vars): + i = 0 + for key in vars.keys(): + var = vars[key] + if i != 0: + print(", %s" %(var.name), end = "") + else: + print("%s " %(var.name), end = "") + i += 1 + print() + +def modify_variable(var, vars): + print("%s is now selected." %(var.name)) + print("The following properties are avaliable: Variable Type, Starting Point and Ending Point.") + print('Commands are "type", "start" and "end", respectly.') + + while True: + response = input("Select a property to modify for %s or q to exit property modifying: " %(var.name)) + + if response == "type": + response = input("Enter the type of variable this is (currently %s): " %(expression.Variable.get_variable_type(var.type))) + vars[var.name].type = response + print("Updated to %s." %(response)) + + elif response == "start": + response = input("Enter the variable's starting point (currently %f): " %(var.starting_point)) + + try: + vars[var.name].starting_point = float(response) + print("Updated to %f." %(float(response))) + except ValueError: + print("The starting point must be a number.") + + elif response == "end": + response = input("Enter the variable's ending point (currently %f): " %(var.ending_point)) + + try: + vars[var.name].ending_point = float(response) + print("Updated to %f." %(float(response))) + except ValueError: + print("The ending point must be a number.") + + pass + + elif response == "q": + return + + else: + print('Invalid property "%s".' %(response)) + print('Commands are "type", "start" and "end".') + +exp_str = input("Enter the expression the student will use: ") +wrong_response = input("Enter the wrong response for the expression: ") +try: + wrong_response = float(wrong_response) +except ValueError: + print("The anwser must be numeric! Will not be included in output file.") +tokens = tokenizer.get_tokens_from_expression_string(exp_str) +rev_tokens = copy.deepcopy(tokens) +#rev_tokens.reverse() + +for t in rev_tokens: + if t.type == token.TokenType.variable: + variables[t.value] = expression.Variable(t.value, expression.Variable.get_variable_type(t.value)) + +selected_variable = None + +while True: + print("Variables in expression:") + print_vars(variables) + response = input("Enter a variable name to modify its properties or continue (default): ") + + if response == "continue" or response == "": + break + + if response in variables: + selected_variable = variables[response] + + if selected_variable != None: + modify_variable(selected_variable, variables) + + else: + print("Invalid selection %s." %(response)) + continue + +exp = expression.Expression(exp_str, variables, wrong_response) +#exp.variables #fileLocation = input('File Path to JSON: ') #json = json.loads(open(fileLocation).read()) #userInput = input('Enter your formula: ') #tokens = tokenizer.get_tokens_from_expression_string("5000(2(2(1.08^10)-1)/0.08)") -with open("expression.json", "r") as f: - #j = json.load(f) - exp = jsonpickle.decode(f.read()) - exp.variables +#with open("expression.json", "r") as f: +# #j = json.load(f) +# exp = jsonpickle.decode(f.read()) +# exp.variables #results = calc_engine.calculate_results(tokens.copy()) #print(results) @@ -25,10 +115,11 @@ with open("expression.json", "r") as f: # print("%s (%s) " %(t.value, token.TokenType.get_token_type_name(t.type)), end = "") #print() -tokens = tokenizer.get_tokens_from_expression_string(exp.expression) +#tokens = tokenizer.get_tokens_from_expression_string(exp.expression) tokenizer.print_token_list(tokens) factors_list = [] ls = [] +answers = {} for v in exp.variables: factor = factors.Factor(v, base_list) @@ -46,7 +137,15 @@ for r in res: t = tokenizer.replace_variables(tokens, list(r)) #tokenizer.print_token_list(t) result = calc_engine.calculate_results(t) - tol = (exp.wrong_response * .01 + exp.wrong_response) - if result <= tol and result >= (exp.wrong_response - exp.wrong_response * .01): - print("Result: %s for expression: " %(format(result, ".8f"))) - tokenizer.print_token_list(t) + tol = int(exp.wrong_response * tolerance + exp.wrong_response) + if result <= tol and result >= int(exp.wrong_response - exp.wrong_response * tolerance): + if not result in answers: + answers[result] = t + #if result <= tol and result >= int(exp.wrong_response - exp.wrong_response * tolerance): + + +for k in answers: + print("Result: %s for expression: " %(format(k, ".8f"))) + tokenizer.print_token_list(answers[k]) + + diff --git a/tokenizer.py b/tokenizer.py index 8183409..92fe785 100644 --- a/tokenizer.py +++ b/tokenizer.py @@ -50,7 +50,8 @@ def get_tokens_from_expression_string(expression_string): if len(tokens) > 1: lookBehind = tokens[-1] if lookBehind.type == token.TokenType.exp_end: - tokens.append(token.Token("^", token.TokenType.power)) + tokens.append(token.Token("^", token.TokenType.power)) + if (i + 1) < len(expression_string): lookAHead = expression_string[i + 1] if lookAHead == '(': @@ -85,5 +86,5 @@ def replace_variables(tokens, new_constants): def print_token_list(tokens): for tk in tokens: - print(tk.value, end = "") + print("%s" %(tk.value), end = "")#, token.TokenType.get_token_type_name(tk.type)), end = "") print()