### can follow user steps up until fraction reduction

parent c37c1241
No preview for this file type
 # Equation Tree class # AI Final Project # Takes an equation of the form x + 3 = 5 + x and makes this into an equation tree # this means = is in root and each expression is a tree on either side # currently only works for addition and two variables on each side of equation class EquationTreeNode: def __init__(self, value, parent=None): self.value = value self.left = None self.right = None self.parent = parent def setLeft(self, newNode): self.left = newNode def setRight(self, newNode): self.right = newNode def addLeftNode(self, newNode): self.left = newNode newNode.parent = self def addRightNode(self, newNode): self.right = newNode newNode.parent = self def splitExpression(self, expression): expressions = expression.split("+") leftNode = EquationTreeNode(expressions) rightNode = EquationTreeNode(expressions) self.addLeftNode(leftNode) self.addRightNode(rightNode) '''def main(): equation = "3x+5=2+2x" expressions = equation.split("=") rootNode = EquationTreeNode("=", None) leftNode = EquationTreeNode("+") rootNode.addLeftNode(leftNode) splitExpression(expressions, leftNode) rightNode = EquationTreeNode("+") rootNode.addRightNode(rightNode) splitExpression(expressions, rightNode) print(rootNode.value) print(rootNode.left.value, rootNode.right.value) print(rootNode.left.left.value, rootNode.left.right.value, rootNode.right.left.value, rootNode.right.right.value) main() ''' \ No newline at end of file
 ... ... @@ -28,12 +28,17 @@ class EquationTree: self.inorder(node.right) def evaluate(self, parent, left): # can simplify this to call helper function if left: if parent.left.canEval(): print("parent.left.left is ", parent.left.left.value) print("parent.left.right is ", parent.left.right) if isinstance(parent.left.left, NumNode): print("num node") print("evaluating", parent.left.eval()) newNode = NumNode(parent.left.eval()) else: print("variable node") print("evaluating", parent.left.eval()) newNode = VariableNode(str(parent.left.eval()) + "x") parent.left = newNode ... ... @@ -113,14 +118,20 @@ class PlusNode: self.value = "+" def canEval(self): if isinstance(self.left, VariableNode) == isinstance(self.right,VariableNode): if isinstance(self.left, VariableNode) and isinstance(self.right,VariableNode): return True return False elif isinstance(self.left, NumNode) and isinstance(self.right, NumNode): return True else: return False def getInverse(self): return MinusNode(None,None) def eval(self): #print("left value ", self.left) #print(isinstance(self.left, NumNode)) #print("right value ", self.right.value()) return self.left.eval() + self.right.eval() ... ... @@ -134,9 +145,12 @@ class MinusNode: self.value = "-" def canEval(self): if isinstance(self.left, VariableNode) == isinstance(self.right,VariableNode): if isinstance(self.left, VariableNode) and isinstance(self.right,VariableNode): return True elif isinstance(self.left, NumNode) and isinstance(self.right, NumNode): return True return False else: return False def getInverse(self): return PlusNode(None, None) ... ... @@ -353,6 +367,12 @@ def main(): equationTree.printTree() equationTree.get_expression() ''' print("old node should be 2, is ", oldNum.value) print("moved node should be 7, is ", moveNode.value) print("new op is ", newOp.value) ''' if __name__ == "__main__": main() \ No newline at end of file
 import ccm import re from ccm.lib.actr import * #from expressionTree import EquationTreeNode import tree import queue ... ... @@ -11,27 +10,40 @@ class TutorState: self.expressions = equation.split("=") self.tree = tree.generate_tree(equation) def move_constants_right(self): def move_values(self, left, constants): moveNode = None node = self.tree.root.left newOp = None q = queue.Queue() if left: # if moving values from right to left node = self.tree.root.right q.enqueue(self.tree.root.left) else: # if moving values from left to right node = self.tree.root.left q.enqueue(self.tree.root.right) if constants: # if moving constants nodeType = tree.NumNode emptyNode = tree.VariableNode("0x") else: # if moving variables nodeType = tree.VariableNode emptyNode = tree.NumNode(0) print("node is ", node) if isinstance(node, tree.PlusNode) or isinstance(node, tree.MinusNode): # if plus or minus node if node.canEval() == False: # if can't evaluate children, need to move one newOp = node.getInverse() if isinstance(node.left, tree.NumNode): if isinstance(node.left, nodeType): moveNode = node.left node.left = tree.VariableNode("0x") elif isinstance(node.right,tree.NumNode): node.left = emptyNode elif isinstance(node.right, nodeType): moveNode = node.right node.right = tree.VariableNode("0x") q = queue.Queue() q.enqueue(self.tree.root.right) node.right = emptyNode moved = False while not q.isEmpty() and not moved: currentNode = q.front() print("currentNode is ", currentNode.value) if currentNode.left != None: if isinstance(currentNode.left, tree.NumNode): if isinstance(currentNode.left, nodeType): oldNum = currentNode.left currentNode.left = newOp currentNode.left.left = oldNum ... ... @@ -39,27 +51,43 @@ class TutorState: moved = True q.enqueue(currentNode.left) if currentNode.right != None and not moved: if isinstance(currentNode.right, tree.NumNode): if isinstance(currentNode.right, nodeType): oldNum = currentNode.right currentNode.right = newOp currentNode.right.left = oldNum currentNode.right.right = moveNode moved = True q.enqueue(currentNode.right) if isinstance(currentNode, nodeType) and not moved: oldNum =currentNode print("old node should be 2, is ", oldNum.value) print("moved node should be 7, is ", moveNode.value) print("new op is ", newOp.value) if left: self.tree.root.left = newOp self.tree.root.left.left = oldNum self.tree.root.left.right = moveNode else: self.tree.root.right = newOp self.tree.root.right.left = oldNum self.tree.root.right.right = moveNode moved=True q.dequeue() self.combine_like_terms(True) # will need to change this to just combine variables 4x + 0x # will need to change this to just combine variables 4x + 0x if left: self.combine_like_terms(False) else : self.combine_like_terms(True) return self.tree.get_expression() #self.tree.printTree() #self.tree.get_expression() def combine_like_terms(self, left): self.tree.get_expression() print("COMBINING LIKE TERMS") if left: print("evaluating left side") self.tree.evaluate(self.tree.root, True) else: print("evaluating right side") self.tree.evaluate(self.tree.root, False) self.tree.get_expression() return self.tree.get_expression() class UserState(ccm.Model): #ccm.ProductionSystem ... ... @@ -72,11 +100,6 @@ class UserState(ccm.Model): #ccm.ProductionSystem self.oldEquation = None self.sides = self.getLeftandRightVals() self.constantCount = self.getConstantCount() #self.generate_tree() #self.moveconstants = ["4x=5x+2-7","4x+7-2=5x", "7-2=1x", "-1x+7-2=0"] #self.movevariables = ["7=5x-4x+2", "4x-5x+7=2"] #self.addconstants = ["4x=5x-5","4x+5=5x"] #self.addvariables = ["7=1x+2", "-1x+7=2"] self.state = None self.end = False ... ... @@ -90,13 +113,15 @@ class UserState(ccm.Model): #ccm.ProductionSystem self.sides = self.getLeftandRightVals() oldConstantCount = self.constantCount self.constantCount = self.getConstantCount() #self.state = self.get_state(oldConstantCount) self.state = self.get_state(oldConstantCount) #print("state is ", self.state) return oldConstantCount #return oldConstantCount def getLeftandRightVals(self): expressions = self.equation.split("=") leftVars = None rightVars = None try: leftVars = re.split("[+-]", expressions) rightVars = re.split("[+-]", expressions) ... ... @@ -114,53 +139,57 @@ class UserState(ccm.Model): #ccm.ProductionSystem for value in self.sides: if self.isConstant(value): constantsOnLeft += 1 else: elif 'x' in value: variablesOnLeft += 1 for value in self.sides: if self.isConstant(value): constantsOnRight += 1 else: elif 'x' in value: variablesOnRight += 1 return [variablesOnLeft, constantsOnLeft, variablesOnRight, constantsOnRight] print("There are ", variablesOnLeft, " variables on the left and ", constantsOnLeft, " constants on the left") print("There are ", variablesOnRight, " variables on the right and ", constantsOnRight, " constants on the right") def isConstant(self, value): if 'x' in value: print(value) if not value.isdigit(): return False return True def get_state(self, oldConstantCount): # based on number of variables constants on each side of the equation, the agent guesses which state the user is moving to print("old constant count ", oldConstantCount) print("self.constantcount ", self.constantCount) print("old: ", oldConstantCount) print("new: ", self.constantCount) if oldConstantCount != self.constantCount and oldConstantCount != self.constantCount: # if not same number of variables as before for both sides then moved variables print("variables were moved") self.state = "move_variables" self.state = "move_variables 1" elif oldConstantCount != self.constantCount or oldConstantCount != self.constantCount: print("variables were added") self.state = "add_variables" if oldConstantCount > self.constantCount: self.state = "add_variables 1" else: self.state = "add_variables 0" elif oldConstantCount != self.constantCount and oldConstantCount != self.constantCount: print("constants were moved") self.state = "move_constants" if oldConstantCount < self.constantCount: #moving constants to left self.state = "move_constants 1" else: self.state = "move_constants 0" elif oldConstantCount != self.constantCount or oldConstantCount != self.constantCount: print("constants were added") self.state = "add_constants" if oldConstantCount > self.constantCount: self.state = "add_constants 1" else: self.state = "add_constants 0" else: print("nothing triggered") # need to do this for division and simplifying fraction return self.state def moveConstants(self): '''def moveConstants(self): print("Constants moved to one side of equation") self.state = "move_constants" def moveVariables(self): print("Variables moved to one side of equation") self.state = "move_variables" self.state = "move_variables"''' # dont think i need these functions anymore # look at how to structure UserState () to not run every function ... ... @@ -174,43 +203,41 @@ class IntelligentTutor(ACTR): #tutor.combine_like_terms(True) def init(): cc = user.get_input() user.get_input() print("USER STATE IS ", user.state) # need to get user input to translate to state goal.set(user.get_state(cc)) # goal.set(user.state) #get_state(cc) def moved_constants(goal="move_constants ?left"): #true if moving constants left tutorEq = tutor.move_values(bool(int(left)), True) print("user equation ",user.equation) goal.set("check_state " + tutorEq) def add_constants(goal= "add_constants ?left"): tutorEq = tutor.combine_like_terms(bool(int(left))) print("user equation ",user.equation) goal.set("check_state " + tutorEq) def moved_variables(goal="move_variables ?left"): tutorEq = tutor.move_values(bool(int(left)), False) print("user equation ",user.equation) goal.set("check_state " + tutorEq) def add_variables(goal = "add_variables ?left"): tutorEq = tutor.combine_like_terms(bool(int(left))) print("user equation", user.equation) goal.set("check_state " + tutorEq) def moved_constants(goal="move_constants"): #user="ready:True" tutorEq = tutor.move_constants_right() def check_state(goal = "check_state ?tutorEq"): if tutorEq == user.equation: user.get_input() goal.set(user.state) else: print("INVALID") goal.set("end_process") #if it is invalid then move to invalid state, and return correct state we found in that function #print("constants") #goal.set("add_constants") def add_constants(goal= "add_constants"): # use tree functionality to add constants, pass in expression with two constants to expression tree and solve # generate new correct equation based on this result # check if user input is the same as what we caluclated # if it is correct then user.get_input() goal.set(user.state) # if it is invalid then move to the invalid state def moved_variables(goal="move_variables"): #user.moveVariables() print("variables") goal.set("add_variables") goal.set("invalid_state " + tutorEq) def add_variables(goal = "add_variables"): print("add") goal.set("end_process") def incorrect_state(goal = "invalid state"): print("You have entered an invalid state. We anticipated the correct step to be: \n Please continue solving the problem with the corrected equation above.") def incorrect_state(goal = "invalid_state ?tutorEqn"): print("You have entered an invalid state. We anticipated the correct step to be: ", tutorEqn, "\nPlease continue solving the problem with the corrected equation.") # need to print what correct state would have been user.equation = tutorEqn user.get_input() goal.set(user.state) ... ... @@ -223,8 +250,6 @@ class EmptyEnvironment(ccm.Model): def main(): #eqn = "3x + 4 = 0" env_name = EmptyEnvironment() agent_name = IntelligentTutor() env_name.agent = agent_name ... ...
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment