In [1]:
import collections

In [2]:
Card = collections.namedtuple('Card', ['rank', 'suit','isup'])

In [3]:
help(collections.namedtuple)
#namedtuple is good to build classes of objects that are just bundles of attributes with no methods


Help on function namedtuple in module collections:

namedtuple(typename, field_names, verbose=False, rename=False)
    Returns a new subclass of tuple with named fields.
    
    >>> Point = namedtuple('Point', ['x', 'y'])
    >>> Point.__doc__                   # docstring for the new class
    'Point(x, y)'
    >>> p = Point(11, y=22)             # instantiate with positional args or keywords
    >>> p[0] + p[1]                     # indexable like a plain tuple
    33
    >>> x, y = p                        # unpack like a regular tuple
    >>> x, y
    (11, 22)
    >>> p.x + p.y                       # fields also accessible by name
    33
    >>> d = p._asdict()                 # convert to a dictionary
    >>> d['x']
    11
    >>> Point(**d)                      # convert from a dictionary
    Point(x=11, y=22)
    >>> p._replace(x=100)               # _replace() is like str.replace() but targets named fields
    Point(x=100, y=22)


In [4]:
type(Card)


Out[4]:
type

In [39]:
class FrenchDeck:
    #list of card ranks from 2 to A
    ranks = [str(n) for n in range(2,11)]+list('JQKA')
    #list of suits
    suits = 'spades diamonds clubs hearts'.split()
    isup = [0,1]#face up? no or yes
    
    def __init__(self):
        self._cards = [Card(rank, suit,0) for suit in self.suits
                      for rank in self.ranks]
    def __len__(self):
        return len(self._cards)
    def __getitem__(self, position):
        return self._cards[position]
    def remove(self,x):
        self._cards.remove(x) 
        print("{} removed from {}".format(x, self))

In [40]:
beer_card = Card('7', 'diamonds',0)
beer_card


Out[40]:
Card(rank='7', suit='diamonds', isup=0)

In [41]:
deck = FrenchDeck()
len(deck)


Out[41]:
52

In [42]:
deck.remove(beer_card)


Card(rank='7', suit='diamonds', isup=0) removed from <__main__.FrenchDeck object at 0x7fc2a81dc668>

In [38]:
len(deck)


Out[38]:
51

In [47]:
deck._cards#we can see that card is removed


Out[47]:
[Card(rank='2', suit='spades', isup=0),
 Card(rank='3', suit='spades', isup=0),
 Card(rank='4', suit='spades', isup=0),
 Card(rank='5', suit='spades', isup=0),
 Card(rank='6', suit='spades', isup=0),
 Card(rank='7', suit='spades', isup=0),
 Card(rank='8', suit='spades', isup=0),
 Card(rank='9', suit='spades', isup=0),
 Card(rank='10', suit='spades', isup=0),
 Card(rank='J', suit='spades', isup=0),
 Card(rank='Q', suit='spades', isup=0),
 Card(rank='K', suit='spades', isup=0),
 Card(rank='A', suit='spades', isup=0),
 Card(rank='2', suit='diamonds', isup=0),
 Card(rank='3', suit='diamonds', isup=0),
 Card(rank='4', suit='diamonds', isup=0),
 Card(rank='5', suit='diamonds', isup=0),
 Card(rank='6', suit='diamonds', isup=0),
 Card(rank='8', suit='diamonds', isup=0),
 Card(rank='9', suit='diamonds', isup=0),
 Card(rank='10', suit='diamonds', isup=0),
 Card(rank='J', suit='diamonds', isup=0),
 Card(rank='Q', suit='diamonds', isup=0),
 Card(rank='K', suit='diamonds', isup=0),
 Card(rank='A', suit='diamonds', isup=0),
 Card(rank='2', suit='clubs', isup=0),
 Card(rank='3', suit='clubs', isup=0),
 Card(rank='4', suit='clubs', isup=0),
 Card(rank='5', suit='clubs', isup=0),
 Card(rank='6', suit='clubs', isup=0),
 Card(rank='7', suit='clubs', isup=0),
 Card(rank='8', suit='clubs', isup=0),
 Card(rank='9', suit='clubs', isup=0),
 Card(rank='10', suit='clubs', isup=0),
 Card(rank='J', suit='clubs', isup=0),
 Card(rank='Q', suit='clubs', isup=0),
 Card(rank='K', suit='clubs', isup=0),
 Card(rank='A', suit='clubs', isup=0),
 Card(rank='2', suit='hearts', isup=0),
 Card(rank='3', suit='hearts', isup=0),
 Card(rank='4', suit='hearts', isup=0),
 Card(rank='5', suit='hearts', isup=0),
 Card(rank='6', suit='hearts', isup=0),
 Card(rank='7', suit='hearts', isup=0),
 Card(rank='8', suit='hearts', isup=0),
 Card(rank='9', suit='hearts', isup=0),
 Card(rank='10', suit='hearts', isup=0),
 Card(rank='J', suit='hearts', isup=0),
 Card(rank='Q', suit='hearts', isup=0),
 Card(rank='K', suit='hearts', isup=0),
 Card(rank='A', suit='hearts', isup=0)]

