Object Oriented Playing Cards in Python
Tags: python, oop
Published: 2019-06-13 15:58:30

---
title: Object Oriented Playing Cards in Python
published: true
tags: [Python, OOP]
canonical_url: https://warrenwong.org/object-oriented-playing-cards-in-python/
cover_image: https://warrenwong.org/static/09fbe04ef35e9d23532978431546cbb6/96726/michal-parzuchowski-453960-unsplash.jpg
---

[`enum`](https://docs.python.org/3/library/enum.html) became a part of the Python standard library starting in version 3.4 and I thought that the classic OOP playing cards example would be a good demonstration of it.

In this example, I'm not going to worry about the actual playing card values like in Poker (twos are more valuable than threes, spades are more valuable than hearts, etc.) since there are many games where cards may not conform to those values.

I'll first create the set of four `enum`s for the suite and the set of thirteen `enum`s for the card's face value. I'll also use `auto`, since I'm not going to worry about the exact value of the `enum`, though I'll list them in Poker value order and `auto` will automatically give me those values anyway.

```python
from enum import Enum, auto

class Suite(Enum):
    DIAMOND = auto()
    CLUB = auto()
    HEART = auto()
    SPADE = auto()

class Value(Enum):
    TWO = auto()
    THREE = auto()
    FOUR = auto()
    FIVE = auto()
    SIX = auto()
    SEVEN = auto()
    EIGHT = auto()
    NINE = auto()
    TEN = auto()
    JACK = auto()
    QUEEN = auto()
    KING = auto()
    ACE = auto()
```

Now I'll create the `Card` class with [getters and setters](https://warrenwong.org/using-getters-and-setters-in-python) so I can ensure the proper `enum`s are passed when initializing each card.

```python
class Card:
    def __init__ (self, suite: Suite, value: Value):
        self.suite = suite
        self.value = value

    @property
    def suite(self):
        return self._suite

    @property
    def value(self):
        return self._value

    @suite.setter
    def suite(self, suite: Suite):
        if suite not in Suite:
            raise Exception
        self._suite = suite

    @value.setter
    def value(self, value: Value):
        if value not in Value:
            raise Exception
        self._value = value

    def __repr__ (self):
        return f"<Card {self.value} of {self.suite}>"
```

If we try to initialize the `Card` with anything other than a valid `Suite` or `Value`, Python will raise an `Exception`.

Okay, now we can create a class for a deck of cards.

```python
class Deck:
    def __init__ (self):
        self.cards = [Card(s, v) for s in Suite for v in Value]

    def __repr__ (self):
        output = [f"{c}\n" for c in self.cards]
        return "".join(output)
```

Now, let's give this a try and see if everything is alright.

```
>>> from card import Suite, Value, Card, Deck
>>> deck = Deck()
>>> len(deck.cards)
52
>>> deck
<Card Value.TWO of Suite.DIAMOND>
<Card Value.THREE of Suite.DIAMOND>
<Card Value.FOUR of Suite.DIAMOND>
<Card Value.FIVE of Suite.DIAMOND>
<Card Value.SIX of Suite.DIAMOND>
<Card Value.SEVEN of Suite.DIAMOND>
<Card Value.EIGHT of Suite.DIAMOND>
<Card Value.NINE of Suite.DIAMOND>
<Card Value.TEN of Suite.DIAMOND>
<Card Value.JACK of Suite.DIAMOND>
<Card Value.QUEEN of Suite.DIAMOND>
<Card Value.KING of Suite.DIAMOND>
<Card Value.ACE of Suite.DIAMOND>
<Card Value.TWO of Suite.CLUB>
<Card Value.THREE of Suite.CLUB>
<Card Value.FOUR of Suite.CLUB>
<Card Value.FIVE of Suite.CLUB>
<Card Value.SIX of Suite.CLUB>
<Card Value.SEVEN of Suite.CLUB>
<Card Value.EIGHT of Suite.CLUB>
<Card Value.NINE of Suite.CLUB>
<Card Value.TEN of Suite.CLUB>
<Card Value.JACK of Suite.CLUB>
<Card Value.QUEEN of Suite.CLUB>
<Card Value.KING of Suite.CLUB>
<Card Value.ACE of Suite.CLUB>
<Card Value.TWO of Suite.HEART>
<Card Value.THREE of Suite.HEART>
<Card Value.FOUR of Suite.HEART>
<Card Value.FIVE of Suite.HEART>
<Card Value.SIX of Suite.HEART>
<Card Value.SEVEN of Suite.HEART>
<Card Value.EIGHT of Suite.HEART>
<Card Value.NINE of Suite.HEART>
<Card Value.TEN of Suite.HEART>
<Card Value.JACK of Suite.HEART>
<Card Value.QUEEN of Suite.HEART>
<Card Value.KING of Suite.HEART>
<Card Value.ACE of Suite.HEART>
<Card Value.TWO of Suite.SPADE>
<Card Value.THREE of Suite.SPADE>
<Card Value.FOUR of Suite.SPADE>
<Card Value.FIVE of Suite.SPADE>
<Card Value.SIX of Suite.SPADE>
<Card Value.SEVEN of Suite.SPADE>
<Card Value.EIGHT of Suite.SPADE>
<Card Value.NINE of Suite.SPADE>
<Card Value.TEN of Suite.SPADE>
<Card Value.JACK of Suite.SPADE>
<Card Value.QUEEN of Suite.SPADE>
<Card Value.KING of Suite.SPADE>
<Card Value.ACE of Suite.SPADE>
```