import collections

Card = collections.namedtuple('Card', ['rank', 'suit']) #'Card' 是 namedtuple 名字,　后面是元素

class FrenchDeck:
    ranks = [str(n) for n in range(2, 11)] + list('JQKA')
    suits = 'spades diamonds clubs hearts'.split() # 黑桃 钻石 梅花 红心
    
    def __init__(self):
        self._cards = [Card(rank, suit) for suit in self.suits
                                        for rank in self.ranks]
        
    def __len__(self):
        return len(self._cards)
    
    def __getitem__(self, position): #代表了 self._cards 的 []运算符
        return self._cards[position]


beer_card = Card('7', 'diamonds')
beer_card

deck = FrenchDeck()
len(deck)  #默认调用了 __len__()

deck[0]  #调用了 __getitem__()

deck[-1]

from random import choice
choice(deck)

deck[:3] #因为 __getitem__() 方法把 [] 操作交给 slef._cards 列表，我们的 desk 自动支持切片操作

deck[12::13]

"""
Explanation: __getitem__  AND  __len__ 方法
下面看一个生成扑克牌以及对其进行操作的例子
End of explanation
"""


# 我们只要写了 __getitem__() 方法，就可以将类变成可迭代的
for card in deck[:10]:
    print(card)

# 也可以反向迭代
for card in reversed(deck):
    print(card)

"""
Explanation: 迭代
End of explanation
"""


Card('Q', 'hearts') in deck

Card('Q', 'beasts') in deck

"""
Explanation: in 运算符
迭代通常是隐式的，如果集合中没有 __contains__　方法， in 操作符就会按顺序进行一次迭代搜索，于是 in 可以在 FrenchDeck 类中使用，因为它是可迭代的
End of explanation
"""


suit_values = dict(spades = 3, hearts = 2, diamonds = 1, clubs = 0)
suit_values

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

for card in sorted(deck, key=spades_high):
    print(card)

"""
Explanation: 排序
扑克牌一般按照数字大小（ Ａ 最大）来排列，花色按照黑桃（最大），红心，方块，梅花（最小）来排序，我们实现一下此功能
End of explanation
"""