In [ ]:


In [8]:
print("first card = {}, last card = {}".format(deck[0],deck[-1]))


first card = Card(rank='2', suit='spades', isup=0), last card = Card(rank='A', suit='hearts', isup=0)

In [9]:
from random import choice
help(choice)
#chooses a random element from a non-empty sequence 
#(works with lists and tuples at least)
choice((1,2, 3))


Help on method choice in module random:

choice(seq) method of random.Random instance
    Choose a random element from a non-empty sequence.

Out[9]:
2

In [10]:
#deck._cards
choice(deck)


Out[10]:
Card(rank='Q', suit='hearts', isup=0)

In [11]:
#didn't have to memorize the method names:
choice(deck._cards)


Out[11]:
Card(rank='8', suit='diamonds', isup=0)

In [12]:
deck[12::13]#start on index 12, skip 13 at a time


Out[12]:
[Card(rank='A', suit='spades', isup=0),
 Card(rank='A', suit='diamonds', isup=0),
 Card(rank='A', suit='clubs', isup=0),
 Card(rank='A', suit='hearts', isup=0)]

In [50]:
#for card in reversed(deck):
#    print(card)

In [13]:
Card('Q', 'hearts',0) in deck


Out[13]:
True

In [17]:
Card('7', 'hearts',1) in deck


Out[17]:
False

In [18]:
suit_values = dict(spades=3, hearts=2, diamonds = 1, clubs=0)

In [19]:
suit_values


Out[19]:
{'clubs': 0, 'diamonds': 1, 'hearts': 2, 'spades': 3}

In [20]:
def spades_high(card):
    rank_value = FrenchDeck.ranks.index(card.rank)
    return rank_value*len(suit_values) + suit_values[card.suit]

In [ ]:


In [22]:
for card in sorted(deck, key=spades_high):
    print(card)


Card(rank='2', suit='clubs', isup=0)
Card(rank='2', suit='diamonds', isup=0)
Card(rank='2', suit='hearts', isup=0)
Card(rank='2', suit='spades', isup=0)
Card(rank='3', suit='clubs', isup=0)
Card(rank='3', suit='diamonds', isup=0)
Card(rank='3', suit='hearts', isup=0)
Card(rank='3', suit='spades', isup=0)
Card(rank='4', suit='clubs', isup=0)
Card(rank='4', suit='diamonds', isup=0)
Card(rank='4', suit='hearts', isup=0)
Card(rank='4', suit='spades', isup=0)
Card(rank='5', suit='clubs', isup=0)
Card(rank='5', suit='diamonds', isup=0)
Card(rank='5', suit='hearts', isup=0)
Card(rank='5', suit='spades', isup=0)
Card(rank='6', suit='clubs', isup=0)
Card(rank='6', suit='diamonds', isup=0)
Card(rank='6', suit='hearts', isup=0)
Card(rank='6', suit='spades', isup=0)
Card(rank='7', suit='clubs', isup=0)
Card(rank='7', suit='diamonds', isup=0)
Card(rank='7', suit='hearts', isup=0)
Card(rank='7', suit='spades', isup=0)
Card(rank='8', suit='clubs', isup=0)
Card(rank='8', suit='diamonds', isup=0)
Card(rank='8', suit='hearts', isup=0)
Card(rank='8', suit='spades', isup=0)
Card(rank='9', suit='clubs', isup=0)
Card(rank='9', suit='diamonds', isup=0)
Card(rank='9', suit='hearts', isup=0)
Card(rank='9', suit='spades', isup=0)
Card(rank='10', suit='clubs', isup=0)
Card(rank='10', suit='diamonds', isup=0)
Card(rank='10', suit='hearts', isup=0)
Card(rank='10', suit='spades', isup=0)
Card(rank='J', suit='clubs', isup=0)
Card(rank='J', suit='diamonds', isup=0)
Card(rank='J', suit='hearts', isup=0)
Card(rank='J', suit='spades', isup=0)
Card(rank='Q', suit='clubs', isup=0)
Card(rank='Q', suit='diamonds', isup=0)
Card(rank='Q', suit='hearts', isup=0)
Card(rank='Q', suit='spades', isup=0)
Card(rank='K', suit='clubs', isup=0)
Card(rank='K', suit='diamonds', isup=0)
Card(rank='K', suit='hearts', isup=0)
Card(rank='K', suit='spades', isup=0)
Card(rank='A', suit='clubs', isup=0)
Card(rank='A', suit='diamonds', isup=0)
Card(rank='A', suit='hearts', isup=0)
Card(rank='A', suit='spades', isup=0)

In [57]:
help(sorted)


Help on built-in function sorted in module builtins:

sorted(iterable, key=None, reverse=False)
    Return a new list containing all items from the iterable in ascending order.
    
    A custom key function can be supplied to customise the sort order, and the
    reverse flag can be set to request the result in descending order.


In [ ]:


In [ ]:


In [ ]:


In [ ]:


In [ ]: