from container import Container
import random


class Sack(Container):
    """
    A Sack with elements in no particular order.
    """

    def __init__(self):
        """
        Create a new, empty Sack self.

        @param Sack self: this Sack
        @rtype: None
        """

        # two possible ways of representing this info
        #
        # 1. a list where the elements are added in
        # random order, and we randomly choose an index
        # to remove
        #
        # 2. a dictionary where the values are the elements
        # from the Sack. Adding element will be done at a
        # random key, and removing an element will select
        # one at random from the dictionary keys (may use
        # either popitem, or pop on a randomly selected key)
        #
        # 3. a dictionary with some kind of generated
        # key that guarantees randomness for the values
        # (the elements in the Sack). You may not get the
        # behaviour you want with int keys - but you could
        # use, for example, varying strings, tuples of ints
        # e.g. (0, 0), (0, 1), (0, 2), ...

        # doing Option #1
        self._contents = []

        # Option #2
        # self._contents = {}

    def add(self, obj):
        """
        Add object obj to random position of Sack self.

        @param Sack self: this Sack
        @param object obj: object to place on Sack
        @rtype: None
        """

        # Option 1:
        self._contents.append(obj)
        random.shuffle(self._contents)

    def remove(self):
        """
        Remove and return some random element of Sack self.

        Assume Sack self is not empty.

        @param Sack self: this Sack
        @rtype: object

        >>> s = Sack()
        >>> s.add(7)
        >>> s.remove()
        7
        """
        # we could also raise an EmptyContainerException here if self is empty.

        # Option 1:
        victim = random.randint(0, len(self._contents)-1)
        return self._contents.pop(victim)

    def is_empty(self):
        """
        Return whether Sack self is empty.

        @param Sack self: this Sack
        @rtype: bool
        """
        return len(self._contents) == 0


if __name__ == "__main__":
    import doctest
    doctest.testmod()
