class CardValueException(Exception): """ Create a new exception class """ def __init__(self, value): """ Constructor : creates a new card value exception @param string Value to display """ self.value = str(value) def __str__(self): """ Display the error message """ return repr(self.value) class HandException(Exception): """ Create a new exception class """ def __init__(self, value): """ Constructor : creates a new hand exception @param string Value to display """ self.value = str(value) def __str__(self): """ Display the error message """ return repr(self.value) class Card(object): """ Definition of a card object """ ### static properties # card type headType = "Head" asType = "As" defaultType = "default" # associaative table assocStringType = { "As" : [ "A" ], "Head" : [ "K", "Q", "J" ], "default" : [ str(i) for i in reversed(range(10)) ] } #available values availableStringValues = ["A", "K", "Q", "J"] + assocStringType[defaultType] def __init__(self, valueString): """ Constructor : creates a new card following its string value @param string valueString @raise CardValueException if unexecpected string value is given """ self.__valueString = valueString self.__type = self.__defineCardType() self.__value = self.__defineCardValue() def __defineCardType(self): """ Using an associative table define if the card is either an head, an as or a normal card """ if not self.__valueString in Card.availableStringValues: raise CardValueException("This value doesn't exist, please check your code") for cardType in Card.assocStringType.keys(): if self.__valueString in Card.assocStringType[cardType]: return cardType def __defineCardValue(self): """ Following is string value define is numeric value A card could have more than one value, ie : As => 1 or 11 In this case the value will be a list, ie As [1, 11] Otherwise an integer """ if self.__type == Card.asType: return [1, 11] if self.__type == Card.headType: return 10 return int(self.__valueString) def getType(self): """ Returns the card type """ return self.__type def getValue(self): """ Returns the card type """ return self.__value def getValueString(self): """ Returns the card type """ return self.__valueString class Hand(object): """ Definition of a hand object """ def __init__(self): """ Constructror : creates a new empty hand """ self.__cards = [] def addCard(self, card): """ Appends a card to hand @param Card A Card instance """ if type(card) != Card: raise HandException("You try to append an unexecpected object, the object a Card instance") self.__cards.append(card) def addCards(self, *args): """ Append a bunch of cards to hand """ for card in args: self.addCard(card) def addUp(self): """ Returns the sum of all card value if there are some as cards in the hand returns a list of total """ #retrieve as cards contents by the hand indexAsCards = [ self.__cards.index(card) for card in self.__cards if card.getType() == Card.asType ] if len(indexAsCards): indexAsCards = indexAsCards[0] for asValue in self.__cards[indexAsCards].getValue(): yield asValue + sum( [card.getValue() for index,card in enumerate(self.__cards) if index != indexAsCards ] ) return yield sum( [card.getValue() for card in self.__cards ]) def detectCouples(self): """ Retrieve the list of coupled cards """ cards = [ card.getValueString() for card in self.__cards ] return dict((x,cards.count(x)) for x in set(cards)) hand = Hand() hand.addCards(Card('3'), Card('2'), Card('4'), Card('3')) for val in hand.addUp(): print val print hand.detectCouples()