import ptoken as token import tokenizer import expression import calc_engine import factors import jsonpickle import itertools import copy import parser base_list = [1, 2, 4, 6, 12] tolerance = .05 variables = {} var_types = {} def print_vars(vars): # Utility function to print out the variables list to standard out. i = 0 for key in vars.keys(): if i != 0: print(", %s" %(key), end = "") else: print("%s " %(key), end = "") i += 1 print() def modify_variable(var, vars): # Acts as an interactive prompt that allows the user to modify any one variable that has been found in the formula string. 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) or c to cancel: " %(var.type)) if response == "c" or response == "C": continue vars[var.name].type = response print("Updated to %s." %(response)) elif response == "start": response = input("Enter the variable's starting point (currently %f) or c to cancel: " %(var.starting_point)) if response == "c" or response == "C": continue 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) or c to cancel: " %(var.ending_point)) if response == "c" or response == "C": continue 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: ") interest = input("Enter the default starting point for Interest variables: ") time = input("Enter the default starting point for Time variables: ") installment = input("Enter the default starting point for the Installment variables: ") var_types["Interest"] = float(interest) var_types["Time"] = float(time) var_types["Installment"] = float(installment) try: wrong_response = float(wrong_response) except ValueError: print("The wrong response must be numeric.") exit() tolerance = input("Enter the tolerance to use: ") try: tolerance = float(tolerance) except ValueError: print("The tolerance must be numeric.") exit() tokens = tokenizer.get_tokens_from_expression_string(exp_str) tree = parser.Parser(tokens) variables = tree.get_variable_value_pairs() rev_tokens = copy.deepcopy(tokens) 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[0])) variables[t.value].starting_point = var_types[expression.Variable.get_variable_type(t.value[0])] for key in variables: variables[key] = expression.Variable(key, expression.Variable.get_variable_type(key)) selected_variable = None if len(variables) > 0: 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: modify_variable(variables[response], variables) #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 = None #fileLocation = input('File Path to JSON: ') fileLocation = "expression.json" json = jsonpickle.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 = jsonpickle.json.load(f) exp = jsonpickle.decode(f.read()) tokens = tokenizer.get_tokens_from_expression_string(exp.expression) tree = parser.Parser(tokens) #results = calc_engine.calculate_results(tokens.copy()) #print(results) #for t in tokens: # print("%s (%s) " %(t.value, token.TokenType.get_token_type_name(t.type)), end = "") #print() #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) if exp.variables[v].type == "Interest": factor.calculate_factors(exp.variables[v].starting_point, True, True) else: factor.calculate_factors(exp.variables[v].starting_point) factors_list.append(factor) ls.append(factor.get_flat_factors_list()) res = list(itertools.product(*ls)) for r in res: vs = tree.get_variable_value_pairs() count = 0 for key in vs: vs[key] = r[count] count +=1 t = tree.update_variables(vs)#tokenizer.replace_variables(tokens, list(r)) #tokenizer.print_token_list(t) result = calc_engine.calculate_results(tree.ast) if result <= int(exp.wrong_response * (1 + tolerance)) and result >= int(exp.wrong_response * (1 - tolerance)): if not result in answers: answers[result] = tree.get_tokens() #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]) with open("results.txt", "w") as f: print("Answers Found: %d" %(len(answers))) for k in answers: f.write("Result: %s for expression: " %(format(k, ".6f"))) f.write(tokenizer.stringify_token_list(answers[k]))