def logicalNOT(token1): """Implements Bitwise NOT Arguments: token1 -- {list} -- List of tokens of a constant number Returns: 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 """ comments = [] animations = [] token1, _, _, _, _ = simplify(token1) if isinstance(token1, Constant): comments += [['Converting numbers to Binary Illustrations: ']] animations += [[]] binaryValue1 = token1.binary() comments += [[]] animations += [[tokenizer('a = ' + str(binaryValue1))]] resultValueBinary = bin((1 << 8) - 1 - int(binaryValue1, 2)) resultValue = int(resultValueBinary, 2) comments += [['Final binary is']] animations += [[tokenizer('r = ' + str(resultValueBinary))]] comments += [['Final result is']] animations += [[tokenizer('r = ' + str(resultValue))]] token_string = 'r = ' + str(resultValue) return token_string, animations, comments else: return '', [], []
def plot(workspace, tokens=None): """When called from window.py it initiates rendering of equations. Arguments: workspace {QtWidgets.QWidget} -- main layout """ from visma.io.tokenize import tokenizer workspace.figure2D.clear() workspace.figure3D.clear() if tokens is None: tokens = workspace.eqToks[-1] eqType = getTokensType(tokens) LHStok, RHStok = getLHSandRHS(tokens) variables = sorted(getVariables(LHStok, RHStok)) dim = len(variables) graphVars, func, variables = graphPlot(workspace, False, tokens) renderPlot(workspace, graphVars, func, variables, tokens) if (dim == 1): var2, var3 = selectAdditionalVariable(variables[0]) if tokens is None: workspace.eqToks[-1] += tokenizer("0" + var2 + "+" + "0" + var3) else: tokens += tokenizer("0" + var2 + "+" + "0" + var3) if (((dim == 2) or (dim == 1)) & (eqType == 'equation')): graphVars, func, variables = graphPlot(workspace, True, tokens) renderPlot(workspace, graphVars, func, variables, tokens)
def factorial(tokens): '''Used to get factorial of tokens provided Argument: tokens {list} -- list of tokens Returns: result {list} -- list of result 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 ''' tokens, _, _, _, _ = simplify(tokens) animation = [] comments = [] if (isinstance(tokens[0], Constant) & len(tokens) == 1): value = int(tokens[0].calculate()) if value == 0: result = [Constant(1)] comments += [['Factorial of ZERO is defined to be 1']] animation += [tokenizer('f = ' + str(1))] else: resultString = '' for i in range(1, value + 1): resultString += (str(i) + '*') resultString = resultString[:-1] resultTokens = tokenizer(resultString) comments += [['Expanding the factorial as']] animation += [resultTokens] result, _, _, _, _ = simplify(resultTokens) token_string = tokensToString(result) comments += [['Hence result: ']] animation += [tokenizer('f = ' + token_string)] return result, [], token_string, animation, comments
def logicalAND(token1, token2): """Implements Bitwise AND Arguments: token1 -- {list} -- List of tokens of a constant number token2 -- {list} -- List of tokens of a constant number Returns: 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 """ comments = [] animations = [] token1, _, _, _, _ = simplify(token1) token2, _, _, _, _ = simplify(token2) if isinstance(token1, Constant) and isinstance(token2, Constant): comments += [['Converting numbers to Binary Illustrations: ']] animations += [[]] binaryValue1 = token1.binary() binaryValue2 = token2.binary() comments += [[]] animations += [[tokenizer('a = ' + str(binaryValue1))]] comments += [[]] animations += [[tokenizer('b = ' + str(binaryValue2))]] comments += [['Doing AND operation for each of the consecutive bit']] animations += [[]] resultValue = token1.calculate() & token2.calculate() comments += [['Final result is']] animations += [[tokenizer('r = ' + str(resultValue))]] token_string = 'r = ' + str(resultValue) return token_string, animations, comments else: return '', [], []
def simpleProbability(sampleSpace, requiredEvent=None): """Implements simple probability Arguments: sampleSpace -- {visma.discreteMaths.statistics.ArithemeticMean} requiredEvent -- {Event whose probability is to be calculated} Returns: 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 """ animations = [] comments = [] events = [] token_string = '' if sampleSpace.values is not []: events.extend(sampleSpace.values) totalOccurances = len(events) animations += [[]] comments += [['The total occurances are ' + str(totalOccurances)]] requiredOccurances = events.count(requiredEvent) animations += [[]] comments += [['The occurances of required event are ' + str(requiredOccurances)]] probability = requiredOccurances/totalOccurances comments += [['Hence, Required probability is: ']] animations += [tokenizer('P = ' + str(probability))] token_string = 'P = ' + str(probability) return token_string, animations, comments else: return '', [], []
def ArithemeticMean(sampleSpace): """Implements arithemetic mean Arguments: sampleSpace -- {visma.discreteMaths.statistics.ArithemeticMean} Returns: 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 """ animations = [] comments = [] if sampleSpace.values is not []: sm = sum(sampleSpace.values) animations += [[]] comments += [[ 'Sum of all the values of the sample space provided by user: '******'' for val in sampleSpace.values: summationString += str(val) + '+' summationString = summationString[:-1] summationTokens = tokenizer(summationString) resultTokens, _, _, _, _ = simplify(summationTokens) if len(resultTokens) == 1 and isinstance(resultTokens[0], Constant): ArithemeticMean = resultTokens[0] / Constant( len(sampleSpace.values)) animations += [[]] comments += [[ 'Considering ' + str(len(sampleSpace.values)) + ' values.' ]] animations += [[tokenizer('mean = ' + str(ArithemeticMean.calculate))]] token_string = tokensToString([ArithemeticMean]) return token_string, animations, comments else: return '', [], []
def cramerMatrices(coefficients): ''' Arguments: coefficients -- 3 X 4 list -- each each row contains coefficients for x, y, z and constant term respectively Returns: Dx, Dy, Dz, D -- 3 X 4 list -- Cramer's Matrices for implementing Cramer's Rule. ''' D = [[0] * 3 for _ in range(3)] Dx = [[0] * 3 for _ in range(3)] Dy = [[0] * 3 for _ in range(3)] Dz = [[0] * 3 for _ in range(3)] for i in range(3): for j in range(3): D[i][j] = coefficients[i][j] Dx[i][j] = coefficients[i][j] Dy[i][j] = coefficients[i][j] Dz[i][j] = coefficients[i][j] for k in range(3): Dx[k][0] = coefficients[k][3] Dy[k][1] = coefficients[k][3] Dz[k][2] = coefficients[k][3] for i in range(3): for j in range(3): D[i][j] = tokenizer(str(D[i][j])) Dx[i][j] = tokenizer(str(Dx[i][j])) Dy[i][j] = tokenizer(str(Dy[i][j])) Dz[i][j] = tokenizer(str(Dz[i][j])) matD = SquareMat() matD.value = D matDx = SquareMat() matDx.value = Dx matDy = SquareMat() matDy.value = Dy matDz = SquareMat() matDz.value = Dz return matD, matDx, matDy, matDz
def quickTest(inp, operation, wrtVar=None): lhs, rhs = getLHSandRHS(tokenizer(inp)) _, inpType = checkTypes(lhs, rhs) if inpType == "equation": if wrtVar is not None: _, _, _, token_string, _, _ = operation(lhs, rhs, wrtVar) else: _, _, _, token_string, _, _ = operation(lhs, rhs) elif inpType == "expression": if wrtVar is not None: _, _, token_string, _, _ = operation(lhs, wrtVar) else: _, _, token_string, _, _ = operation(lhs) output = removeSpaces(token_string) return output
def combination(nTokens, rTokens): '''Used to get Combination (nCr) Argument: nTokens {list} -- list of tokens of "n" in nCr rTokens {list} -- list of tokens of "r" in nCr Returns: result {list} -- list of result 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 ''' nTokens, _, _, _, _ = simplify(nTokens) rTokens, _, _, _, _ = simplify(rTokens) animation = [] comments = [] if (isinstance(nTokens[0], Constant) & len(nTokens) == 1) & (isinstance(rTokens[0], Constant) & len(rTokens) == 1): comments += [['nCr is defined as (n!)/(r!)*(n-r)!']] animation += [[]] comments += [['Solving for n!']] animation += [[]] numerator, _, _, animNew1, commentNew1 = factorial(nTokens) commentNew1[1] = ['(n)! is thus solved as: '] animation.extend(animNew1) comments.extend(commentNew1) denominator1 = nTokens[0] - rTokens[0] comments += [['Solving for (n - r)!']] animation += [[]] denominator1, _, _, animNew2, commentNew2 = factorial([denominator1]) commentNew2[1] = ['(n - r)! is thus solved as: '] comments.extend(commentNew2) animation.extend(animNew2) comments += [['Solving for r!']] animation += [[]] denominator2, _, _, animNew3, commentNew3 = factorial([rTokens[0]]) commentNew3[1] = ['r! is thus solved as: '] comments.extend(commentNew3) animation.extend(animNew3) denominator = denominator1[0] * denominator2[0] result = [numerator[0] / denominator] comments += [['On placing values in (n!)/(r!)*(n-r)!']] animation += [tokenizer('r = ' + tokensToString(result))] token_string = tokensToString(result) return result, [], token_string, animation, comments
def calluser(): availableOperations = [] tokenString = '' equationTokens = [] if varName == 'back': self.input = str(self.textedit.toPlainText()) self.tokens = tokenizer(self.input) # print(self.tokens) lhs, rhs = getLHSandRHS(self.tokens) operations, self.solutionType = checkTypes(lhs, rhs) self.refreshButtons(operations) else: if operation == 'solve': self.lTokens, self.rTokens, availableOperations, tokenString, equationTokens, comments = solveFor( self.lTokens, self.rTokens, varName) elif operation == 'integrate': self.lTokens, availableOperations, tokenString, equationTokens, comments = integrate( self.lTokens, varName) elif operation == 'differentiate': self.lTokens, availableOperations, tokenString, equationTokens, comments = differentiate( self.lTokens, varName) self.eqToks = equationTokens self.output = resultLatex(operation, equationTokens, comments, varName) if len(availableOperations) == 0: self.clearButtons() else: self.refreshButtons(availableOperations) if self.mode == 'normal': self.textedit.setText(tokenString) elif self.mode == 'interaction': cursor = self.textedit.textCursor() cursor.insertText(tokenString) if self.showStepByStep is True: showSteps(self) if self.showPlotter is True: plot(self)
def quickTest(inp, operation, wrtVar=None): if operation.__name__ not in ['ArithemeticMean', 'Mode', 'Median']: if (inp.count(';') == 2): afterSplit = inp.split(';') eqStr1 = afterSplit[0] eqStr2 = afterSplit[1] eqStr3 = afterSplit[2] tokens = [tokenizer(eqStr1), tokenizer(eqStr2), tokenizer(eqStr3)] token_string, _, _ = operation(tokens[0], tokens[1], tokens[2], wrtVar) return removeSpaces(token_string) elif (inp.count(';') == 1): afterSplit = inp.split(';') eqStr1 = afterSplit[0] eqStr2 = afterSplit[1] tokens = [tokenizer(eqStr1), tokenizer(eqStr2)] _, _, token_string, _, _ = operation(tokens[0], tokens[1]) return removeSpaces(token_string) else: lhs, rhs = getLHSandRHS(tokenizer(inp)) _, inpType = checkTypes(lhs, rhs) if inpType == "equation": if wrtVar is not None: _, _, _, token_string, _, _ = operation(lhs, rhs, wrtVar) else: _, _, _, token_string, _, _ = operation(lhs, rhs) elif inpType == "expression": if wrtVar is not None: _, _, token_string, _, _ = operation(lhs, wrtVar) else: _, _, token_string, _, _ = operation(lhs) else: sampleSpaceObject = sampleSpace(inp) token_string, _, _ = operation(sampleSpaceObject) output = removeSpaces(token_string) return output
def interactionMode(self): self.enableQSolver = False showQSolve(self, self.enableQSolver) cursor = self.textedit.textCursor() interactionText = cursor.selectedText() if str(interactionText) == '': self.mode = 'normal' self.input = str(self.textedit.toPlainText()) else: self.input = str(interactionText) self.mode = 'interaction' showbuttons = True if len(self.input) == 0: self.input = '0' QMessageBox.information( self, "Message", "No input is given. please enter some expression.") showbuttons = False self.tokens = tokenizer(self.input) self.addEquation() lhs, rhs = getLHSandRHS(self.tokens) self.lTokens = lhs self.rTokens = rhs operations, self.solutionType = checkTypes(lhs, rhs) if isinstance(operations, list) and showbuttons: opButtons = [] if len(operations) > 0: if len(operations) == 1: if operations[0] not in [ 'integrate', 'differentiate', 'find roots', 'factorize' ]: opButtons = ['simplify'] else: opButtons = ['simplify'] for operation in operations: if operation == '+': opButtons.append("addition") elif operation == '-': opButtons.append("subtraction") elif operation == '*': opButtons.append("multiplication") elif operation == '/': opButtons.append("division") else: opButtons.append(operation) if self.buttonSet: for i in reversed(range(self.solutionOptionsBox.count())): self.solutionOptionsBox.itemAt(i).widget().setParent(None) for i in range(int(len(opButtons) / 2) + 1): for j in range(2): if len(opButtons) > (i * 2 + j): self.solutionButtons[(i, j)] = QtWidgets.QPushButton( opButtons[i * 2 + j]) self.solutionButtons[(i, j)].resize(100, 100) self.solutionButtons[(i, j)].clicked.connect( self.onSolvePress(opButtons[i * 2 + j])) self.solutionOptionsBox.addWidget( self.solutionButtons[(i, j)], i, j) else: self.bottomButton.setParent(None) self.solutionWidget = QWidget() for i in range(int(len(opButtons) / 2) + 1): for j in range(2): if len(opButtons) > (i * 2 + j): self.solutionButtons[(i, j)] = QtWidgets.QPushButton( opButtons[i * 2 + j]) self.solutionButtons[(i, j)].resize(100, 100) self.solutionButtons[(i, j)].clicked.connect( self.onSolvePress(opButtons[i * 2 + j])) self.solutionOptionsBox.addWidget( self.solutionButtons[(i, j)], i, j) self.solutionWidget.setLayout(self.solutionOptionsBox) self.buttonSplitter.addWidget(self.solutionWidget) self.buttonSet = True
def commandExec(command): operation = command.split('(', 1)[0] inputEquation = command.split('(', 1)[1][:-1] if ',' in inputEquation: varName = inputEquation.split(',')[1] inputEquation = inputEquation.split(',')[0] lhs = [] rhs = [] solutionType = '' lTokens = [] rTokens = [] equationTokens = [] comments = [] tokens = tokenizer(inputEquation) lhs, rhs = getLHSandRHS(tokens) lTokens = lhs rTokens = rhs _, solutionType = checkTypes(lhs, rhs) if operation == 'simplify': if solutionType == 'expression': tokens, _, _, equationTokens, comments = simplify(tokens) else: lTokens, rTokens, _, _, equationTokens, comments = simplifyEquation( lTokens, rTokens) elif operation == 'addition': if solutionType == 'expression': tokens, _, _, equationTokens, comments = addition(tokens, True) else: lTokens, rTokens, _, _, equationTokens, comments = additionEquation( lTokens, rTokens, True) elif operation == 'subtraction': if solutionType == 'expression': tokens, _, _, equationTokens, comments = subtraction(tokens, True) else: lTokens, rTokens, _, _, equationTokens, comments = subtractionEquation( lTokens, rTokens, True) elif operation == 'multiplication': if solutionType == 'expression': tokens, _, _, equationTokens, comments = multiplication( tokens, True) else: lTokens, rTokens, _, _, equationTokens, comments = multiplicationEquation( lTokens, rTokens, True) elif operation == 'division': if solutionType == 'expression': tokens, _, _, equationTokens, comments = division(tokens, True) else: lTokens, rTokens, _, _, equationTokens, comments = divisionEquation( lTokens, rTokens, True) elif operation == 'simplify': if solutionType == 'expression': tokens, _, _, equationTokens, comments = simplify(tokens) else: lTokens, rTokens, _, _, equationTokens, comments = simplifyEquation( lTokens, rTokens) elif operation == 'factorize': tokens, _, _, equationTokens, comments = factorize(tokens) elif operation == 'find-roots': lTokens, rTokens, _, _, equationTokens, comments = quadraticRoots( lTokens, rTokens) elif operation == 'solve': lhs, rhs = getLHSandRHS(tokens) lTokens, rTokens, _, _, equationTokens, comments = solveFor( lTokens, rTokens, varName) elif operation == 'integrate': lhs, rhs = getLHSandRHS(tokens) lTokens, _, _, equationTokens, comments = integrate(lTokens, varName) elif operation == 'differentiate': lhs, rhs = getLHSandRHS(tokens) lTokens, _, _, equationTokens, comments = differentiate( lTokens, varName) printOnCLI(equationTokens, operation, comments)
def inverse(self): """Calculates the inverse of the matrix using Gauss-Jordan Elimination Arguments: matrix {visma.matrix.structure.Matrix} -- matrix token Returns: inv {visma.matrix.structure.Matrix} -- result matrix token """ from visma.simplify.simplify import simplify from visma.io.tokenize import tokenizer from visma.io.parser import tokensToString if tokensToString(self.determinant()) == "0": return -1 self.dim[0] = len(self.value) self.dim[1] = len(self.value[0]) n = self.dim[0] mat = Matrix() mat.empty([n, 2 * n]) for i in range(0, n): for j in range(0, 2 * n): if j < n: mat.value[i][j] = self.value[i][j] else: mat.value[i][j] = [] for i in range(0, n): for j in range(n, 2 * n): if j == (i + n): mat.value[i][j].extend(tokenizer('1')) else: mat.value[i][j].extend(tokenizer("0")) for i in range(n - 1, 0, -1): if mat.value[i - 1][0][0].value < mat.value[i][0][0].value: for j in range(0, 2 * n): temp = mat.value[i][j] mat.value[i][j] = mat.value[i - 1][j] mat.value[i - 1][j] = temp for i in range(0, n): for j in range(0, n): if j != i: temp = [] if len(mat.value[j][i]) != 1: temp.append(Expression(mat.value[j][i])) else: temp.extend(mat.value[j][i]) temp.append(Binary('/')) if len(mat.value[i][i]) != 1: temp.append(Expression(mat.value[i][i])) else: temp.extend(mat.value[i][i]) temp, _, _, _, _ = simplify(temp) for k in range(0, 2 * n): t = [] if mat.value[i][k][0].value != 0: if len(mat.value[i][k]) != 1: t.append(Expression(mat.value[i][k])) else: t.extend(mat.value[i][k]) t.append(Binary('*')) if len(temp) != 1: t.append(Expression(temp)) else: t.extend(temp) t, _, _, _, _ = simplify(t) mat.value[j][k].append(Binary('-')) if len(t) != 1: mat.value[j][k].append(Expression(t)) else: mat.value[j][k].extend(t) mat.value[j][k], _, _, _, _ = simplify( mat.value[j][k]) for i in range(0, n): temp = [] temp.extend(mat.value[i][i]) for j in range(0, 2 * n): if mat.value[i][j][0].value != 0: mat.value[i][j].append(Binary('/')) mat.value[i][j].extend(temp) mat.value[i][j], _, _, _, _ = simplify(mat.value[i][j]) inv = SquareMat() inv.empty([n, n]) for i in range(0, n): for j in range(n, 2 * n): inv.value[i][j - n] = mat.value[i][j] return inv
def expressionSimplification(tokens_now, scope, tokens1): '''Makes an input equation free from Expressions, i.e. solving each Expression recursively to convert them in other tokens. Arguments: tokens_now {list} -- list of original tokens as function gets called recursively scope {list} -- integers (bounds) indicating which Expression we are currently solving tokens1 {list} -- list of current tokens as function gets called recursively Returns: simToks {list} -- list of simplified tokens of each Expression 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 ''' animation = [] comments = [] pfTokens = [] i = 0 while (i < len(tokens1)): if (i + 1 < len(tokens1)): if isinstance(tokens1[i], Binary) and tokens1[i].value == '^': if isinstance(tokens1[i - 1], Expression): tokens1[i - 1].tokens, _, _, _, _ = expressionSimplification( tokens_now, scope, tokens1[i - 1].tokens) if isinstance(tokens1[i + 1], Expression): tokens1[i + 1].tokens, _, _, _, _ = expressionSimplification( tokens_now, scope, tokens1[i + 1].tokens) if len(tokens1[i + 1].tokens) == 1 and isinstance( tokens1[i + 1].tokens[0], Constant): tokens1[i + 1] = Constant( tokens1[i + 1].tokens[0].calculate(), 1, 1) if (isinstance(tokens1[i], Binary) and tokens1[i].value == '^') and isinstance( tokens1[i + 1], Constant): if float(tokens1[i + 1].calculate()).is_integer(): rep = int(tokens1[i + 1].calculate()) for _ in range(rep - 1): pfTokens.extend([Binary('*'), tokens1[i - 1]]) i += 1 else: pfTokens.append(tokens1[i]) else: pfTokens.append(tokens1[i]) else: pfTokens.append(tokens1[i]) i += 1 tokens1 = copy.deepcopy(pfTokens) animation.append(pfTokens) comments.append(['Expanding the powers of expressions']) mulFlag = True expressionMultiplication = False # Check for the case: {Non-Expression} * {Expression} for _ in range(50): for i, _ in enumerate(tokens1): mulFlag = False if isinstance(tokens1[i], Expression): if (i > 1): if (tokens1[i - 1].value == '*'): scope.append(i) tokens1[ i].tokens, _, _, _, _ = expressionSimplification( tokens_now, scope, tokens1[i].tokens) if isinstance(tokens1[i - 2], Expression): scope.append(i - 2) tokens1[ i - 2].tokens, _, _, _, _ = expressionSimplification( tokens_now, scope, tokens1[i - 2].tokens) a = tokens1[i - 2] b = tokens1[i] c = a * b mulFlag = True expressionMultiplication = True if isinstance(c, Expression): scope.append(i) c.tokens, _, _, _, _ = expressionSimplification( tokens_now, scope, c.tokens) tokens1[i] = c del tokens1[i - 1] del tokens1[i - 2] break trigonometricError = False # Check for the case: {Expression} * {Non-Expression} if not trigonometricError: for _ in range(50): for i, _ in enumerate(tokens1): mulFlag = False if isinstance(tokens1[i], Expression): if i + 2 < len(tokens1): if (tokens1[i + 1].value == '*'): scope.append(i) tokens1[ i].tokens, _, _, _, _ = expressionSimplification( tokens_now, scope, tokens1[i].tokens) if isinstance(tokens1[i + 2], Expression): scope.append(i + 2) tokens1[ i + 2].tokens, _, _, _, _ = expressionSimplification( tokens_now, scope, tokens1[i + 2].tokens) a = tokens1[i + 2] b = tokens1[i] trigonometricError = False for ec in b.tokens: if isinstance(ec, Trigonometric): trigonometricError = True break if not trigonometricError: c = a * b mulFlag = True expressionMultiplication = True if isinstance(c, Expression): scope.append(i) c.tokens, _, _, _, _ = expressionSimplification( tokens_now, scope, c.tokens) tokens1[i] = c del tokens1[i + 1] del tokens1[i + 1] break if not mulFlag: break if expressionMultiplication: animation.append(tokens1) comments.append(['Multiplying expressions']) # TODO: Implement verbose multiplication steps. simToks = [] expressionPresent = False for i, _ in enumerate(tokens1): if isinstance(tokens1[i], Expression): expressionPresent = True scope.append(i) newToks, _, _, _, _ = expressionSimplification( tokens_now, scope, tokens1[i].tokens) if not simToks: simToks.extend(newToks) elif (simToks[len(simToks) - 1].value == '+'): if isinstance(newToks[0], Constant): if (newToks[0].value < 0): simToks.pop() simToks.extend(newToks) elif (simToks[len(simToks) - 1].value == '-'): for _, x in enumerate(newToks): if x.value == '+': x.value = '-' elif x.value == '-': x.value = '+' if (isinstance(newToks[0], Constant)): if (newToks[0].value < 0): simToks[-1].value = '+' newToks[0].value = abs(newToks[0].value) elif (isinstance(newToks[0], Variable)): if (newToks[0].coefficient < 0): simToks[-1].value = '+' newToks[0].coefficient = abs(newToks[0].coefficient) simToks.extend(newToks) else: simToks.extend([tokens1[i]]) simToks = tokenizer(tokensToString(simToks)) if expressionPresent: animation += [simToks] comments += [['Opening up all the brackets']] # TODO: Implement Trigonometric functions in the simplify module. trigonometricError = False for tk in simToks: if isinstance(tk, Trigonometric): trigonometricError = True break if not trigonometricError: if scope == []: simToks, availableOperations, token_string, animExtra, commentExtra = simplifification( simToks) animExtra.pop(0) animation += animExtra comments += commentExtra else: availableOperations = '' token_string = '' else: availableOperations = [] token_string = tokensToString(simToks) # TODO: Implement verbose steps in simplification of Expressions (steps shown can be varied depending on length of expression) if scope != []: scope.pop() return simToks, availableOperations, token_string, animation, comments
def interactionMode(self): if not self.matrix: self.enableQSolver = False renderQuickSol(self, self.qSol, self.enableQSolver) cursor = self.textedit.textCursor() interactionText = cursor.selectedText() if str(interactionText) == '': self.mode = 'normal' self.input = str(self.textedit.toPlainText()) else: self.input = str(interactionText) self.mode = 'interaction' showbuttons = True if len(self.input) == 0: return self.warning("No input given!") self.simul = False self.combi = False self.matrix = False self.dualOperandMatrix = False self.scalarOperationsMatrix = False self.nonMatrixResult = False if self.input[0:4] == 'mat_': self.input = self.input[4:] self.input = self.input[0:-1] self.input = self.input[1:] self.matrix = True if not self.matrix: if ';' in self.input: self.simul = True if (self.input.count(';') == 2): afterSplit = self.input.split(';') eqStr1 = afterSplit[0] eqStr2 = afterSplit[1] eqStr3 = afterSplit[2] elif (self.input.count(';') == 1): self.combi = True afterSplit = self.input.split(';') eqStr1 = afterSplit[0] eqStr2 = afterSplit[1] eqStr3 = '' if self.simul: self.tokens = [tokenizer(eqStr1), tokenizer(eqStr2), tokenizer(eqStr3)] self.addEquation() operations = ['solve'] if self.combi: operations.extend(['combination', 'permutation']) self.solutionType = 'equation' else: self.tokens = tokenizer(self.input) # DBP: print(self.tokens) self.addEquation() lhs, rhs = getLHSandRHS(self.tokens) self.lTokens = lhs self.rTokens = rhs operations, self.solutionType = checkTypes(lhs, rhs) if isinstance(operations, list) and showbuttons: opButtons = [] if len(operations) > 0: if len(operations) == 1: if (operations[0] not in ['integrate', 'differentiate', 'find roots', 'factorize']) and (not self.simul): opButtons = ['simplify'] else: opButtons = ['simplify'] for operation in operations: if operation == '+': opButtons.append("addition") elif operation == '-': opButtons.append("subtraction") elif operation == '*': opButtons.append("multiplication") elif operation == '/': opButtons.append("division") else: opButtons.append(operation) else: if ',' in self.input: self.dualOperandMatrix = True [inputEquation1, inputEquation2] = self.input.split(', ') if '[' in inputEquation1: inputEquation1 = inputEquation1[1:][:-1] inputEquation1 = inputEquation1.split('; ') matrixOperand1 = [] for row in inputEquation1: row1 = row.split(' ') for i, _ in enumerate(row1): row1[i] = tokenizer(row1[i]) matrixOperand1.append(row1) self.Matrix1 = Matrix() self.Matrix1.value = matrixOperand1 inputEquation2 = inputEquation2[1:][:-1] inputEquation2 = inputEquation2.split('; ') matrixOperand2 = [] for row in inputEquation2: row1 = row.split(' ') for i, _ in enumerate(row1): row1[i] = tokenizer(row1[i]) matrixOperand2.append(row1) self.Matrix2 = Matrix() self.Matrix2.value = matrixOperand2 else: self.scalarOperationsMatrix = True inputEquation2 = inputEquation2[1:][:-1] inputEquation2 = inputEquation2.split('; ') matrixOperand2 = [] for row in inputEquation2: row1 = row.split(' ') for i, _ in enumerate(row1): row1[i] = tokenizer(row1[i]) matrixOperand2.append(row1) self.Matrix2 = Matrix() self.Matrix2.value = matrixOperand2 else: self.dualOperandMatrix = False inputEquation = self.input[:-2] inputEquation = inputEquation[:-1][1:] inputEquation = inputEquation.split('; ') matrixOperand = [] for row in inputEquation: row1 = row.split(' ') for i, _ in enumerate(row1): row1[i] = tokenizer(row1[i]) matrixOperand.append(row1) self.Matrix0 = Matrix() self.Matrix0.value = matrixOperand opButtons = [] if ',' in self.input: opButtons.extend(['Addition', 'Subtraction', 'Multiply']) else: opButtons.extend(['Determinant', 'Trace', 'Inverse']) if self.buttonSet: for i in reversed(range(self.solutionOptionsBox.count())): self.solutionOptionsBox.itemAt(i).widget().setParent(None) for i in range(int(len(opButtons) / 2) + 1): for j in range(2): if len(opButtons) > (i * 2 + j): self.solutionButtons[(i, j)] = QtWidgets.QPushButton( opButtons[i * 2 + j]) self.solutionButtons[(i, j)].resize(100, 100) self.solutionButtons[(i, j)].clicked.connect( self.onSolvePress(opButtons[i * 2 + j])) self.solutionOptionsBox.addWidget( self.solutionButtons[(i, j)], i, j) else: self.bottomButton.setParent(None) self.solutionWidget = QWidget() for i in range(int(len(opButtons) / 2) + 1): for j in range(2): if len(opButtons) > (i * 2 + j): self.solutionButtons[(i, j)] = QtWidgets.QPushButton( opButtons[i * 2 + j]) self.solutionButtons[(i, j)].resize(100, 100) self.solutionButtons[(i, j)].clicked.connect( self.onSolvePress(opButtons[i * 2 + j])) self.solutionOptionsBox.addWidget( self.solutionButtons[(i, j)], i, j) self.solutionWidget.setLayout(self.solutionOptionsBox) self.buttonSplitter.addWidget(self.solutionWidget) self.buttonSet = True
def calluser(): availableOperations = [] tokenString = '' equationTokens = [] self.input = str(self.textedit.toPlainText()) if varName == 'back': if self.input[0:4] == 'mat_': self.input = self.input[4:] self.input = self.input[0:-1] self.input = self.input[1:] if ';' in self.input: self.simul = True if (self.input.count(';') == 2): afterSplit = self.input.split(';') eqStr1 = afterSplit[0] eqStr2 = afterSplit[1] eqStr3 = afterSplit[2] elif (self.input.count(';') == 1): afterSplit = self.input.split(';') eqStr1 = afterSplit[0] eqStr2 = afterSplit[1] eqStr3 = '' if self.simul: self.tokens = [tokenizer(eqStr1), tokenizer(eqStr2), tokenizer(eqStr3)] else: self.tokens = tokenizer(self.input) # DBP: print(self.tokens) self.addEquation() lhs, rhs = getLHSandRHS(self.tokens) self.lTokens = lhs self.rTokens = rhs operations, self.solutionType = checkTypes(lhs, rhs) self.refreshButtons(operations) else: if operation == 'solve': if not self.simul: self.lTokens, self.rTokens, availableOperations, tokenString, equationTokens, comments = solveFor(self.lTokens, self.rTokens, varName) else: tokenString, equationTokens, comments = simulSolver(self.tokens[0], self.tokens[1], self.tokens[2], varName) elif operation == 'integrate': self.lTokens, availableOperations, tokenString, equationTokens, comments = integrate(self.lTokens, varName) elif operation == 'differentiate': self.lTokens, availableOperations, tokenString, equationTokens, comments = differentiate(self.lTokens, varName) self.eqToks = equationTokens renderQuickSol(self, tokenString, self.showQSolver) self.output = resultLatex(equationTokens, operation, comments, self.solutionType, self.simul, varName) if len(availableOperations) == 0: self.clearButtons() else: self.refreshButtons(availableOperations) if self.mode == 'normal': self.textedit.setText(tokenString) elif self.mode == 'interaction': cursor = self.textedit.textCursor() cursor.insertText(tokenString) if self.showStepByStep is True: showSteps(self) if self.showPlotter is True: plot(self)
def getTokens(eqString): tokens = tokenizer(eqString) if len(tokens) == 1: tokens = tokens[0] return tokens
def commandExec(command): operation = command.split('(', 1)[0] inputEquation = command.split('(', 1)[1][:-1] matrix = False # True when matrices operations are present in the code. if operation[0:4] == 'mat_': matrix = True if not matrix: """ This part handles the cases when VisMa is NOT dealing with matrices. Boolean flags used in code below: simul -- {True} when VisMa is dealing with simultaneous equations & {False} in all other cases """ varName = None if ',' in inputEquation: varName = inputEquation.split(',')[1] varName = "".join(varName.split()) inputEquation = inputEquation.split(',')[0] simul = False # True when simultaneous equation is present if (inputEquation.count(';') == 2) and (operation == 'solve'): simul = True afterSplit = inputEquation.split(';') eqStr1 = afterSplit[0] eqStr2 = afterSplit[1] eqStr3 = afterSplit[2] lhs = [] rhs = [] solutionType = '' lTokens = [] rTokens = [] equationTokens = [] comments = [] if simul: tokens = [tokenizer(eqStr1), tokenizer(eqStr2), tokenizer(eqStr3)] else: tokens = tokenizer(inputEquation) if '=' in inputEquation: lhs, rhs = getLHSandRHS(tokens) lTokens = lhs rTokens = rhs _, solutionType = checkTypes(lhs, rhs) else: solutionType = 'expression' lhs, rhs = getLHSandRHS(tokens) lTokens = lhs rTokens = rhs if operation == 'plot': app = QApplication(sys.argv) App(tokens) sys.exit(app.exec_()) elif operation == 'simplify': if solutionType == 'expression': tokens, _, _, equationTokens, comments = simplify(tokens) else: lTokens, rTokens, _, _, equationTokens, comments = simplifyEquation( lTokens, rTokens) elif operation == 'addition': if solutionType == 'expression': tokens, _, _, equationTokens, comments = addition(tokens, True) else: lTokens, rTokens, _, _, equationTokens, comments = additionEquation( lTokens, rTokens, True) elif operation == 'subtraction': if solutionType == 'expression': tokens, _, _, equationTokens, comments = subtraction( tokens, True) else: lTokens, rTokens, _, _, equationTokens, comments = subtractionEquation( lTokens, rTokens, True) elif operation == 'multiplication': if solutionType == 'expression': tokens, _, _, equationTokens, comments = multiplication( tokens, True) else: lTokens, rTokens, _, _, equationTokens, comments = multiplicationEquation( lTokens, rTokens, True) elif operation == 'division': if solutionType == 'expression': tokens, _, _, equationTokens, comments = division(tokens, True) else: lTokens, rTokens, _, _, equationTokens, comments = divisionEquation( lTokens, rTokens, True) elif operation == 'factorize': tokens, _, _, equationTokens, comments = factorize(tokens) elif operation == 'find-roots': lTokens, rTokens, _, _, equationTokens, comments = rootFinder( lTokens, rTokens) elif operation == 'solve': if simul: if varName is not None: _, equationTokens, comments = simulSolver( tokens[0], tokens[1], tokens[2], varName) else: _, equationTokens, comments = simulSolver( tokens[0], tokens[1], tokens[2]) solutionType = equationTokens else: lhs, rhs = getLHSandRHS(tokens) lTokens, rTokens, _, _, equationTokens, comments = solveFor( lTokens, rTokens, varName) elif operation == 'factorial': tokens, _, _, equationTokens, comments = factorial(tokens) elif operation == 'combination': n = tokenizer(inputEquation) r = tokenizer(varName) tokens, _, _, equationTokens, comments = combination(n, r) elif operation == 'permutation': n = tokenizer(inputEquation) r = tokenizer(varName) tokens, _, _, equationTokens, comments = permutation(n, r) elif operation == 'integrate': lhs, rhs = getLHSandRHS(tokens) lTokens, _, _, equationTokens, comments = integrate( lTokens, varName) elif operation == 'differentiate': lhs, rhs = getLHSandRHS(tokens) lTokens, _, _, equationTokens, comments = differentiate( lTokens, varName) if operation != 'plot': # FIXME: when either plotting window or GUI window is opened from CLI and after it is closed entire CLI exits, it would be better if it is avoided final_string = resultStringCLI(equationTokens, operation, comments, solutionType, simul) print(final_string) else: """ This part handles the cases when VisMa is dealing with matrices. Boolean flags used in code below: dualOperand -- {True} when the matrix operations require two operands (used in operations like addition, subtraction etc) nonMatrixResult -- {True} when the result after performing operations on the Matrix is not a Matrix (in operations like Determinant, Trace etc.) scalarOperations -- {True} when one of the operand in a scalar (used in operations like Scalar Addition, Scalar Subtraction etc.) """ operation = operation[4:] dualOperand = False nonMatrixResult = False scalarOperations = False if ', ' in inputEquation: dualOperand = True [inputEquation1, inputEquation2] = inputEquation.split(', ') if '[' in inputEquation1: inputEquation1 = inputEquation1[1:][:-1] inputEquation1 = inputEquation1.split('; ') matrixOperand1 = [] for row in inputEquation1: row1 = row.split(' ') for i, _ in enumerate(row1): row1[i] = tokenizer(row1[i]) matrixOperand1.append(row1) Matrix1 = Matrix() Matrix1.value = matrixOperand1 inputEquation2 = inputEquation2[1:][:-1] inputEquation2 = inputEquation2.split('; ') matrixOperand2 = [] for row in inputEquation2: row1 = row.split(' ') for i, _ in enumerate(row1): row1[i] = tokenizer(row1[i]) matrixOperand2.append(row1) Matrix2 = Matrix() Matrix2.value = matrixOperand2 Matrix1_copy = copy.deepcopy(Matrix1) Matrix2_copy = copy.deepcopy(Matrix2) else: scalarOperations = True scalar = inputEquation1 scalarTokens = scalar # scalarTokens = tokenizer(scalar) inputEquation2 = inputEquation2[1:][:-1] inputEquation2 = inputEquation2.split('; ') matrixOperand2 = [] for row in inputEquation2: row1 = row.split(' ') for i, _ in enumerate(row1): row1[i] = tokenizer(row1[i]) matrixOperand2.append(row1) Matrix2 = Matrix() Matrix2.value = matrixOperand2 scalarTokens_copy = copy.deepcopy(scalarTokens) Matrix2_copy = copy.deepcopy(Matrix2) else: inputEquation = inputEquation[1:][:-1] inputEquation = inputEquation.split('; ') matrixOperand = [] for row in inputEquation: row1 = row.split(' ') for i, _ in enumerate(row1): row1[i] = tokenizer(row1[i]) matrixOperand.append(row1) Matrix0 = Matrix() Matrix0.value = matrixOperand Matrix0_copy = copy.deepcopy(Matrix0) if operation == 'simplify': MatrixResult = simplifyMatrix(Matrix0) elif operation == 'add': MatrixResult = addMatrix(Matrix1, Matrix2) elif operation == 'sub': MatrixResult = subMatrix(Matrix1, Matrix2) elif operation == 'mult': MatrixResult = multiplyMatrix(Matrix1, Matrix2) elif operation == 'determinant': nonMatrixResult = True sqMatrix = SquareMat() sqMatrix.value = Matrix0.value result = sqMatrix.determinant() elif operation == 'trace': nonMatrixResult = True sqMatrix = SquareMat() sqMatrix.value = Matrix0.value result = sqMatrix.traceMat() elif operation == 'inverse': sqMatrix = SquareMat() sqMatrix.value = Matrix0.value MatrixResult = SquareMat() MatrixResult = sqMatrix.inverse() finalCLIstring = '' if dualOperand: if not scalarOperations: finalCLIstring = resultMatrixString(operation=operation, operand1=Matrix1_copy, operand2=Matrix2_copy, result=MatrixResult) else: finalCLIstring = resultMatrixString(operation=operation, operand1=scalarTokens_copy, operand2=Matrix2_copy, result=MatrixResult) else: if nonMatrixResult: finalCLIstring = resultMatrixString(operation=operation, operand1=Matrix0_copy, nonMatrixResult=True, result=result) else: finalCLIstring = resultMatrixString(operation=operation, operand1=Matrix0_copy, result=MatrixResult) print(finalCLIstring)