Esempio n. 1
0
 def _move_to_left(self) -> None:
     if not len(self._res):
         self.select_action(Token('0', 0))
     self._moved_left = True
     self._possible_unary = False
     self.select_action(Token('-', self._position))
     self.select_action(Token('(', self._position + 1))
Esempio n. 2
0
    def _second_degree(self) -> str:

        a = Node(Token('x', 0), 'var')
        a.power = 1
        a.mult = 0
        b = Node(Token('x', 0), 'var')
        b.power = 1
        b.mult = 0
        c = Node(Token('x', 0), 'var')
        c.power = 0
        c.mult = 0
        for val in self._terms:
            if val.power == 2:
                a = val
            elif val.power == 1:
                b = val
            else:
                c = val
        disc = self.discriminant(a, b, c)
        if disc < 0:
            print("Значение дискриминанта меньше 0. Действительных "
                  "решений нет.")
            disc = -disc
            res1 = f"{-b.mult / (2 * a.mult):.2} - " \
                   f"{round(sqrt(disc) / (2 * a.mult), 2):.2}i"
            res2 = f"{-b.mult / (2 * a.mult):.2} + " \
                   f"{round(sqrt(disc) / (2 * a.mult), 2):.2}i"
            return f"Результат:\n\tX1 = {res1}, X2 = {res2}"
        if disc == 0:
            if not self._quiet:
                print("Дискриминант равен нулю. Доступно одно решение.")
            res = -b.mult / (2 * a.mult)
            if not round(res, 2).is_integer():
                res = f"{round(res, 2):.2f}"
            else:
                res = int(res)
            return f"Результат:\n\tX = {res}"
        else:
            if not self._quiet:
                print("Дискриминант больше нуля. Доступно два решения.")
            res1 = (-b.mult - sqrt(disc)) / (2 * a.mult)
            res2 = (-b.mult + sqrt(disc)) / (2 * a.mult)
            if not round(res1, 2).is_integer():
                res1 = f"{round(res1, 2):.2f}"
            else:
                res1 = int(res1)
            if not round(res2, 2).is_integer():
                res2 = f"{round(res2, 2):.2f}"
            else:
                res2 = int(res2)
            return f"Результат:\n\tX1 = {res1}, X2 = {res2}"
Esempio n. 3
0
 def _handle_eos(self) \
         -> None:
     if self._moved_left:
         self._handle_parentheses(Token(')', 0))
     while not self._stack.is_empty():
         val = self._stack_to_res()
         if val.text == '(':
             raise ValidateError("Brackets not balanced", val)
Esempio n. 4
0
 def _handle_operator(self, op: Token) \
         -> None:
     if self._possible_unary and op.text in ['-', '+']:
         op.text = '@' if op.text == '-' else '#'
     while not self._stack.is_empty():
         if not self._stack.check_precedence(op):
             break
         self._stack_to_res()
     self.__increase_stack(op)
     self._possible_unary = True
Esempio n. 5
0
 def _add_token(self, token: Token) -> None:
     if token.text in operations:
         token = Node(token, NODE_OP)
     elif token.text in unary_op:
         token = Node(token, NODE_UNARY)
     elif token.text in ['x', 'X']:
         token = Node(token, NODE_VAR)
     elif token.isdigit():
         token = Node(token, NODE_NUM)
     else:
         raise ValidateError("Undefined token", token)
     self._stack.push(token)
Esempio n. 6
0
def create_tokens(equation: str) -> Generator:

    pattern = re.compile(r"("
                         r"(?:[-+()])"
                         r"|(?:[\d.]+)"
                         r"|(?:[*/])"
                         r"|(?:[xX])"
                         r"|(?:\^)"
                         r"|(?:\s+)"
                         r"|(?:=)"
                         r")")
    position: int = 0
    while position < len(equation):
        match_obj = pattern.match(equation, position)
        if match_obj is None:
            raise ValidateError("Символ не опознан. Уравнение не валидно.",
                                Token("", position))

        text = match_obj.group(1)
        yield Token(text, match_obj.start(1))
        position = match_obj.end()
Esempio n. 7
0
 def select_action(self, val: Token) \
         -> None:
     if val.position >= self._position:
         self._position = val.position
     if val.text in OPS:
         self._handle_operator(val)
     elif val.text.isspace():
         pass
     elif val.isdigit():
         if self._previous_token == ')':
             self.select_action(Token('*', self._position))
         self._res.append(val)
         self._possible_unary = False
     elif val.text in ['x', 'X']:
         if self.__previous_is_digit() or \
                 self._previous_token in ['x', 'X'] or \
                 self._previous_token == ')':
             self.select_action(Token('*', self._position))
         self._res.append(val)
         self._possible_unary = False
     elif val.text == '(':
         self.__increase_stack(val)
         self._possible_unary = True
     elif val.text == ')':
         if self._previous_token in OPS:
             raise ValidateError(
                 "Перед закрывающими скобками стоит "
                 "знак операции", val)
         self._handle_parentheses(val)
         self._possible_unary = False
     elif val.text == '=':
         if self._moved_left:
             raise ValidateError("Not more than one quality sign allowed",
                                 val)
         self._handle_eos()
         self._move_to_left()
         self._possible_unary = True
     else:
         raise ValidateError(f"Unknown token '{val.text}'", val)
Esempio n. 8
0
 def test_rpn(self, tokens, res):
     array = (Token(val, 0) for val in tokens)
     res_ = rpn.ShuntingYard(array).convert()
     assert ' '.join([val.text for val in res_]) == res
Esempio n. 9
0
 def test_precedence(self, op, res):
     res_ = self.stack.check_precedence(Token(op, 0))
     assert res == res_
Esempio n. 10
0
 def test_stack_push(self, op, size):
     self.stack.push(Token(op, 0))
     assert self.stack.size == size