def calculate(self): from visma.functions.constant import Constant if isinstance(self.power, int) or isinstance( self.power, float) or isinstance(self.power, Constant): const = Constant() if isinstance(self.power, Constant): self.power = self.power.calculate() const.value = self.coefficient * (self.base**self.power) return const else: return self
def __mul__(self, other): from visma.io.checks import isNumber from visma.functions.constant import Constant if isinstance(other, Variable): for j, var in enumerate(other.value): found = False for k, var2 in enumerate(self.value): self.coefficient *= other.coefficient if var == var2: if isNumber(other.power[j]) and isNumber( self.power[k]): self.power[k] += other.power[j] if self.power[k] == 0: del self.power[k] del self.value[k] found = True break if not found: self.value.append(other.value[j]) self.power.append(other.power[j]) if len(self.value) == 0: result = Constant(self.coefficient) result.scope = self.scope result.power = 1 result.value = self.coefficient self = result return self elif isinstance(other, Constant): self.coefficient *= other.calculate() return self elif isinstance(other, Expression): result = Expression() for _, token in enumerate(other.tokens): if isinstance(token, Variable) or isinstance(token, Constant): c = copy.deepcopy(self) result.tokens.extend([c * token]) else: result.tokens.extend([token]) return result
def division_constants(constant1, constant2, coeff): no_1 = False no_2 = False constant = Constant() if isNumber(constant1.value): no_1 = True if isNumber(constant2.value): no_2 = True if no_1 and no_2: constant.value = (evaluateConstant( constant1) / evaluateConstant(constant2)) * coeff constant.power = 1 # removeScopes.append(tokens[i].scope) # removeScopes.append(tokens[i-1].scope) elif no_1 and not no_2: constant.value = [constant1.value] constant.power = [constant1.power] for i, val in enumerate(constant2.value): done = False for j, val2 in enumerate(constant.value): if val == val2: constant.power[j] -= constant2.power[i] done = True break if not done: constant.value.append(val) constant.power.append(-constant2.power[i]) constant.value.append(coeff) constant.power.append(1) # removeScopes.append(tokens[i].scope) # removeScopes.append(tokens[i-1].scope) elif not no_1 and no_2: constant.value = constant1.value constant.power = constant1.power done = False for i, val in enumerate(constant.value): if val == constant2.value: constant.power[i] -= constant2.power done = True break if not done: constant.value.append(constant2.value) constant.power.append(-constant2.power) constant.value.append(coeff) constant.power.append(1) # removeScopes.append(tokens[i].scope) # removeScopes.append(tokens[i+1].scope) elif not no_1 and not no_2: constant.value = constant1.value constant.power = constant1.power for i, val in enumerate(constant2.value): done = False for j, val2 in enumerate(constant.value): if val == val2: constant.power[j] -= constant2.power[i] done = True break if not done: constant.value.append(val) constant.power.append(-constant2.power[i]) constant.value.append(coeff) constant.power.append(1) # removeScopes.append(tokens[i].scope) # removeScopes.append(tokens[i-1].scope) return constant
def expressionDivision(variables, tokens): removeScopes = [] comments = [] for i, token in enumerate(tokens): if isinstance(token, Binary): if token.value in ['/']: prev = False nxt = False if i != 0: if tokens[i - 1].__class__ in [Variable, Constant]: prev = True if i + 1 < len(tokens): if tokens[i + 1].__class__ in [Variable, Constant]: nxt = True if nxt and prev: if isinstance(tokens[i + 1], Constant) and isinstance(tokens[i - 1], Constant): comments.append("Dividing " + r"$" + tokens[i - 1].__str__() + r"$" + " by " + r"$" + tokens[i + 1].__str__() + r"$") no_1 = False no_2 = False if isNumber(tokens[i - 1].value): no_1 = True if isNumber(tokens[i + 1].value): no_2 = True if no_1 and no_2: tokens[i + 1].value = evaluateConstant( tokens[i - 1]) / evaluateConstant(tokens[i + 1]) tokens[i + 1].power = 1 removeScopes.append(tokens[i].scope) removeScopes.append(tokens[i - 1].scope) elif no_1 and not no_2: value = tokens[i - 1].value power = tokens[i - 1].power tokens[i - 1].value = [value] tokens[i - 1].power = [power] for val in tokens[i + 1].value: tokens[i - 1].value.append(val) for pows in tokens[i + 1].power: tokens[i - 1].power.append(-pows) removeScopes.append(tokens[i].scope) removeScopes.append(tokens[i + 1].scope) elif not no_1 and no_2: tokens[i - 1].value.append(tokens[i + 1].value) tokens[i - 1].power.append(-tokens[i + 1].power) removeScopes.append(tokens[i].scope) removeScopes.append(tokens[i + 1].scope) elif not no_1 and not no_2: for vals in tokens[i + 1].value: tokens[i - 1].value.append(vals) for pows in tokens[i + 1].power: tokens[i - 1].power.append(pows) removeScopes.append(tokens[i].scope) removeScopes.append(tokens[i + 1].scope) return variables, tokens, removeScopes, comments elif isinstance(tokens[i + 1], Variable) and isinstance(tokens[i - 1], Variable): comments.append("Dividing " + r"$" + tokens[i - 1].__str__() + r"$" + " by " + r"$" + tokens[i + 1].__str__() + r"$") for j, var in enumerate(tokens[i + 1].value): found = False for k, var2 in enumerate(tokens[i - 1].value): tokens[i-1].coefficient /= tokens[i+1].coefficient if var == var2: if isNumber(tokens[i + 1].power[j]) and isNumber(tokens[i - 1].power[k]): tokens[i - 1].power[k] -= tokens[i + 1].power[j] if tokens[i - 1].power[k] == 0: del tokens[i - 1].power[k] del tokens[i - 1].value[k] found = True break if not found: tokens[i - 1].value.append(tokens[i + 1].value[j]) tokens[i - 1].power.append(-tokens[i + 1].power[j]) if len(tokens[i - 1].value) == 0: constant = Constant() constant.scope = tokens[i - 1].scope constant.power = 1 constant.value = tokens[i - 1].coefficient tokens[i - 1] = constant removeScopes.append(tokens[i].scope) removeScopes.append(tokens[i + 1].scope) return variables, tokens, removeScopes, comments elif (isinstance(tokens[i + 1], Variable) and isinstance(tokens[i - 1], Constant)): comments.append("Dividing " + r"$" + tokens[i - 1].__str__() + r"$" + " by " + r"$" + tokens[i + 1].__str__() + r"$") val = evaluateConstant(tokens[i - 1]) scope = tokens[i - 1].scope tokens[i - 1] = Variable() tokens[i - 1].value = tokens[i + 1].value tokens[i - 1].coefficient = val / \ tokens[i + 1].coefficient tokens[i - 1].power = [] tokens[i - 1].scope = scope for pows in tokens[i + 1].power: tokens[i - 1].power.append(-pows) removeScopes.append(tokens[i].scope) removeScopes.append(tokens[i + 1].scope) return variables, tokens, removeScopes, comments elif (isinstance(tokens[i - 1], Variable) and isinstance(tokens[i + 1], Constant)): comments.append("Dividing " + r"$" + tokens[i - 1].__str__() + r"$" + " by " + r"$" + tokens[i + 1].__str__() + r"$") tokens[i - 1].coefficient /= evaluateConstant(tokens[i + 1]) removeScopes.append(tokens[i].scope) removeScopes.append(tokens[i + 1].scope) return variables, tokens, removeScopes, comments return variables, tokens, removeScopes, comments
def expressionMultiplication(variables, tokens): removeScopes = [] comments = [] for i, token in enumerate(tokens): if isinstance(token, Binary): if token.value in ['*']: prev = False nxt = False if i != 0: if tokens[i - 1].__class__ in [Variable, Constant]: prev = True if i + 1 < len(tokens): if tokens[i + 1].__class__ in [Variable, Constant]: nxt = True if nxt and prev: comments.append("Multiplying " + r"$" + tokens[i - 1].__str__() + r"$" + " and " + r"$" + tokens[i + 1].__str__() + r"$") if isinstance(tokens[i + 1], Constant) and isinstance( tokens[i - 1], Constant): tokens[i + 1].value = evaluateConstant( tokens[i - 1]) * evaluateConstant(tokens[i + 1]) tokens[i + 1].power = 1 removeScopes.append(tokens[i].scope) removeScopes.append(tokens[i - 1].scope) return variables, tokens, removeScopes, comments elif isinstance(tokens[i + 1], Variable) and isinstance( tokens[i - 1], Variable): for j, var in enumerate(tokens[i + 1].value): found = False for k, var2 in enumerate(tokens[i - 1].value): tokens[i - 1].coefficient *= tokens[i + 1].coefficient if var == var2: if isNumber( tokens[i + 1].power[j]) and isNumber( tokens[i - 1].power[k]): tokens[i - 1].power[k] += tokens[ i + 1].power[j] if tokens[i - 1].power[k] == 0: del tokens[i - 1].power[k] del tokens[i - 1].value[k] found = True break if not found: tokens[i - 1].value.append(tokens[i + 1].value[j]) tokens[i - 1].power.append(tokens[i + 1].power[j]) if len(tokens[i - 1].value) == 0: constant = Constant() constant.scope = tokens[i - 1].scope constant.power = 1 constant.value = tokens[i - 1].coefficient tokens[i - 1] = constant removeScopes.append(tokens[i].scope) removeScopes.append(tokens[i + 1].scope) return variables, tokens, removeScopes, comments elif (isinstance(tokens[i + 1], Variable) and isinstance(tokens[i - 1], Constant)): tokens[i + 1].coefficient *= evaluateConstant( tokens[i - 1]) removeScopes.append(tokens[i].scope) removeScopes.append(tokens[i - 1].scope) return variables, tokens, removeScopes, comments elif (isinstance(tokens[i - 1], Variable) and isinstance(tokens[i + 1], Constant)): tokens[i - 1].coefficient *= evaluateConstant( tokens[i + 1]) removeScopes.append(tokens[i].scope) removeScopes.append(tokens[i + 1].scope) return variables, tokens, removeScopes, comments return variables, tokens, removeScopes, comments
def getLevelVariables(tokens): """Returns tokens of Function class from a list of function tokens Arguments: tokens {list} -- list of function tokens Returns: variables {list} -- list of tokens of Function class(Variable/Constant) """ variables = [] for i, term in enumerate(tokens): if isinstance(term, Variable): skip = False for var in variables: if var.value == term.value and var.power[0] == term.power: var.power.append(term.power) var.scope.append(term.scope) var.coefficient.append(term.coefficient) if i != 0 and isinstance(tokens[i - 1], Binary): var.before.append(tokens[i - 1].value) var.beforeScope.append(tokens[i - 1].scope) else: var.before.append('') var.beforeScope.append('') if i + 1 < len(tokens) and isinstance(tokens[i + 1], Binary): var.after.append(tokens[i + 1].value) var.afterScope.append(tokens[i + 1].scope) else: var.after.append('') var.afterScope.append('') skip = True break if not skip: variable = Variable() variable.value = term.value variable.scope = [term.scope] variable.power = [] variable.coefficient = [] variable.before = [] variable.beforeScope = [] variable.after = [] variable.afterScope = [] variable.power.append(term.power) variable.coefficient.append(term.coefficient) if i != 0 and isinstance(tokens[i - 1], Binary): variable.before.append(tokens[i - 1].value) variable.beforeScope.append(tokens[i - 1].scope) else: variable.before.append('') variable.beforeScope.append('') if i + 1 < len(tokens) and isinstance(tokens[i + 1], Binary): variable.after.append(tokens[i + 1].value) variable.afterScope.append(tokens[i + 1].scope) else: variable.after.append('') variable.afterScope.append('') variables.append(variable) elif isinstance(term, Constant): skip = False for var in variables: if isinstance(var.value, list) and isNumber(var.value[0]): if var.power[0] == term.power: var.value.append(term.value) var.power.append(term.power) var.scope.append(term.scope) if i != 0 and isinstance(tokens[i - 1], Binary): var.before.append(tokens[i - 1].value) var.beforeScope.append(tokens[i - 1].scope) else: var.before.append('') var.beforeScope.append('') if i + 1 < len(tokens) and isinstance(tokens[i + 1], Binary): var.after.append(tokens[i + 1].value) var.afterScope.append(tokens[i + 1].scope) else: var.after.append('') var.afterScope.append('') skip = True break if not skip: variable = Constant() variable.power = [] if isinstance(term.value, list): variable.value = [evaluateConstant(term)] variable.power.append(1) else: variable.value = [term.value] variable.power.append(term.power) variable.scope = [term.scope] variable.before = [] variable.beforeScope = [] variable.after = [] variable.afterScope = [] if i != 0 and isinstance(tokens[i - 1], Binary): variable.before.append(tokens[i - 1].value) variable.beforeScope.append(tokens[i - 1].scope) else: variable.before.append('') variable.beforeScope.append('') if i + 1 < len(tokens) and isinstance(tokens[i + 1], Binary): variable.after.append(tokens[i + 1].value) variable.afterScope.append(tokens[i + 1].scope) else: variable.after.append('') variable.afterScope.append('') variables.append(variable) elif isinstance(term, Expression): var = getLevelVariables(term.tokens) retType, val = extractExpression(var) if retType == "expression": variable = Expression() variable.value = val variable.tokens = term.tokens variables.append(variable) elif retType == "constant": skip = False for var in variables: if isinstance(var.value, list) and isNumber(var.value[0]): if var.power == val.power: var.value.append(val.value) var.power.append(val.power) var.scope.append(val.scope) var.before.append(val.before) var.beforeScope.append(val.beforeScope) var.after.append(val.after) var.afterScope.append(val.afterScope) skip = True break if not skip: var = Constant() var.value = [val.value] var.power = [val.power] var.scope = [val.scope] var.before = [val.before] var.beforeScope = [val.beforeScope] var.after = [] var.afterScope = [''] variables.append(var) elif retType == "variable": skip = False for var in variables: if var.value == val.value: var.power.append(val.power) var.before.append('') var.beforeScope.append('') var.after.append('') var.afterScope.append('') var.coefficient.append(val.coefficient) var.scope.append(val.scope) skip = True break if not skip: var = Constant() var.coefficient = [val.coefficient] var.value = val.value var.power = [val.power] var.scope = [val.scope] var.before = [''] var.beforeScope = [''] var.after = [''] var.afterScope = [''] variables.append(var) elif retType == "mixed": for v in val: if isinstance(v, Variable): skip = False for var in variables: if var.value == v.value: var.power.extend(v.power) var.before.extend(v.before) var.beforeScope.extend(v.beforeScope) var.after.extend(v.after) var.afterScope.extend(v.afterScope) var.coefficient.extend(v.coefficient) var.scope.extend(v.scope) skip = True break if not skip: var = Constant() var.coefficient = [v.coefficient] var.value = v.value var.power = [v.power] var.scope = [v.scope] var.before = [v.before] var.beforeScope = [v.beforeScope] var.after = [v.after] var.afterScope = [v.afterScope] variables.append(var) elif isinstance(v, Constant): for var in variables: if isinstance(var.value, list) and isNumber(var.value[0]): if var.power == v.power: var.value.extend(v.value) var.power.extend(v.power) var.before.extend(v.before) var.beforeScope.extend( v.beforeScope) var.after.extend(v.after) var.afterScope.extend(v.afterScope) var.coefficient.extend(v.coefficient) var.scope.extend(v.scope) skip = True break if not skip: var = Constant() var.coefficient = [v.coefficient] var.value = [v.value] var.power = [v.power] var.scope = [v.scope] var.before = [v.before] var.beforeScope = [v.beforeScope] var.after = [v.after] var.afterScope = [v.afterScope] variables.append(var) elif isinstance(v, Expression): variables.append(v) return variables
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