1
\$\begingroup\$

I wrote a card class a while back in this post here: Previous Question I know it has been a long time but I recently came back to the project and wrote it using an enum as suggested in the answer to increase readability and to make input less error prone. I've never really used enums in Python so the question is did I do it correctly or is there a better way to do it?

from enum import Enum

class Suit(Enum):
    CLUB, HEART, DIAMOND, SPADE = range(1, 5)

class Rank(Enum):
    TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN = range(2,11)
    JACK, QUEEN, KING, ACE = 'J', 'Q', 'K', 'A'

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
"""

    def __init__(self, suit, rank, in_deck = False):
        if suit in Suit and rank in Rank:
            self.suit = suit
            self.rank = rank
            self.suit_weight = suit.value
            self.rank_weight = rank.value
        else:
            self.suit = "Joker"
            self.rank = "J"
            self.suit_weight = 0
            self.rank_weight = 0
        self.in_deck = in_deck

    def __str__(self):
        """Returns abbreviated name of card

        Example: str(Card('Spades', 'A') outputs 'AS'
        """
        return str(self.rank.value) + str(self.suit.name[0])

    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 is_in_deck(self):
        """Return True if card is in a deck, else false"""
        return self.in_deck

    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
\$\endgroup\$
1
\$\begingroup\$

Python is not Java (or C++, or ...). There is no need to have a getter and setter for every attribute.

  • Instead of calling card.modify_weight(new_suit_weight=3), you can just do card.suit_weight = 3, so that method is not needed at all.
  • Instead of calling card.get_suit(), just use card.suit, so all those get_* methods are superfluous.

The rest looks fine to me, except for the closing part of the docstring of Card, those """ should be indented the same distance the opening """ are.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.