def test_peek_pass(one_operand_calc_id: int): calc_id = one_operand_calc_id # given # when (push operand) # then operand = Stack.peek(id_=calc_id) assert operand_data[0] == operand # check that the stack is empty. stack = Stack.stack(id_=calc_id) assert 1 == len(stack)
def test_push_pass(calc_id: int): # given x, y = 1, 2 # when (push first operand) operand_x = Stack.push(operand=x, id_=calc_id) operand_y = Stack.push(operand=y, id_=calc_id) # then assert x == operand_x assert y == operand_y operands = Stack.stack(id_=calc_id) assert x == operands[0] assert y == operands[1]
class RPNCalculator: """Simple RPN calculator built around an in memory stack.""" # stack = None stack = Stack() @classmethod def start(cls): """Start a new calculation with a fresh stack.""" # return cls.stack.id_ return cls.stack.start() @classmethod def push(cls, operand: float, id_: int) -> float: """Push a number onto the stack.""" pushed_operand = cls.stack.push(operand=operand, id_=id_) return pushed_operand @classmethod def binary_op(cls, *, operator: Callable, id_: int) -> float: """Apply the operation to the last two numbers on the stack.""" try: x_operand = cls.stack.pop(id_=id_) except IndexError: raise OperandError("Stack empty. Missing first operand.") try: y_operand = cls.stack.pop(id_=id_) except IndexError: raise OperandError("Stack empty. Missing second operand.") result = operator(x_operand, y_operand) pushed_result = cls.stack.push(operand=result, id_=id_) return pushed_result @classmethod def add(cls, id_: int) -> float: """Add the last two numbers on the stack.""" result = cls.binary_op(operator=lambda x, y: y + x, id_=id_) return result @classmethod def sub(cls, id_: int) -> float: """Subtract the last two numbers on the stack.""" result = cls.binary_op(operator=lambda x, y: y - x, id_=id_) return result @classmethod def result(cls, id_: int) -> float: """Get the last entry in the stack.""" try: result = cls.stack.peek(id_=id_) return result except IndexError: raise OperandError("Stack empty.") @classmethod def delete(cls, id_: int) -> None: """Delete the calculation.""" # cls.start() cls.stack.delete(id_=id_)
def test_add_new_stack_pass(): # given # when calc_id = Stack.start() # then stacks = Stack.stacks() assert 1 == len(stacks) assert 1 == calc_id # when (delete the stack) Stack.delete(id_=calc_id) # then stack = Stack.stacks() assert 0 == len(stack)
def test_cascading_delete_pass(): # given x = 1 # when calc_id = Stack.start() Stack.push(operand=x, id_=calc_id) Stack.delete(id_=calc_id) # then stacks = Stack.stacks() assert 0 == len(stacks) # Check to make sure that the operands are removed through cascading delete. with session_scope() as session: operands = session.query(_Operand).filter( _Operand.calc_id == calc_id).all() assert 0 == len(operands)
def one_operand_calc_id(calc_id: int) -> int: Stack.push(operand=operand_data[0], id_=calc_id) return calc_id
def calc_id() -> int: calc_id = Stack.start() yield calc_id Stack.delete(id_=calc_id)