Created a small utility program to generate JSON files for testing the main input.

This commit is contained in:
2020-04-12 00:03:33 -05:00
parent 4386b1af99
commit 1265f8ac3e
7 changed files with 294 additions and 8 deletions
-1
View File
@@ -55,7 +55,6 @@ class Factor:
print(self.complex_four)
print()
def clear_factors_lists(self):
self.simple_one = []
self.simple_two = []
+17
View File
@@ -0,0 +1,17 @@
{
"expression": "i + 2 + n",
"variables": {
"n1": {
"name": "n1",
"type": "Unknown",
"starting_point": 0,
"ending_point": 0
},
"i1": {
"name": "i1",
"type": "Unknown",
"starting_point": 0,
"ending_point": 0
}
}
}
+27
View File
@@ -0,0 +1,27 @@
class Expression:
expression = ""
variables = []
def __init__(self, expression_string, variables):
self.expression = expression_string
self.variables = variables
class Variable:
VARIABLE_TYPES = {
"i" : "Interest",
"I" : "Interest",
"n" : "Time",
"N" : "Time"
}
def __init__(self, name, type, starting_point = 0, ending_point = 0):
self.name = name
self.type = type
self.starting_point = starting_point
self.ending_point = ending_point
@staticmethod
def get_variable_type(variable_name):
if not variable_name in Variable.VARIABLE_TYPES:
return "Unknown"
return Variable.VARIABLE_TYPES[variable_name]
+96
View File
@@ -0,0 +1,96 @@
import tokenizer
import token
import expression
import json
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".')
def transform(object):
if isinstance(object, expression.Expression) or isinstance(object, expression.Variable):
return object.__dict__
else:
raise TypeError("Only Books and Index will be JSON serialized!")
exp = input("Enter the expression the student will use: ")
tokens = tokenizer.get_tokens_from_expression_string(exp)
for t in 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
with open("data.json", "w", encoding="utf-8") as f:
json.dump(expression.Expression(exp, variables), f, default=transform, indent = 4)
+64
View File
@@ -0,0 +1,64 @@
class CToken:
def __init__(self, value, type):
self.value = value
self.type = type
class TokenType:
add = 0
subtract = 1
multiply = 2
divide = 3
power = 4
variable = 5
constant = 6
exp_start = 7
exp_end = 8
unknown = 9
OPERATOR_VERBS = {
0 : "Adding",
1 : "Subtracting",
2 : "Multiplying",
3 : "Dividing",
4 : "Raising"
}
TOKEN_NAMES = {
0 : "Addition",
1 : "Subtraction",
2 : "Multiplication",
3 : "Division",
4 : "Power",
5 : "Variable",
6 : "Constant",
7 : "Expression Start",
8 : "Expression End",
9 : "Unknown"
}
OPERATORS = {
'+' : add,
'-' : subtract,
'*' : multiply,
'^' : power,
'/' : divide
}
@staticmethod
def get_operator_verb(token):
if not token in TokenType.OPERATOR_VERBS:
raise ValueError("An operator verb could not be found.", "token")
return TokenType.OPERATOR_VERBS[token]
@staticmethod
def get_operator(character):
#
#Accepts an individual character and returns either the math operator TokenType or unknown.
#
if not character in TokenType.OPERATORS:
return TokenType.unknown
return TokenType.OPERATORS[character]
@staticmethod
def get_token_type_name(tokenType):
return TokenType.TOKEN_NAMES[tokenType]
+78
View File
@@ -0,0 +1,78 @@
import token
def get_tokens_from_expression_string(expression_string):
#Takes user input of an actuarial formula and parses the formula to id its components.
#:return: tokens (List of objects of CToken class).
tokens = [] # List of objects of CToken class
tmp = ""
parsing_number = False
symbols_dic = {} # Dictionary to keep track of the no. of times each variable appears.
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 len(tokens) > 1:
lookBehind = tokens[-1]
if lookBehind.type == token.TokenType.exp_end:
tokens.append(token.CToken("^", token.TokenType.power))
if (i + 1) == len(expression_string):
tokens.append(token.CToken(tmp + c, token.TokenType.constant))
parsing_number = True
tmp = tmp + c
continue
elif c == '(':
if parsing_number:
tokens.append(token.CToken(tmp, token.TokenType.constant))
tokens.append(token.CToken("*", token.TokenType.multiply))
tokens.append(token.CToken("(", token.TokenType.exp_start))
parsing_number = False
tmp = ""
continue
elif c == ')':
if parsing_number:
tokens.append(token.CToken(tmp, token.TokenType.constant))
tokens.append(token.CToken(")", token.TokenType.exp_end))
parsing_number = False
tmp = ""
continue
elif token.TokenType.get_operator(c) != token.TokenType.unknown:
if parsing_number:
tokens.append(token.CToken(tmp, token.TokenType.constant))
tokens.append(token.CToken(c, token.TokenType.get_operator(c)))
parsing_number = False
tmp = ""
continue
elif c != ' ':
if len(tokens) > 1:
lookBehind = tokens[-1]
if lookBehind.type == token.TokenType.exp_end:
tokens.append(token.CToken("^", token.TokenType.power))
if (i + 1) < len(expression_string):
lookAHead = expression_string[i + 1]
if lookAHead == '(':
tokens.append(token.CToken(c, token.TokenType.variable))
tokens.append(token.CToken("*", token.TokenType.multiply))
tmp = ""
parsing_number = False
continue
if parsing_number:
tokens.append(token.CToken(tmp, token.TokenType.constant))
tokens.append(token.CToken("*", token.TokenType.multiply))
if c in symbols_dic.keys():
symbols_dic[c] += 1
else:
symbols_dic[c] = 1
tokens.append(token.CToken(c + str(symbols_dic[c]), token.TokenType.variable))
parsing_number = False
tmp = ""
#When building this list we've effectively ordered the tokens in reverse order from how we want to
#process them. So, reverse the order of the list before returning them to the caller, we don't want
#the caller to have to worry about such a minor detail.
tokens.reverse()
return tokens
+12 -7
View File
@@ -1,12 +1,17 @@
import token
import tokenizer
import calc_engine
import json
userInput = input('Enter your formula: ')
tokens = tokenizer.get_tokens_from_expression_string(userInput)
results = calc_engine.calculate_results(tokens)
print(results)
fileLocation = input('File Path to JSON: ')
#json = json.loads(open(fileLocation).read())
#for t in tokens:
# print("%s (%s) " %(t.value, token.TokenType.get_token_type_name(t.type)), end = "")
#print()
#userInput = input('Enter your formula: ')
tokens = tokenizer.get_tokens_from_expression_string("2 + 6 / 2")
#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()