This assignment requires familiarity with the lecture materials presented in class through week 05.
There are many variants game of poker, most of which involve hands consisting of five cards from a standard 52-card deck. Hands are ranked by category, e.g. straight or two pair.
For the purposes of this assignment, a card descriptor shall be a two-character string consisting of the rank and suit of a card.
Rank characters | 23456789TJQKA |
---|---|
Suit characters | ♠♣♥♦ |
Here are ten example card descriptors: T♦ Q♦ 7♥ 3♦ K♠ 2♠ J♣ 2♣ K♥ 2♥
You shall define a class named PokerHand
in a module named poker_hand
. PokerHand
instances represent five-card poker hands and support various Python operators for easy interaction with the language, as demonstrated briefly in the REPL session below:
>>> h1 = PokerHand(['4♠', '9♠', '2♣', '2♦', '9♥']) >>> h1.describe() 'two pair' >>> int(h1) 2 >>> h2 = PokerHand(['3♠', '3♣', '2♠', 'Q♣', '3♦']) >>> h2.describe() 'three of a kind' >>> int(h2) 3 >>> h1 < h2 True >>> PokerHand(['2♠', '5♠', 'A♥', '4♥', '3♦']) < PokerHand(['Q♠', 'J♠', 'K♣', 'A♠', 'T♥']) True
Define your class with the starter code below, and fill in code for the methods as specified by the docstrings and doctests. Feel free to add other internal-only attributes (module-scoped variables, helper methods, etc.) in order to reduce redundant code.
""" Classifying and ranking poker hands. Numeric ranks and rank descriptions are as follows: 0: high card 1: one pair 2: two pair 3: three of a kind 4: straight 5: flush 6: full house 7: four of a kind 8: straight flush 9: royal flush """ from __future__ import annotations # for self-referential type hints from collections.abc import Sequence # for type hints class PokerHand: """ Represents a hand of cards for 5-card poker. Card descriptors are two-character strings (RS: Rank and Suit). Valid ranks: 23456789TJQKA Valid suits: ♥♠♦♣ """ def __init__(self, cards: Sequence[str]): """ Initializes a poker hand from a sequence of card descriptors. >>> h = PokerHand(('6♦', 'J♦', '8♣', '4♦', 'T♣')) >>> int(h) 0 >>> h.describe() 'high card' >>> h2 = PokerHand('6♣ 2♣ 7♣ 5♣ 3♣'.split()) >>> int(h2) 5 >>> h2.describe() 'flush' >>> h < h2 True """ pass def __contains__(self, descriptor): """ Determines whether this hand contains the given descriptor. >>> '2♠' in PokerHand(['3♠', '3♣', '2♠', 'Q♣', '3♦']) True >>> 'Q♦' in PokerHand(['3♠', '3♣', '2♠', 'Q♣', '3♦']) False """ pass def __int__(self): """ Returns the integer rank for this hand (0 through 9—see class docstring). >>> hands = ['T♥ A♠ 2♦ 9♣ J♣', ... 'T♦ 6♦ 2♠ J♠ T♥', ... '6♣ 5♥ 8♠ 5♠ 6♥', ... '9♠ 9♦ Q♥ 9♥ A♥', ... '7♦ 4♠ 5♦ 6♦ 8♣', ... '5♠ T♠ J♠ 3♠ 2♠', ... 'Q♣ 7♣ 7♥ Q♠ Q♦', ... '4♥ 5♣ 5♥ 5♦ 5♠', ... '5♣ 4♣ 8♣ 6♣ 7♣', ... 'A♣ J♣ T♣ Q♣ K♣'] >>> list(map(int, [PokerHand(h.split()) for h in hands])) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] """ pass def __lt__(self, other: PokerHand): """Compares this hand with another by rank.""" pass def __le__(self, other: PokerHand): """Compares this hand with another by rank.""" pass def __gt__(self, other: PokerHand): """Compares this hand with another by rank.""" pass def __ge__(self, other: PokerHand): """Compares this hand with another by rank.""" pass def __eq__(self, other: PokerHand): """Compares this hand with another by rank.""" pass def __ne__(self, other: PokerHand): """Compares this hand with another by rank.""" pass def __repr__(self): """Returns a printable representation of this hand, suitable for eval().""" pass def __str__(self): """ Returns the nicely printable string representation of this hand: 'C1 C2 C3 C4 C5 (rank description)' >>> h = PokerHand(['7♦', '4♠', '5♦', '6♦', '8♣']) >>> print(h) 7♦ 4♠ 5♦ 6♦ 8♣ (straight) """ pass def describe(self) -> str: """ Returns the description of this hand's rank (see class docstring). >>> hands = ['T♥ A♠ 2♦ 9♣ J♣', ... 'T♦ 6♦ 2♠ J♠ T♥', ... '6♣ 5♥ 8♠ 5♠ 6♥', ... '9♠ 9♦ Q♥ 9♥ A♥', ... '7♦ 4♠ 5♦ 6♦ 8♣', ... '5♠ T♠ J♠ 3♠ 2♠', ... 'Q♣ 7♣ 7♥ Q♠ Q♦', ... '4♥ 5♣ 5♥ 5♦ 5♠', ... '5♣ 4♣ 8♣ 6♣ 7♣', ... 'A♣ J♣ T♣ Q♣ K♣'] >>> list(map(PokerHand.describe, [PokerHand(h.split()) for h in hands])) ['high card', 'one pair', 'two pair', 'three of a kind', 'straight', 'flush', 'full house', 'four of a kind', 'straight flush', 'royal flush'] """ pass
File /srv/datasets/poker_hands
contains descriptions and rankings of 1 million sample poker hands, e.g. here are 10 randomly selected lines:
J♦ 2♥ 2♦ 5♠ 9♣ 1 4♦ 8♠ 7♥ 3♣ 4♠ 1 Q♦ 2♠ 7♣ T♠ 4♦ 0 9♠ 3♦ 9♥ 3♥ 7♥ 2 2♥ 5♦ 5♠ 6♥ 2♦ 2 A♣ 4♠ 5♠ 2♦ J♦ 0 3♥ 2♥ 3♣ 3♦ A♠ 3 T♦ 4♠ 4♥ T♥ T♠ 6 4♣ 2♥ A♣ 5♦ A♥ 1 9♠ T♥ 5♦ 2♠ Q♠ 0
If you need some sample hands with a given rank to test/work with, you could either pull them out in a Python script of your own, or use the interpreter as follows with the -c
option to quickly isolate the hands you'd like and print them as lists of strings, e.g. to get all straight flush (rank 8) hands in the file:
% python -c 'import sys; print("\n".join(str(t[:-1]) for l in sys.stdin if (t := l.split())[-1] == "8"))' </srv/datasets/poker_hands ['5♣', '4♣', '8♣', '6♣', '7♣'] ['T♠', 'J♠', '9♠', '7♠', '8♠'] ['4♦', '5♦', '3♦', 'A♦', '2♦'] ['7♠', '6♠', '4♠', '5♠', '8♠'] ['8♠', '7♠', '5♠', '6♠', '4♠'] ['J♣', '7♣', '9♣', 'T♣', '8♣'] ['Q♠', 'J♠', 'K♠', '9♠', 'T♠'] ['8♥', '7♥', 'J♥', 'T♥', '9♥'] ['K♦', 'J♦', 'Q♦', 'T♦', '9♦'] ['7♥', '3♥', '6♥', '5♥', '4♥'] ['8♥', '7♥', '9♥', '5♥', '6♥'] ['T♣', 'Q♣', '9♣', 'J♣', 'K♣']
Or to get 5 randomly selected three-of-a-kind (rank 3) hands:
% python -c 'import sys; print("\n".join(str(t[:-1]) for l in sys.stdin if (t := l.split())[-1] == "3"))' </srv/datasets/poker_hands | shuf -n 5 ['K♠', 'K♥', 'K♦', 'A♣', '5♦'] ['K♠', 'J♦', 'K♥', 'K♣', '9♠'] ['6♦', 'J♣', '3♦', '6♠', '6♣'] ['3♦', '3♠', 'T♠', '6♥', '3♣'] ['T♥', '6♥', 'T♠', '4♦', 'T♦']
Submit poker_hand.py
via turnin.
Feedback Robot
This project has a feedback robot that will run some tests on your submission and provide you with a feedback report via email within roughly one minute.
Please read the feedback carefully.
Due at 23:59:59 on the date listed on the syllabus.
Assignment 05
is worth 60 points.
Possible point values per category: --------------------------------------- Hand comparison methods 36 Other methods 24 Possible deductions: Style and practices 10–20% Possible extra credit: Submission via Git 5% ---------------------------------------