示例#1
0
 def __sub__(self, other):
     from visma.functions.constant import Constant
     from visma.functions.variable import Variable
     from visma.functions.operator import Plus, Minus
     if isinstance(other, Expression):
         result = Expression()
         for tok1 in self.tokens:
             result.tokens.append(tok1)
         for _, x in enumerate(other.tokens):
             if x.value == '+':
                 x.value = '-'
             elif x.value == '-':
                 x.value = '+'
         result.tokens.append(Minus())
         if (isinstance(other.tokens[0], Constant)):
             if (other.tokens[0].value < 0):
                 result.tokens[-1] = Plus()
                 other.tokens[0].value = abs(other.tokens[0].value)
         elif (isinstance(other.tokens[0], Variable)):
             if (other.tokens[0].coefficient < 0):
                 result.tokens[-1] = Plus()
                 other.tokens[0].coefficient = abs(other.tokens[0].coefficient)
         return result
     elif isinstance(other, Constant):
         result = self
         result += (Constant(0) - other)
         return result
     elif isinstance(other, Variable):
         result = self
         a = Constant(0) - other
         result = a + result
         return result
示例#2
0
 def __init__(self, dim):
     super().__init__()
     for i in range(0, dim[0]):
         row = []
         for j in range(0, dim[1]):
             if i == j:
                 row.append(Constant(1))
             else:
                 row.append(Constant(0))
         self.value.append(row)
示例#3
0
def test_Constant():

    constant1 = Constant(10)
    assert constant1.__str__() == "{10}"
    constant1.differentiate()
    assert constant1.value == 0

    constant2 = Constant(5)
    constant2.integrate('x')
    assert isinstance(constant2, Variable)
    assert constant2.__str__() == "5{x}"
示例#4
0
 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
示例#5
0
    def __pow__(self, other):
        from visma.functions.constant import Constant

        if isinstance(other, Constant):
            if other.value == -1:
                one = Constant(1, 1, 1)
                result = Variable()
                result.value = self.value
                result.coefficient = one.calculate() / self.coefficient
                result.power = []
                for pows in self.power:
                    result.power.append(-pows)
                return result
示例#6
0
def factorizeTokens(tokens):

    coeffs, var = getPolyCoeffs(tokens)
    gcf, roots, polynomial = factor(coeffs)
    if roots != []:
        tokens = []
        comment = "The real roots of the above polynomial are "
        for root in roots:
            comment += r"$" + str(root) + "\ ,\ " + r"$"
        if gcf != 1:
            tokens.append(Constant(float(gcf)))
            tokens.append(Multiply())
        for root in roots:
            expression = Expression()
            expression.tokens.append(Variable(1, var, 1))
            if root > 0:
                expression.tokens.append(Minus())
                expression.tokens.append(Constant(float(root)))
            elif root < 0:
                expression.tokens.append(Plus())
                expression.tokens.append(Constant(float(-root)))
            tokens.append(expression)
            tokens.append(Multiply())
        if polynomial != [1]:
            expression = Expression()
            degree = len(polynomial) - 1
            for i, coeff in enumerate(polynomial):
                if i == degree:
                    if coeff > 0:
                        expression.tokens.append(Plus())
                        expression.tokens.append(Constant(float(coeff)))
                    elif coeff < 0:
                        expression.tokens.append(Minus())
                        expression.tokens.append(Constant(float(-coeff)))
                elif coeff > 0:
                    expression.tokens.append(Plus())
                    expression.tokens.append(Variable(coeff, var, degree - i))
                elif coeff < 0:
                    expression.tokens.append(Minus())
                    expression.tokens.append(Variable(-coeff, var, degree - i))
            if isinstance(expression.tokens[0], Plus):
                expression.tokens.pop(0)
            tokens.append(expression)
        else:
            tokens.pop()
    else:
        comment = None
    animation = [tokens]
    comments = [comment]
    return tokens, animation, comments
示例#7
0
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
示例#8
0
def scalarDiv(const, mat):
    """Divides constant terms with Matrix

    Arguments:
        const {string}--- constant value
        mat {visma.matrix.structure.Matrix} -- matrix token

    Returns:
        matRes {visma.matrix.structure.Matrix} -- result matrix token
    """
    if const != 0:
        matRes = Matrix()
        matRes.empty([mat.dim[0], mat.dim[1]])
        for i in range(mat.dim[0]):
            for j in range(mat.dim[1]):
                if len(mat.value[i][j]) != 1:
                    matRes.value[i][j].append(Expression(mat.value[i][j]))
                else:
                    matRes.value[i][j].extend(mat.value[i][j])

                matRes.value[i][j].append(Binary('/'))
                matRes.value[i][j].append(Constant(int(const)))
        matRes = simplifyMatrix(matRes)
        return matRes
    else:
        logger.error("ZeroDivisionError: Cannot divide matrix by zero")
