# An implementation of the Stack ADT.  Notice that the
# instance variables in this class (in this case there is
# only one) are not part of the public interface of the
# class.  Client code is not intended to access the instance
# variable.  Instead, the methods provide access.
# The single underscore at the beginning of the variable name
# alerts programmers to this fact.

# Exercises:
# - Uncomment the code that tests performance.  Run it, and
#   compare this implementation of Stack to the one in stack2.py.
# - implement __eq__, __str__, and __repr__.

class Stack:
    """
    A last-in, first-out (LIFO) stack of items
    """

    def __init__(self):
        """
        (Stack) -> NoneType

        Initialize this Stack to be empty.

        >>> isinstance(Stack(), Stack)
        True
        """
        
        # _data is not part of the public interface.
        self._data = []

    def pop(self):
        """
        (Stack) -> object

        Remove and return the top item from this Stack.

        >>> s = Stack()
        >>> s.push(2)
        >>> s.push(3)
        >>> s.pop()
        3
        """
        
        return self._data.pop()

    def is_empty(self):
        """ 
        (Stack) -> bool

        Return whether this Stack is empty.

        >>> s = Stack()
        >>> s.push(4)
        >>> s.pop()
        4
        >>> s.is_empty()
        True
        """
        return self._data == []

    def push(self, o):
        """ (Stack, object) -> NoneType

        Place object o on top of this Stack.
        """
        self._data.append(o)

if __name__  ==  '__main__':
    import doctest
    doctest.testmod()
    
    ## uncomment lines below to test performance
    #import time
    #s = Stack()
    #items = range(100000)
    ## start the clock
    #start = time.time()
    #for i in items:
        #s.push(i)
    #for i in items:
        #s.pop()
    #end = time.time()
    #print ("It took ", end - start, "to push/pop", len(items), "items")