class ReversePolishNotationCalculator: """ Calculator of expression in Reverse Polish Notation """ def __init__(self): self.stack = Stack() def calculate(self, rpn_expression: ReversePolishNotation) -> float: """ Main method of the ReversePolishNotationCalculator class. Calculating result of expression in Reverse Polish Notation. :param rpn_expression: expression in Reverse Polish Notation Format :return: result of the expression """ for element in rpn_expression: if isinstance(element, Op): res = self._calculate_value(element) self.stack.push(res) else: self.stack.push(element) return self.stack.top().digit def _calculate_value(self, operator: Op) -> Digit: first = self.stack.top() self.stack.pop() second = self.stack.top() self.stack.pop() return operator(first, second)
class ReversePolishNotationCalculator: """ Calculator of expression in Reverse Polish Notation """ def __init__(self): self.stack = Stack() def calculate(self, rpn_expression: ReversePolishNotation) -> float: """ Main method of the ReversePolishNotationCalculator class. Calculating result of expression in Reverse Polish Notation. :param rpn_expression: expression in Reverse Polish Notation Format :return: result of the expression """ for el in rpn_expression: if isinstance(el, Digit): self.stack.push(el) if isinstance(el, Op): hitotsu = self.stack.top() self.stack.pop() futatsu = self.stack.top() self.stack.pop() self.stack.push(el(hitotsu, futatsu)) res = self.stack.top() return res
def test_top_gets_last_pushed_value(self): stack = Stack() stack.push(0) assert stack.top() == 0 stack.push(1) assert stack.top() == 1 stack.push(2) assert stack.top() == 2
def test_new_stack_from_generator(self): """ Create a Stack from a generator. Test that its size equals to the number provided in the generator. """ stack = Stack(range(10)) self.assertFalse(stack.empty()) self.assertEqual(stack.size(), 10) self.assertEqual(stack.top(), 9)
def test_new_stack_from_list(self): """ Create a Stack from a list. Check that the size of stack equals to the size of the list. Check that the top element of stack equals to the latest element of the list. """ data_to_stack = (1, 3, 5, 7, 2, 4) stack = Stack(data_to_stack) self.assertFalse(stack.empty()) self.assertEqual(stack.size(), len(data_to_stack)) self.assertEqual(stack.top(), data_to_stack[-1])
class ReversePolishNotationCalculator: """ Calculator of expression in Reverse Polish Notation """ def __init__(self): self.stack = Stack() def calculate(self, rpn_expression: ReversePolishNotation) -> float: for element in rpn_expression: if isinstance(element, Op): res = self.calculate_value(element) self.stack.push(res) else: self.stack.push(element) return self.stack.top() def _calculate_value(self, operator: Op) -> Digit: first = self.stack.top() self.stack.pop() second = self.stack.top() self.stack.pop() return operator.function(first, second)
class ReversePolishNotationCalculator: """ Calculator of expression in Reverse Polish Notation """ def __init__(self): self.stack = Stack() self.ops = { "+": (lambda a, b: a + b), "-": (lambda a, b: a - b), "*": (lambda a, b: a * b), "/": (lambda a, b: a / b) } def calculate(self, expr) -> int: """ Main method of the ReversePolishNotationCalculator class. Calculating result of expression in Reverse Polish Notation. :param rpn_expression: expression in Reverse Polish Notation Format :return: result of the expression """ a = ReversePolishNotationConverter(expr) result = a.convert().split() for res in result: if res in self.ops: operand2 = self.stack.top() self.stack.pop() operand1 = self.stack.top() self.stack.pop() rst = self.ops[res](operand1, operand2) self.stack.push(rst) else: self.stack.push(float(res)) return self.stack.top()
def test_push_sequence_of_elements(self): """ Push a sequence of elements in stack. Test that its size equals to the length of the given sequence. Pop all elements from stack and check reversed order. """ stack = Stack() elements = (1, 2, "string", None, 0, Stack()) map(stack.push, elements) self.assertEqual(stack.size(), len(elements)) for index, element in enumerate(reversed(elements)): top = stack.top() self.assertEqual(top, element) stack.pop() number_pop_elements = index + 1 expected_current_stack_size = len(elements) - number_pop_elements self.assertEqual(stack.size(), expected_current_stack_size) self.assertTrue(stack.empty())
def test_top_of_empty_stack_is_empty_stack_exception(self): stack = Stack() with raises(Stack.EmptyStackException): stack.top()