示例#9
0
def scalarSub(const, mat):
    """
    Subtracts constant terms with Matrix

    Arguments:
        const {string}--- constant value
        mat {visma.matrix.structure.Matrix} -- matrix token

    Returns:
        matRes {visma.matrix.structure.Matrix} -- subtracted matrix token

    Note:
        This scalar addition follows the following equation
            {mat} - {lambda}{identity mat}

    """
    matRes = Matrix()
    matRes.empty([mat.dim[0], mat.dim[1]])
    for i in range(mat.dim[0]):
        for j in range(mat.dim[1]):
            if i != j:
                matRes.value[i][j].extend(mat.value[i][j])
            else:
                if len(mat.value[i][j]) != 1:
                    matRes.value[i][j].append(Expression(mat.value[i][j]))
                else:
                    matRes.value[i][j].extend(mat.value[i][j])
                matRes.value[i][j].append(Binary('-'))
                matRes.value[i][j].append(Constant(int(const)))
    matRes = simplifyMatrix(matRes)
    return matRes
示例#10
0
 def differentiate(self, wrtVar):
     term1 = Constant(-1, 1, 1)
     term2 = copy.deepcopy(self)
     term2.__class__ = Sine
     term2.value = 'sin'
     result = Expression()
     result.tokens = [term1, Multiply(), term2]
     return result
示例#11
0
 def integrate(self, wrtVar=None):
     term1 = Constant(-1, 1, 1)
     term2 = copy.deepcopy(self)
     term2.__class__ = Cosine
     term2.value = 'cos'
     term2.coefficient = 1
     result = Expression()
     result.tokens = [term1, Multiply(), term2]
     return result
示例#12
0
 def differentiate(self, wrtVar):
     term1 = Constant(-1, 1, 1)
     term2 = copy.deepcopy(self)
     term2.__class__ = Cosecant
     term2.value = 'csc'
     term2.coefficient = 1
     term2.power = 2
     result = Expression()
     result.tokens = [term1, Multiply(), term2]
     return result
示例#13
0
 def integrate(self, wrtVar):
     term1 = Constant(-1, 1, 1)
     term2 = NaturalLog()
     term3 = Cosine()
     term3.operand = self.operand
     term2.operand = term3
     term2.power = 1
     term2.coefficient = 1
     result = Expression()
     result.tokens = [term1, Multiply(), term2]
     return result
示例#14
0
 def differentiate(self, wrtVar):
     term1 = Constant(-1, 1, 1)
     term2 = Cosecant()
     term2.operand = self.operand
     term2.coefficient = 1
     term3 = Cotangent()
     term3.operand = self.operand
     term3.coefficient = 1
     result = Expression()
     result.tokens = [term1, Multiply(), term2, Multiply(), term3]
     return result
示例#15
0
def test_isDiagonal():

    mat = getTokens("[1, 0; \
                      0, z]")
    assert mat.isDiagonal()

    mat = getTokens("[1+x, 0+y; \
                      0, z]")
    assert not mat.isDiagonal()

    mat = getTokens("[1, 2; \
                      1, 3; \
                      1, 4]")
    assert not mat.isDiagonal()

    mat = DiagMat([3, 3], [[Constant(1)], [Constant(5)], [Constant(2)]])
    assert mat.isDiagonal()

    mat = IdenMat([2, 2])
    assert mat.isDiagonal()
示例#16
0
    def __truediv__(self, other):
        from visma.functions.constant import Constant
        if isinstance(other, Variable) or isinstance(other, Constant):
            self = self * (other**Constant(-1, 1, 1))
            return self

        elif isinstance(other, Expression):
            expression = Expression()
            self.coefficient /= other.coefficient
            other.power *= -1
            expression.tokens = [self]
            expression.tokens.extend([Multiply(), other])
            self = expression
            return expression
