def equationAnimationBuilder(lTokens, rTokens): """Given LHS & RHS tokens for an equation it builds the tokens of complete equation Arguments: lTokens {list} -- Tokens of LHS rTokens {list} -- Tokens of RHS Returns: animBulder {list} -- list of tokens of complete equation """ animBuilder = [] lToks = copy.deepcopy(lTokens) rToks = copy.deepcopy(rTokens) animBuilder = lToks lenToks = len(lToks) equalTo = Binary() equalTo.scope = [lenToks] equalTo.value = '=' animBuilder.append(equalTo) if len(rToks) == 0: zero = Zero() zero.scope = [lenToks + 1] animBuilder.append(zero) else: animBuilder.extend(rToks) return animBuilder
def moveRTokensToLTokens(lTokens, rTokens): """Moves tokens in RHS to LHS Arguments: ltokens {list} -- LHS tokens list rtokens {list} -- RHS tokens list Returns: ltokens {list} -- LHS tokens list rtokens {list} -- RHS tokens list """ if len(lTokens) == 0 and len(rTokens) > 0: return rTokens, lTokens elif isEquation(lTokens, rTokens): return lTokens, rTokens elif len(lTokens) != 0: for i, token in enumerate(rTokens): if i == 0 and not isinstance(token, Binary): binary = Binary() binary.value = '-' binary.scope = copy.copy(token.scope) binary.scope[-1] -= 1 lTokens.append(binary) if isinstance(token, Binary): if token.value in ['+', '-']: if token.value == '-': token.value = '+' else: token.value = '-' elif isinstance(token, Constant): if token.value < 0: if isinstance(lTokens[-1], Binary): if lTokens[-1].value == '-': token.value *= -1 lTokens[-1].value = '+' elif lTokens[-1].value == '+': token.value *= -1 lTokens[-1].value = '-' elif isinstance(token, Variable): if token.coefficient < 0: if isinstance(lTokens[-1], Binary): if lTokens[-1].value == '-': token.coefficient *= -1 lTokens[-1].value = '+' elif lTokens[-1].value == '+': token.coefficient *= -1 lTokens[-1].value = '-' lTokens.append(token) rTokens = [] return lTokens, rTokens
def divisionEquation(lToks, rToks, direct=False): lTokens = copy.deepcopy(lToks) rTokens = copy.deepcopy(rToks) animation = [] comments = [] if direct: comments = [[]] animBuilder = lToks lenToks = len(lToks) equalTo = Binary() equalTo.scope = [lenToks] equalTo.value = '=' animBuilder.append(equalTo) if len(rToks) == 0: zero = Zero() zero.scope = [lenToks + 1] animBuilder.append(zero) else: animBuilder.extend(rToks) animation.append(copy.deepcopy(animBuilder)) lVariables = [] lVariables.extend(getLevelVariables(lTokens)) rVariables = [] rVariables.extend(getLevelVariables(rTokens)) availableOperations = getOperationsExpression(lVariables, lTokens) while '/' in availableOperations: _, tok, rem, com = expressionDivision(lVariables, lTokens) lTokens = removeToken(tok, rem) comments.append(com) animBuilder = copy.deepcopy(lTokens) lenToks = len(lTokens) equalTo = Binary() equalTo.scope = [lenToks] equalTo.value = '=' animBuilder.append(equalTo) if len(rTokens) == 0: zero = Zero() zero.scope = [lenToks + 1] animBuilder.append(zero) else: animBuilder.extend(rTokens) animation.append(copy.deepcopy(animBuilder)) lVariables = getLevelVariables(lTokens) availableOperations = getOperationsExpression(lVariables, lTokens) availableOperations = getOperationsExpression(rVariables, rTokens) while '/' in availableOperations: _, tok, rem, com = expressionDivision(rVariables, rTokens) rTokens = removeToken(tok, rem) comments.append(com) animBuilder = copy.deepcopy(lTokens) lenToks = len(lTokens) equalTo = Binary() equalTo.scope = [lenToks] equalTo.value = '=' animBuilder.append(equalTo) if len(rTokens) == 0: zero = Zero() zero.scope = [lenToks + 1] animBuilder.append(zero) else: animBuilder.extend(rTokens) animation.append(copy.deepcopy(animBuilder)) rVariables = getLevelVariables(rTokens) availableOperations = getOperationsExpression(rVariables, rTokens) tokenToStringBuilder = copy.deepcopy(lTokens) lenToks = len(lTokens) equalTo = Binary() equalTo.scope = [lenToks] equalTo.value = '=' tokenToStringBuilder.append(equalTo) if len(rTokens) == 0: zero = Zero() zero.scope = [lenToks + 1] tokenToStringBuilder.append(zero) else: tokenToStringBuilder.extend(rTokens) token_string = tokensToString(tokenToStringBuilder) lVariables = getLevelVariables(lTokens) rVariables = getLevelVariables(rTokens) availableOperations = getOperationsEquation( lVariables, lTokens, rVariables, rTokens) return lTokens, rTokens, availableOperations, token_string, animation, comments
def simplifyEquation(lToks, rToks): """Simplifies given equation tokens Arguments: lToks {list} -- LHS tokens list rToks {list} -- RHS tokens list Returns: lTokens {list} -- LHS tokens list rTokens {list} -- RHS tokens list availableOperations {list} -- list of operations token_string {string} -- simplified result in string animation {list} -- list of equation simplification progress comments {list} -- list of solution steps """ lTokens = copy.deepcopy(lToks) rTokens = copy.deepcopy(rToks) animation = [] comments = [[]] lVariables = [] lVariables.extend(getLevelVariables(lTokens)) rVariables = [] rVariables.extend(getLevelVariables(rTokens)) animBuilder = lToks lenToks = len(lToks) equalTo = Binary() equalTo.scope = [lenToks] equalTo.value = '=' animBuilder.append(equalTo) if len(rToks) == 0: zero = Zero() zero.scope = [lenToks + 1] animBuilder.append(zero) else: animBuilder.extend(rToks) animation.append(copy.deepcopy(animBuilder)) availableOperations = getOperationsEquation(lVariables, lTokens, rVariables, rTokens) while len(availableOperations) > 0: if '/' in availableOperations: lTokens, rTokens, availableOperations, token_string, anim, com = divisionEquation( lTokens, rTokens) animation.pop(len(animation) - 1) animation.extend(anim) comments.extend(com) elif '*' in availableOperations: lTokens, rTokens, availableOperations, token_string, anim, com = multiplicationEquation( lTokens, rTokens) animation.pop(len(animation) - 1) animation.extend(anim) comments.extend(com) elif '+' in availableOperations: lTokens, rTokens, availableOperations, token_string, anim, com = additionEquation( lTokens, rTokens) animation.pop(len(animation) - 1) animation.extend(anim) comments.extend(com) elif '-' in availableOperations: lTokens, rTokens, availableOperations, token_string, anim, com = subtractionEquation( lTokens, rTokens) animation.pop(len(animation) - 1) animation.extend(anim) comments.extend(com) lVariables = getLevelVariables(lTokens) rVariables = getLevelVariables(rTokens) availableOperations = getOperationsEquation(lVariables, lTokens, rVariables, rTokens) moved = False if len(rTokens) > 0: moved = True lTokens, rTokens = moveRTokensToLTokens(lTokens, rTokens) tokenToStringBuilder = copy.deepcopy(lTokens) lenToks = len(lTokens) equalTo = Binary() equalTo.scope = [lenToks] equalTo.value = '=' tokenToStringBuilder.append(equalTo) if len(rTokens) == 0: zero = Zero() zero.scope = [lenToks + 1] tokenToStringBuilder.append(zero) else: tokenToStringBuilder.extend(rTokens) if moved: animation.append(copy.deepcopy(tokenToStringBuilder)) comments.append(['Moving the rest of variables/constants to LHS']) token_string = tokensToString(tokenToStringBuilder) return lTokens, rTokens, availableOperations, token_string, animation, comments
def divisionEquation(lToks, rToks, direct=False): """Function deals with division related operations FOR EQUATIONS (driver function in division module) Arguments: rtoks {list} -- list of right tokens ltoks {list} -- list of left tokens direct {bool} -- True when we are only concerned about multiplications terms in the input Returns: availableOperations {list} -- list of operations which can be performed on a equation token token_string {string} -- final result stored in a string animation {list} -- list of equation solving process comments {list} -- list of comments in equation solving process """ lTokens = copy.deepcopy(lToks) rTokens = copy.deepcopy(rToks) animation = [] comments = [] if direct: comments = [[]] animBuilder = lToks lenToks = len(lToks) equalTo = Binary() equalTo.scope = [lenToks] equalTo.value = '=' animBuilder.append(equalTo) if len(rToks) == 0: zero = Zero() zero.scope = [lenToks + 1] animBuilder.append(zero) else: animBuilder.extend(rToks) animation.append(copy.deepcopy(animBuilder)) lVariables = [] lVariables.extend(getLevelVariables(lTokens)) rVariables = [] rVariables.extend(getLevelVariables(rTokens)) availableOperations = getOperationsExpression(lVariables, lTokens) while '/' in availableOperations: _, tok, rem, com = expressionDivision(lVariables, lTokens) lTokens = removeToken(tok, rem) comments.append(com) animBuilder = copy.deepcopy(lTokens) lenToks = len(lTokens) equalTo = Binary() equalTo.scope = [lenToks] equalTo.value = '=' animBuilder.append(equalTo) if len(rTokens) == 0: zero = Zero() zero.scope = [lenToks + 1] animBuilder.append(zero) else: animBuilder.extend(rTokens) animation.append(copy.deepcopy(animBuilder)) lVariables = getLevelVariables(lTokens) availableOperations = getOperationsExpression(lVariables, lTokens) availableOperations = getOperationsExpression(rVariables, rTokens) while '/' in availableOperations: _, tok, rem, com = expressionDivision(rVariables, rTokens) rTokens = removeToken(tok, rem) comments.append(com) animBuilder = copy.deepcopy(lTokens) lenToks = len(lTokens) equalTo = Binary() equalTo.scope = [lenToks] equalTo.value = '=' animBuilder.append(equalTo) if len(rTokens) == 0: zero = Zero() zero.scope = [lenToks + 1] animBuilder.append(zero) else: animBuilder.extend(rTokens) animation.append(copy.deepcopy(animBuilder)) rVariables = getLevelVariables(rTokens) availableOperations = getOperationsExpression(rVariables, rTokens) tokenToStringBuilder = copy.deepcopy(lTokens) lenToks = len(lTokens) equalTo = Binary() equalTo.scope = [lenToks] equalTo.value = '=' tokenToStringBuilder.append(equalTo) if len(rTokens) == 0: zero = Zero() zero.scope = [lenToks + 1] tokenToStringBuilder.append(zero) else: tokenToStringBuilder.extend(rTokens) token_string = tokensToString(tokenToStringBuilder) lVariables = getLevelVariables(lTokens) rVariables = getLevelVariables(rTokens) availableOperations = getOperationsEquation(lVariables, lTokens, rVariables, rTokens) return lTokens, rTokens, availableOperations, token_string, animation, comments
def cubicRoots(lTokens, rTokens): '''Used to get roots of a cubic equation This functions also translates roots {list} into final result of solution Argument: lTokens {list} -- list of LHS tokens rTokens {list} -- list of RHS tokens Returns: lTokens {list} -- list of LHS tokens rTokens {list} -- list of RHS tokens {empty list} token_string {string} -- final result stored in a string animation {list} -- list of equation solving process comments {list} -- list of comments in equation solving process ''' from visma.solvers.polynomial.roots import getCoefficients animations = [] comments = [] lTokens, rTokens, _, token_string, animNew1, commentNew1 = simplifyEquation( lTokens, rTokens) animations.extend(animNew1) comments.extend(commentNew1) if len(rTokens) > 0: lTokens, rTokens = moveRTokensToLTokens(lTokens, rTokens) coeffs = getCoefficients(lTokens, rTokens, 3) var = getVariables(lTokens) roots, animNew2, commentNew2 = getRootsCubic(coeffs) animations.extend(animNew2) comments.extend(commentNew2) tokens1 = [] expression1 = Expression(coefficient=1, power=3) variable = Variable(1, var[0], 1) tokens1.append(variable) if roots[0][1] == 0: binary = Binary() if roots[0][0] < 0: roots[0][0] *= -1 binary.value = '+' else: binary.value = '-' tokens1.append(binary) constant = Constant(round(roots[0][0], ROUNDOFF), 1) tokens1.append(constant) expression1.tokens = tokens1 lTokens = [expression1, Binary('*')] if len(roots) > 1: expression1.power = 1 for _, root in enumerate(roots[1:]): tokens2 = [] expression2 = Expression(coefficient=1, power=1) variable = Variable(1, var[0], 1) tokens2.append(variable) binary = Binary() if root[1] == 0: if root[0] < 0: root[0] *= -1 binary.value = '+' else: binary.value = '-' tokens2.append(binary) constant = Constant(round(root[0], ROUNDOFF), 1) tokens2.append(constant) else: binary.value = '-' tokens2.append(binary) expressionResult = Expression(coefficient=1, power=1) tokensResult = [] real = Constant(round(root[0], ROUNDOFF), 1) tokensResult.append(real) imaginary = Constant(round(root[1], ROUNDOFF), 1) if imaginary.value < 0: tokensResult.append(Minus()) imaginary.value = abs(imaginary.value) tokensResult.append(imaginary) else: tokensResult.extend([Plus(), imaginary]) sqrt = Sqrt(Constant(2, 1), Constant(-1, 1)) tokensResult.append(Binary('*')) tokensResult.append(sqrt) expressionResult.tokens = tokensResult tokens2.append(expressionResult) expression2.tokens = tokens2 lTokens.extend([expression2, Binary('*')]) lTokens.pop() rTokens = [Zero()] tokenToStringBuilder = copy.deepcopy(lTokens) tokLen = len(lTokens) equalTo = Binary() equalTo.scope = [tokLen] equalTo.value = '=' tokenToStringBuilder.append(equalTo) tokenToStringBuilder.extend(rTokens) token_string = tokensToString(tokenToStringBuilder) animations.append(copy.deepcopy(tokenToStringBuilder)) comments.append([]) return lTokens, rTokens, [], token_string, animations, comments
def quadraticRoots(lTokens, rTokens): '''Used to get quadratic roots of an equation Argument: lTokens {list} -- list of LHS tokens rTokens {list} -- list of RHS tokens Returns: lTokens {list} -- list of LHS tokens rTokens {list} -- list of RHS tokens {empty list} token_string {string} -- final result stored in a string animation {list} -- list of equation solving process comments {list} -- list of comments in equation solving process ''' from visma.solvers.polynomial.roots import getCoefficients animations = [] comments = [] lTokens, rTokens, _, token_string, animNew1, commentNew1 = simplifyEquation(lTokens, rTokens) animations.extend(animNew1) comments.extend(commentNew1) if len(rTokens) > 0: lTokens, rTokens = moveRTokensToLTokens(lTokens, rTokens) coeffs = getCoefficients(lTokens, rTokens, 2) var = getVariables(lTokens) roots, animNew2, commentNew2 = getRootsQuadratic(coeffs) animations.extend(animNew2) comments.extend(commentNew2) if len(roots) == 1: tokens = [] expression = Expression(coefficient=1, power=2) variable = Variable(1, var[0], 1) tokens.append(variable) binary = Binary() if roots[0] < 0: roots[0] *= -1 binary.value = '+' else: binary.value = '-' tokens.append(binary) constant = Constant(round(roots[0], ROUNDOFF), 1) tokens.append(constant) expression.tokens = tokens lTokens = [expression] elif len(roots) == 2: tokens = [] expression = Expression(coefficient=1, power=1) variable = Variable(1, var[0], 1) tokens.append(variable) binary = Binary() if roots[0] < 0: roots[0] *= -1 binary.value = '+' else: binary.value = '-' tokens.append(binary) constant = Constant(round(roots[0], ROUNDOFF), 1) tokens.append(constant) expression.tokens = tokens tokens2 = [] expression2 = Expression(coefficient=1, power=1) tokens2.append(variable) binary2 = Binary() if roots[1] < 0: roots[1] *= -1 binary2.value = '+' else: binary2.value = '-' tokens2.append(binary2) constant2 = Constant(round(roots[1], ROUNDOFF), 1) tokens2.append(constant2) expression2.tokens = tokens2 binary3 = Binary() binary3.value = '*' lTokens = [expression, binary3, expression2] elif len(roots) == 3: binary4 = Binary() if roots[0] < 0: roots[0] *= -1 binary4.value = '+' else: binary4.value = '-' constant3 = Constant(round(roots[0], ROUNDOFF), 1) binary5 = Binary() binary5.value = '*' constant2 = Constant(round(roots[2], ROUNDOFF), 1) tokens = [] expression = Expression(coefficient=1, power=1) variable = Variable(1, var[0], 1) tokens.extend([variable, binary4, constant3]) binary = Binary() binary.value = '+' tokens.extend([binary, constant2, binary5]) constant = Constant(round(roots[1], ROUNDOFF), 1) sqrt = Sqrt(Constant(2, 1), constant) tokens.append(sqrt) expression.tokens = tokens tokens2 = [] expression2 = Expression(coefficient=1, power=1) variable2 = Variable(1, var[0], 1) tokens2.extend([variable2, binary4, constant3]) binary2 = Binary() binary2.value = '-' tokens2.extend([binary2, constant2, binary5, sqrt]) expression2.tokens = tokens2 binary3 = Binary() binary3.value = '*' lTokens = [expression, binary3, expression2] zero = Zero() rTokens = [zero] comments.append([]) tokenToStringBuilder = copy.deepcopy(lTokens) tokLen = len(lTokens) equalTo = Binary() equalTo.scope = [tokLen] equalTo.value = '=' tokenToStringBuilder.append(equalTo) tokenToStringBuilder.extend(rTokens) animations.append(copy.deepcopy(tokenToStringBuilder)) token_string = tokensToString(tokenToStringBuilder) return lTokens, rTokens, [], token_string, animations, comments