Files
calc_engine/main.py
T
lahemals fc7f1e0dbf Dev_Ops
Outputs csv file of calc details.
2020-07-26 01:58:58 -05:00

223 lines
6.5 KiB
Python
Executable File

from base_unit import Token, TokenType
from calc_engine import calculate_results
from expression import Expression, Variable
from tokenizer import get_tokens_from_expression_string, stringify_token_list
import factors
import jsonpickle
import itertools
import copy
from ast_gen import Parser
import random
import csv
base_list = [1, 2, 4, 6, 12]
tolerance = .025
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 = get_tokens_from_expression_string(exp.expression)
tree = 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))
details_lst = [['Ans', 'K', 'I1', 'N1', 'I2', 'Exp', 'Conf']]
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 = 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:
row_list = []
answers[result] = tree.get_tokens()
val_pairs = tree.get_variable_value_pairs()
row_list.append(result)
for key in val_pairs:
row_list.append(val_pairs[key])
row_list.append(stringify_token_list(answers[result]))
row_list.append(random.uniform(0.75, 0.99))
details_lst.append(row_list)
#if result <= tol and result >= int(exp.wrong_response - exp.wrong_response * tolerance):
with open("details.csv", "w", newline="") as f:
writer = csv.writer(f)
writer.writerows(details_lst)
#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(stringify_token_list(answers[k]))