import doctest

def faroShuffle(oldDeck, outShuffle=True):
    """
    performs a 'faro' or 'perfect' shuffle

    `oldDeck` (a sequence) is the original deck.  The shuffled deck is
    returned.  It does an 'out' shuffle (top and bottom cards
    preserved).
 
    >>> # To shuffle two cards...
    >>> faroShuffle([0, 1])
    [0, 1]

    >>> # Four cards...
    >>> faroShuffle([0, 1, 2, 3])
    [0, 2, 1, 3]

    >>> # A deck (range) of 10 cards...
    >>> faroShuffle(range(10))
    [0, 5, 1, 6, 2, 7, 3, 8, 4, 9]

    >>> # Suppose we try to shuffle a list that includes non-integers...
    >>> faroShuffle(['queen', 'jack', 'ace', 7])
    ['queen', 'ace', 'jack', 7]

    >>> # Three cards, being an odd number, should raise an exception...
    >>> faroShuffle([0, 1, 2])
    Traceback (most recent call last):
    ...
    ValueError: attempt to assign sequence of size 2 to extended slice of size 1

    >>> # How about something that's not a sequence?
    >>> faroShuffle(1)
    Traceback (most recent call last):
    ...
    TypeError: object of type 'int' has no len()

    >>> # An empty list should be returned unchanged.
    >>> faroShuffle([])
    []

    >>> # How about an empty argument list?
    >>> faroShuffle()
    Traceback (most recent call last):
    ...
    TypeError: faroShuffle() takes at least 1 argument (0 given)
    """
    # Look how easy Python makes this!
    n = len(oldDeck)
    newDeck = n*[ 0 ] # initializes result
    newDeck[0:n-1:2] = oldDeck[:n//2] # insert left hand
    newDeck[1:n:2]   = oldDeck[n//2:] # insert right hand
    return newDeck

if __name__ == '__main__':
    doctest.testmod()
