from  abc import  ABCMeta,  abstractmethod
from  enum import  Enum
import  sysclass  Suit ( Enum) : HEART =  0 DIAMOND =  1 CLUBS =  2 SPADE =  3 class  Card ( metaclass= ABCMeta) : def  __init__ ( self,  value,  suit) : self. value =  valueself. suit =  suitself. is_available =  true@property @abstractmethod def  value ( self) : pass @value. setter @abstractmethod def  value ( self,  other) : pass class  BlackJackCard ( Card) : def  __init__ ( self,  value,  suit) : super ( BlackJackCard,  self) . __init__( value,  suit) def  is_ace ( self) : '''Jack =11, Queen = 12, King = 13''' return  10  <  self. _value <=  13 @preoperty def  value ( self) : if  self. is_ace( )  ==  1 : return  1 elif  self. is_face_card( ) : return  10 else : return  self. _value@value. setter def  value ( self,  new_value) : if  1  <=  new_value <=  13 : self. _value =  new_valueelse : raise  ValueError( 'Invalid card value: {}' . format ( new_value) ) class  Hand ( object ) : def  __init__ ( self,  cards) : self. cards =  cardsdef  add_card ( self,  card) : self. cards. append( card) def  score ( self) : total_value =  0 for  card in  self. cards: total_value +=  card. valuereturn  total_valueclass  BlackJackHand ( Hand) : BLACKJACK =  21 def  __init__ ( self,  cards) : min_over =  sys. MAXSIZEmax_under =  - sys. MAXSIZEfor  score in  self. possible_scores( ) : if  self. BLACKJACK <  score <  min_over: min_over =  scoreelif  max_under <  score <=  self. BLACKJACK: max_under =  scorereturn  max_under if  max_under !=  - sys. MAXSIZE else  min_overdef  possible_scores ( self) : '''Return a list of possible scores, taking aces into account''' class  Deck ( oject) : def  __init__ ( self, card) : self. cards =  cardsself. deal_index =  0 def  remaining_cards ( self) : return  len ( self. cards)  -  deal_indexdef  deal_card ( ) : try : card =  self. card[ self. deal_index] card. is_available =  False self. deal_index +=  1 except  IndexError: return  None return  carddef  shuffle ( self) :