示例#17
0
 def __sub__(self, other):
     from visma.functions.constant import Constant
     if isinstance(other, Variable):
         otherValueSorted = sorted(other.value)
         selfValueSorted = sorted(self.value)
         if (other.power == self.power) & (selfValueSorted
                                           == otherValueSorted):
             self = self + Constant(-1, 1, 1) * other
             return self
         else:
             expression = Expression()
             expression.tokens = [self]
             expression.tokens.extend([Minus(), other])
             self = expression
             return expression
     elif isinstance(other, Constant):
         if other.isZero():
             return self
         expression = Expression()
         expression.tokens = [self]
         expression.tokens.extend([Minus(), other])
         self = expression
         return expression
     elif isinstance(other, Expression):
         expression = Expression()
         expression.tokens = [self]
         for i, token in enumerate(other.tokens):
             if isinstance(token, Variable):
                 tokenValueSorted = sorted(token.value)
                 selfValueSorted = sorted(self.value)
                 if (token.power == self.power) & (tokenValueSorted
                                                   == selfValueSorted):
                     if other.tokens[i - 1].value == '+' or (i == 0):
                         self.coefficient -= other.tokens[i].coefficient
                     elif other.tokens[i - 1].value == '-':
                         self.coefficient += other.tokens[i].coefficient
                 else:
                     if other.tokens[i - 1].value == '+' or i == 0:
                         expression.tokens.extend([Plus(), Variable(token)])
                     elif other.tokens[i - 1].value == '-':
                         expression.tokens.extend(
                             [Minus(), Variable(token)])
             elif not isinstance(token, Binary):
                 if other.tokens[i - 1].value == '+' or (i == 0):
                     expression.tokens.extend([Minus(), token])
                 elif other.tokens[i - 1].value == '-':
                     expression.tokens.extend([Plus(), token])
         expression.tokens[0] = self
         self = expression
         return expression
示例#18
0
 def __init__(self, dim, diagElem):
     """
     dim {list} -- dimension of matrix
     diagElem {list} -- list of tokens list
     """
     super().__init__()
     self.dim = dim
     for i in range(0, dim[0]):
         row = []
         for j in range(0, dim[1]):
             if i == j:
                 row.append(diagElem[i])
             else:
                 row.append([Constant(0)])
         self.value.append(row)
示例#19
0
 def integrate(self, wrtVar):
     term1 = Constant(-1, 1, 1)
     term2 = NaturalLog()
     result = Expression()
     term3 = Cosecant()
     term3.operand = self.operand
     term4 = Cotangent()
     term4.operand = self.operand
     inExpression = Expression()
     inExpression.tokens = [term3, Plus(), term4]
     term2.operand = inExpression
     term2.power = 1
     term2.coefficient = 1
     result.tokens = [term1, Multiply(), term2]
     return result
示例#20
0
def substituteTokens(initTok, subsTok, givenTok):
    """Substitute initTok with subsTok in a givenTok.

    For example: substitute x(initTok) with wyz^2(subsTok) in xyz(givenTok)
    i.e. final_tok will be wy^2z^3

    Arguments:
        initTok {functions.structure.Function} -- token to be substituted
        subsTok {functions.structure.Function} -- substitute token
        givenTok {functions.structure.Function} -- given token

    Returns:
        givenTok {functions.structure.Function} -- given token after substitution
    """

    if isinstance(givenTok, Variable):
        if isinstance(initTok, Variable):
            power = getPowerRatio(initTok, givenTok)
            if isinstance(subsTok, Constant):
                givenTok = removeValues(initTok, givenTok)
                if len(givenTok.value) == 0:
                    givenTok = Constant(
                        (subsTok.value**power) * givenTok.coefficient)
                else:
                    givenTok.coefficient *= subsTok.value**power
            elif isinstance(subsTok, Variable):

                givenTok.coefficient /= initTok.coefficient**power
                givenTok.coefficient *= subsTok.coefficient**power
                givenTok = replaceValues(initTok, subsTok, givenTok, power)
            elif isinstance(subsTok, Expression):
                subs_copy = copy.deepcopy(subsTok)
                givenTok.coefficient /= initTok.coefficient**power
                givenTok.coefficient *= subs_copy.coefficient**power
                subs_copy.coefficient = 1
                subs_copy.power = power
                givenTok = removeValues(initTok, givenTok)
                if len(givenTok.value) == 0:
                    subs_copy.coefficient = givenTok.coefficient
                    givenTok = subs_copy
                else:
                    givenTok = Expression([givenTok, Multiply(), subs_copy])

    elif isinstance(givenTok, Expression):
        substitute(initTok, subsTok, Expression.toklist)

    return givenTok
示例#21
0
    def traceMat(self):
        """Returns the trace of a square matrix (sum of diagonal elements)

        Arguments:
            mat {visma.matrix.structure.Matrix} -- matrix token

        Returns:
            trace {visma.matrix.structure.Matrix} -- string token
        """
        from visma.simplify.simplify import simplify
        trace = []
        for i in range(self.dim[0]):
            trace.extend(self.value[i][i])
            trace.append(Binary('+'))
        trace.append(Constant(0))
        trace, _, _, _, _ = simplify(trace)
        return trace
