I wrote classes to model a playing card, a deck, and a player to be used in multiple playing card games. I originally posted a
Card class here, and now extended the project by adding a deck and player class and am really looking for some feedback. This is my first real object oriented design project and I feel unsure about the current way the deck and player classes are implemented.
class Card(object): """Models a playing card, each Card object will have a suit, rank, and weight associated with each. possible_suits -- List of possible suits a card object can have possible_ranks -- List of possible ranks a card object can have Suit and rank weights are initialized by position in list. If card parameters are outside of expected values, card becomes joker with zero weight """ possible_suits = ["Clubs", "Hearts", "Diamonds", "Spades"] possible_ranks = [2, 3, 4, 5, 6, 7, 8, 9, 10, "J", "Q", "K", "A"] def __init__(self, suit, rank): if suit in Card.possible_suits and rank in Card.possible_ranks: self.suit = suit self.rank = rank self.suit_weight = Card.possible_suits.index(suit) self.rank_weight = Card.possible_ranks.index(rank) else: self.suit = "Joker" self.rank = "J" self.suit_weight = 0 self.rank_weight = 0 def __str__(self): """Returns abbreviated name of card Example: str(Card('Spades', 'A') outputs 'AS' """ return str(self.rank) + self.suit def __eq__(self, other): """Return True if cards are equal by suit and rank weight""" return self.suit_weight == other.suit_weight and self.rank_weight == other.rank_weight def __gt__(self, other): """Returns true if first card is greater than second card by weight""" if self.suit_weight > other.suit_weight: return True if self.suit_weight == other.suit_weight: if self.rank_weight > other.rank_weight: return True return False def modify_weight(self, new_suit_weight = None, new_rank_weight = None): """Modifies weight of card object""" if new_suit_weight: self.suit_weight = new_suit_weight if new_rank_weight: self.rank_weight = new_rank_weight def get_suit(self): return self.suit def get_rank(self): return self.rank def get_suit_weight(self): return self.suit_weight def get_rank_weight(self): return self.rank_weight from itertools import product from random import shuffle class Deck(object): """Models a deck of playing cards, each instance will be a list of 52 Card objects""" def __init__(self): self.cards = [Card(card, card) for card in product(Card.possible_suits, Card.possible_ranks)] def __str__(self): return str([str(card) for card in self.cards]) def length(self): return len(self.cards) def draw(self, end = None): """Return a card object or a set of card objects from the zeroth index of the deck, while removing it""" card = self.cards[0: end] del self.cards[0: end] return card def shuffle_deck(self): """Shuffle the deck of cards in place""" shuffle(self.cards) def get_suit(self, suit): """Return all cards of suit in the deck""" cards_of_suit =  for card in self.cards: if card.get_suit() == suit: cards_of_suit.append(card) if len(cards_of_suit) == 13: break return cards_of_suit def find(self, card_to_find): """Return position of card in deck, if card not in deck return None""" print(type(card_to_find), "; ", card_to_find) if card_to_find in self.cards: return self.cards.index(card_to_find) return None def remove(self, card_to_remove): """Remove a card from the deck""" position = self.find(card_to_remove) if position: del self.cards[position] class Player(object): """Models a Player in a playing card game, each instance will have an id, can be initialized with a hand of cards and can be initialized with a score """ def __init__(self, id, hand = None, score = None): self.id = id self.hand = hand self.score = score def __str__(self): return str(self.id) def set_hand(self, cards): """Append cards to hand""" self.hand = cards def find_card(self, card): """Finds a card in hand""" if card in self.hand: return self.hand.index(card) return None def play(self, card_to_be_played): """Return card_to_be_played from hand while removing it, return None if card not in hand""" position = self.find_card(card_to_be_played) if position: del self.hand[position] return card_to_be_played return None def update_score(self, update): """Updates the current score of the instance by adding the update""" self.score += update def get_hand(self): return [str(i) for i in self.hand] def get_score(self): return self.score