Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

card inheritance exercises #6

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 23 additions & 9 deletions src/card.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,36 @@
class Card:
# instance attributes
suit_names = ['Clubs', 'Diamonds', 'Hearts', 'Spades']
rank_names = [None, 'Ace', '2', '3', '4', '5', '6', '7',
'8', '9', '10', 'Jack', 'Queen', 'King']
"""Represents a standard playing card.

def __init__(self, suit=0, rank=2):
# defaults to a 2 of Clubs
Attributes:
suit: integer 0-3
rank: integer 1-13
"""

suit_names = ["Clubs", "Diamonds", "Hearts", "Spades"]
rank_names = [None, "Ace", "2", "3", "4", "5", "6", "7",
"8", "9", "10", "Jack", "Queen", "King"]

# class attributes
def __init__(self, suit=0, rank=2):
self.suit = suit
self.rank = rank

def __str__(self):
"""Returns a human-readable string representation."""
return '%s of %s' % (Card.rank_names[self.rank],
Card.suit_names[self.suit])

def __eq__(self, other):
"""Checks whether self and other have the same rank and suit.

returns: boolean
"""
return self.suit == other.suit and self.rank == other.rank

def __lt__(self, other):
# using tuple comparison
"""Compares this card to other, first by suit, then rank.

returns: boolean
"""
t1 = self.suit, self.rank
t2 = other.suit, other.rank
return t1 < t2
return t1 < t2
48 changes: 40 additions & 8 deletions src/deck.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,63 @@
from random import random

from src.card import Card

import random

class Deck:
"""Represents a deck of cards.

Attributes:
cards: list of Card objects.
"""

def __init__(self):
"""Initializes the Deck with 52 cards.
"""
self.cards = []
for suit in range(4):
for rank in range(1, 14):
card = Card(suit, rank)
self.cards.append(card)

def __str__(self):
"""Returns a string representation of the deck.
"""
res = []
for card in self.cards:
res.append(str(card))
return '\n'.join(res)

def pop_card(self):
return self.cards.pop()

def add_card(self, card):
"""Adds a card to the deck.

card: Card
"""
self.cards.append(card)

def remove_card(self, card):
"""Removes a card from the deck or raises exception if it is not there.

card: Card
"""
self.cards.remove(card)

def pop_card(self, i=-1):
"""Removes and returns a card from the deck.

i: index of the card to pop; by default, pops the last card.
"""
return self.cards.pop(i)

def shuffle(self):
"""Shuffles the cards in this deck."""
random.shuffle(self.cards)

def sort(self):
self.cards.sort()
"""Sorts the cards in ascending order."""
self.cards.sort()

def move_cards(self, hand, num):
"""Moves the given number of cards from the deck into the Hand.

hand: destination Hand object
num: integer number of cards to move
"""
for i in range(num):
hand.add_card(self.pop_card())
32 changes: 27 additions & 5 deletions src/hand.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,34 @@
from src.deck import Deck


class Hand(Deck):
"""Represents a hand of playing cards."""

def init__(self, label=''):
def __init__(self, label=''):
self.cards = []
self.label = label

def move_cards(self, hand, num):
for i in range(num):
hand.add_card(self.pop_card())

def find_defining_class(obj, method_name):
"""Finds and returns the class object that will provide
the definition of method_name (as a string) if it is
invoked on obj.

obj: any python object
method_name: string method name
"""
for ty in type(obj).mro():
if method_name in ty.__dict__:
return ty
return None


if __name__ == '__main__':
deck = Deck()
deck.shuffle()

hand = Hand()
print(find_defining_class(hand, 'shuffle'))

deck.move_cards(hand, 5)
hand.sort()
print(hand)
43 changes: 43 additions & 0 deletions src/poker_hand.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
from __future__ import print_function, division

from src.hand import Hand
from src.deck import Deck


class PokerHand(Hand):
"""Represents a poker hand."""

def suit_hist(self):
"""Builds a histogram of the suits that appear in the hand.

Stores the result in attribute suits.
"""
self.suits = {}
for card in self.cards:
self.suits[card.suit] = self.suits.get(card.suit, 0) + 1

def has_flush(self):
"""Returns True if the hand has a flush, False otherwise.

Note that this works correctly for hands with more than 5 cards.
"""
self.suit_hist()
for val in self.suits.values():
if val >= 5:
return True
return False


if __name__ == '__main__':
# make a deck
deck = Deck()
deck.shuffle()

# deal the cards and classify the hands
for i in range(7):
hand = PokerHand()
deck.move_cards(hand, 7)
hand.sort()
print(hand)
print(hand.has_flush())
print('')
Loading