示例#22
0
    def determinant(self, mat=None):
        """Calculates square matrices' determinant

        Returns:
            list of tokens forming the determinant
        """
        from visma.simplify.simplify import simplify

        if mat is None:
            self.dimension()
            mat = np.array(self.value)
        if (mat.shape[0] > 2):
            ans = []
            for i in range(mat.shape[0]):
                mat1 = SquareMat()
                mat1.value = np.concatenate((mat[1:, :i], mat[1:, i + 1:]),
                                            axis=1).tolist()
                a, _, _, _, _ = simplify(mat1.determinant())
                if (a[0].value != 0 and a != []):
                    a, _, _, _, _ = simplify(a + [Multiply()] +
                                             mat[0][i].tolist())
                    if (i % 2 == 0):
                        if (ans != []):
                            ans, _, _, _, _ = simplify(ans + [Plus()] + a)
                        else:
                            ans = a
                    else:
                        ans, _, _, _, _ = simplify(ans + [Minus()] + a)
        elif (mat.shape[0] == 2):
            a = Multiply()
            b = Minus()
            mat = mat.tolist()
            a1, _, _, _, _ = simplify(mat[0][0] + [a] + mat[1][1])
            a2, _, _, _, _ = simplify(mat[0][1] + [a] + mat[1][0])
            ans, _, _, _, _ = simplify([a1[0], b, a2[0]])
            if (isinstance(ans[0], Minus) or isinstance(
                    ans[0], Plus)) and ans[0].value not in ['+', '-']:
                ans[0] = Constant(ans[0].value)
        else:
            ans, _, _, _, _ = simplify(mat[0][0])
        if not ans:
            ans = Zero()
        return ans
示例#23
0
def row_echelon(mat):
    """
    Returns the row echelon form of the given matrix

    Arguments:
        mat {visma.matrix.structure.Matrix} -- matrix token

    Returns:
        row_echelon {visma.matrix.structure.Matrix} -- result matrix token
    """

    N = mat.dim[0]
    M = mat.dim[1]
    for k in range(0, N):
        if abs(mat.value[k][k][0].value) == 0.0:
            if k == N - 1:
                return simplifyMatrix(mat)
            else:
                for i in range(0, N):
                    t = mat.value[k][i]
                    mat.value[k][i] = mat.value[k + 1][i]
                    mat.value[k + 1][i] = t
        else:
            for i in range(k + 1, N):
                temp = []
                temp.extend(mat.value[i][k])
                temp.append(Binary('/'))
                temp.extend(mat.value[k][k])
                temp, _, _, _, _ = simplify(temp)
                for j in range(k + 1, M):
                    temp2 = []
                    temp2.extend(mat.value[k][j])
                    temp2.append(Binary('*'))
                    temp2.extend(temp)
                    temp2, _, _, _, _ = simplify(temp2)
                    mat.value[i][j].append(Binary('-'))
                    mat.value[i][j].extend(temp2)
                mat.value[i][k].append(Binary('*'))
                mat.value[i][k].append(Constant(0))
                mat = simplifyMatrix(mat)
    return simplifyMatrix(mat)
示例#24
0
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 '', [], []
示例#25
0
def scalarMult(const, mat):
    """Multiplies constant terms with Matrix

    Arguments:
        const {string}--- constant value
        mat {visma.matrix.structure.Matrix} -- matrix token

    Returns:
        matRes {visma.matrix.structure.Matrix} -- product matrix token
    """
    matRes = Matrix()
    matRes.empty([mat.dim[0], mat.dim[1]])
    for i in range(mat.dim[0]):
        for j in range(mat.dim[1]):
            if len(mat.value[i][j]) != 1:
                matRes.value[i][j].append(Expression(mat.value[i][j]))
            else:
                matRes.value[i][j].extend(mat.value[i][j])

            matRes.value[i][j].append(Binary('*'))
            matRes.value[i][j].append(Constant(int(const)))
    matRes = simplifyMatrix(matRes)
    return matRes
示例#26
0
    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
示例#27
0
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
示例#28
0
 def __rsub__(self, other):
     from visma.functions.constant import Constant
     return Constant(0, 1, 1) - self + other
示例#29
0
 def __init__(self, dim):
     super().__init__(dim, [[Constant(1)]] * dim[0])
     for i in range(0, dim[0]):
         self.value[i][i] = Constant(1)
示例#30
0
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