Beispiel #1
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
Beispiel #2
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
Beispiel #3
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
Beispiel #4
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
Beispiel #5
0
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
Beispiel #6
0
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
Beispiel #7
0
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