Skip to content

Instantly share code, notes, and snippets.

@kracekumar
Created December 8, 2025 10:33
Show Gist options
  • Select an option

  • Save kracekumar/c75ef68e7bab21bc7e6a1195ac39ce53 to your computer and use it in GitHub Desktop.

Select an option

Save kracekumar/c75ef68e7bab21bc7e6a1195ac39ce53 to your computer and use it in GitHub Desktop.
Make a data structure for a deck of cards, and implement a `shuffle()` method, and a `draw(n)` method (where you draw `n` cards). Calling `draw()` when the deck is empty returns an empty array.
"""
Make a data structure for a deck of cards,
and implement a `shuffle()` method, and a `draw(n)` method (where you draw `n` cards).
Calling `draw()` when the deck is empty returns an empty array.
URL: https://buttondown.com/cassidoo/archive/dont-watch-the-clock-do-what-it-does-keep-going
"""
VALID_SUITS = ['♠', '♥', '♣', '♦']
VALID_SYMBOLS = ['A', 'K', 'J', 'Q']
import random
class Card:
def __init__(self, rank: int | str, suit: str) -> None:
self.rank: str = self.valid_rank(rank)
self.suit: str = self.valid_suit(suit)
def valid_rank(self, rank: int | str) -> str:
raise_error: bool = False
if isinstance(rank, int):
if not (rank >= 1 and rank <= 10):
raise_error = True
elif rank not in VALID_SYMBOLS:
raise_error = True
else:
raise_error = False
if raise_error:
raise ValueError(f"Rank is invalid. Valid values are : 1 to 10 OR VALID_SYMBOLS")
return str(rank)
def valid_suit(self, suit: str) -> str:
if suit not in VALID_SUITS:
raise ValueError(f'{suit} is not valid suit. Values: {VALID_SUITS}')
return suit
def __repr__(self) -> str:
return f"{self.rank}{self.suit}"
class Deck:
def __init__(self) -> None:
self.cards: list[Card] = [
Card(rank=rank, suit=suit) for suit in VALID_SUITS for rank in range(1, 11)
]
self.cards += [Card(rank=rank, suit=suit) for suit in VALID_SUITS for rank in VALID_SYMBOLS]
def draw(self, count: int) -> list[Card] | list:
if count < 0 or count > 52:
raise ValueError(f"count should be from 1 to 52. Passed value: {count}")
if count > len(self.cards):
raise ValueError(f"Cannot draw {count} cards. Only {len(self.cards)} remaining.")
if count == 0 and len(self.cards) == 0:
# Sepcial Case to allow empty draw
return []
drawn_cards = self.cards[:count]
self.cards = self.cards[count:]
return drawn_cards
def shuffle(self) -> None:
random.shuffle(self.cards)
if __name__ == "__main__":
deck: Deck = Deck()
deck.shuffle()
draw: list[Card] = deck.draw(5)
print(draw)
assert(len(draw) == 5)
draw = deck.draw(2)
print(draw)
assert(len(draw) == 2)
while len(deck.cards) >= 5:
print(deck.draw(5))
print(f"Remaining cards {deck.cards}")
try:
print(deck.draw(4))
print(f"Empty Draw: {deck.draw(0)}")
except ValueError as e:
print(e)
[A♠, K♣, 4♦, J♦, K♠]
[8♣, 4♠]
[5♥, 3♣, 2♦, 7♠, 9♥]
[A♦, 5♣, A♣, 6♣, Q♠]
[7♥, 1♦, J♠, 1♥, 7♦]
[7♣, Q♦, 1♣, 9♦, 1♠]
[K♦, 6♥, 6♠, 9♣, 3♥]
[6♦, 10♠, 4♥, 3♠, Q♣]
[9♠, 8♥, 2♥, 8♦, 8♠]
[4♣, 2♠, 5♠, 10♣, 10♥]
[K♥, 5♦, 10♦, 3♦, J♣]
Remaining cards [A♥, 2♣, J♥, Q♥]
[A♥, 2♣, J♥, Q♥]
Empty Draw: []
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment