diff --git a/expression.py b/expression.py index 8e04869..42eeafd 100644 --- a/expression.py +++ b/expression.py @@ -40,6 +40,9 @@ class Variable: # Utilitie function to get the variable's type from it's name. # For example, a variable with 'i' in its name is an Interest type. # Returns the variable's type as a string or 'Unknown' otherwise. - if not variable_name in Variable.VARIABLE_TYPES: + if not variable_name[0] in Variable.VARIABLE_TYPES: return "Unknown" - return Variable.VARIABLE_TYPES[variable_name] + return Variable.VARIABLE_TYPES[variable_name[0]] + + def __str__(self): + return "Name: %s Type: %s Start: %f" %(self.name, Variable.get_variable_type(self.name), self.starting_point) diff --git a/main.py b/main.py index 43eeb6b..30e758d 100755 --- a/main.py +++ b/main.py @@ -3,9 +3,10 @@ import tokenizer import expression import calc_engine import factors -#import jsonpickle +import jsonpickle import itertools import copy +import parser base_list = [1, 2, 4, 6, 12] tolerance = .05 @@ -18,11 +19,10 @@ def print_vars(vars): i = 0 for key in vars.keys(): - var = vars[key] if i != 0: - print(", %s" %(var.name), end = "") + print(", %s" %(key), end = "") else: - print("%s " %(var.name), end = "") + print("%s " %(key), end = "") i += 1 print() @@ -77,7 +77,7 @@ def modify_variable(var, vars): 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: ") @@ -103,6 +103,8 @@ except ValueError: 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: @@ -110,6 +112,10 @@ for t in rev_tokens: 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: @@ -123,27 +129,30 @@ if len(variables) > 0: break if response in variables: - selected_variable = variables[response] + modify_variable(variables[response], variables) - if selected_variable != None: - modify_variable(selected_variable, 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.variables +''' +exp = None #fileLocation = input('File Path to JSON: ') -#json = json.loads(open(fileLocation).read()) +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 = json.load(f) -# exp = jsonpickle.decode(f.read()) -# exp.variables +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) @@ -152,7 +161,7 @@ exp = expression.Expression(exp_str, variables, wrong_response) #print() #tokens = tokenizer.get_tokens_from_expression_string(exp.expression) -tokenizer.print_token_list(tokens) +#tokenizer.print_token_list(tokens) factors_list = [] ls = [] answers = {} @@ -169,16 +178,21 @@ for v in exp.variables: ls.append(factor.get_flat_factors_list()) res = list(itertools.product(*ls)) -for r in res: - t = tokenizer.replace_variables(tokens, list(r)) +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(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] = t + 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]) diff --git a/parser.py b/parser.py index 7d09d8f..7498384 100644 --- a/parser.py +++ b/parser.py @@ -34,15 +34,29 @@ class Parser: def __init__(self, tokens): if len(tokens) == 0: raise ValueError("Token list can't be empty") + self.bak = deque() self.variables = {} self.tokens = tokens self.current_token = None self.advance_current_token() self.ast = self.generate_ast() + + + def get_tokens(self): + new_list = [] + + for t in self.bak: + if t.type == token.TokenType.variable: + if t.value in self.variables: + new_list.append(token.Token(self.variables[t.value], token.TokenType.constant)) + else: + new_list.append(token.Token(t.value, t.type)) + return new_list def advance_current_token(self): if len(self.tokens) > 0: + if self.current_token != None: self.bak.append(self.current_token) self.current_token = self.tokens.popleft() def factor(self): diff --git a/ptoken.py b/ptoken.py index d09f963..0fc6364 100755 --- a/ptoken.py +++ b/ptoken.py @@ -5,6 +5,9 @@ class Token: self.value = value self.type = type self.is_negative_variable = is_negative_variable + + def __str__(self): + return "Value: %s" %(self.value) class TokenType: add = 0