def test_peek():
    s = Stack()
    s.push("apple")
    s.push("banana")
    actual = s.peek()
    expected = "banana"
    assert actual == expected
def test_peek_empty():
    s = Stack()
    with pytest.raises(InvalidOperationError) as e:
        s.peek()
    assert str(e.value) == "Method not allowed on empty collection"
Beispiel #3
0
class StackMin2(Stack):
    """More efficient version of StackMin

    Doesn't store extra piece of data (min value) at every node, since this is
    v. inefficient if, say, first node is min value, and there are many nodes
    above it.

    Instead, use another stack to keep track of min value when it changes. Note
    that adding another element with value equal to the current min value does
    add to this stack, since otherwise removing this element would break
    get_min() (this wasn't clear in book's solution).
    ^Above solution based on book's solution.
    """
    def __init__(self):
        """Initialise stack as is done for Stack, but also introduce stack
        to track min values
        """
        # Initialise Stack
        super().__init__()

        # Use this stack to track min vals
        self.min_vals = Stack()

    def get_min(self):
        """Returns min value in stack

        Returns
        -------
        min_val : any
            Minimum value of sub-stack. Can be any Python object that allows
            comparison.
        """
        return self.min_vals.peek()

    def push(self, data):
        """Add item (data) to top of stack (i.e. to head of Stack).

        Ensure to add info about min of sub-array

        Parameters
        ----------
        data
            Data to store in stack.
        """
        # Find exising min_val
        # Handle special case of empty stack
        if self.head is None:
            self.min_vals.push(data)
        else:
            min_val = self.get_min()
            if data <= min_val:
                self.min_vals.push(data)

        # Add data to stack
        self.prepend(data)

    def pop(self):
        """Remove and return the top item from the stack.

        Returns
        -------
        any
            Data at head of Stack. Can be any Python object that allows
            comparison.
        """
        if self.head is None:
            raise Exception('{} is empty.'.format(self.__name__))

        # Retrieve head node data, then delete head node
        data = self.head.data
        self._delete_head()

        # Remove element from min_vals stack, if required
        if data == self.min_vals.peek():
            self.min_vals.pop()

        return data