Python Forum
why don't i get the answer i want
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
why don't i get the answer i want
#9
My ace is high. Is easy to make if low. Tougher to make it both.

But not a lot tougher.
import random
import collections
 
card_suits = ['Clubs', 'Diamonds', 'Hearts', 'Spades']
card_ranks = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']
straights = [set(card_ranks[i:i+5]) for i in range(len(card_ranks)-4)] + [{'A', '2', '3', '4', '5'}]
 
class Grouper(dict):
    '''Similar to a Counter, but instead of increasing a counter I append to a value list'''
    def __init__(self, items=[]):
        super().__init__()
        for item in items:
            self[item[0]] = item[1]

    def __setitem__(self, key, value):
        group = self.get(key, [])
        group.append(value)
        super().__setitem__(key, group)
 
    def most_common(self):
        '''Return items sorted in decreasing order by count'''
        items = list(super().items())
        items.sort(key=lambda item: len(item[1]), reverse=True)
        return items
 
class Card():
    '''A playing card.  Has a suite and a rank'''
    def __init__(self, rank, suit):
        self.suit = suit
        self.rank = rank
        self.value = card_ranks.index(rank) + 2
        self.name = f'{rank} {suit}'
        self.abbr = f'{rank}{suit[0]}'
 
    def __eq__(self, other):
        '''Return True if self has same value as other'''
        return self.value == other.value
 
    def __lt__(self, other):
        '''Return True if self has lower value than other.  Used for sorting'''
        return self.value < other.value
 
    def __hash__(self):
        '''Use value as the hash value.  Allows using sets to remove duplicate
        ranks.  Not sure if this is a good idea as it means Cards cannot be used
        as keys in dictionaries.
        '''
        return self.value
 
    def __repr__(self):
        '''Return nice string representation for card'''
        return self.name
 
class Hand(list):
    '''A list of cards that knows a little bit about poker'''
    def __init__(self, cards=None):
        self.cards = [] if cards is None else cards.copy()
 
    def deal(self, deck, count):
        '''Deal count cards from deck into hand'''
        for _ in range(count):
            self.cards.append(deck.pop())
        return self
 
    def __getitem__(self, index):
        '''Return card[index]'''
        return self.cards[index]
 
    def append(self, card):
        '''Append card to self.cards'''
        self.cards.append(card)
 
    def __len__(self):
        '''Return number of cards in hand'''
        return len(self.cards)
 
    def __add__(self, other):
        '''Make a new hand containing all cards from self and other'''
        return Hand(self.cards + other.cards)
 
    def __repr__(self):
        '''Make a pretty string rep of a hand'''
        return f"{{{', '.join([card.abbr for card in self.cards])}}}"
 
    def group_by_rank(self):
        """Return list of cards grouped by rank.  Groups are sorted by count in decreasing order"""
        return Grouper([(card.rank, card) for card in self.cards]).most_common()
 
    def group_by_suit(self):
        """Return list of cards grouped by suit.  Groups are sorted by count in decreasing order"""
        return Grouper([(card.suit, card) for card in self.cards]).most_common()
 
    def full_house(self):
        '''Return full-house if hand contains 3 of one rank and 2 of another'''
        ranks = self.group_by_rank()
        if len(ranks[0][1]) >= 3 and len(ranks[1][1]) >= 2:
            return ranks[0][1] + ranks[1][1]
        return None
 
    def two_pair(self):
        '''Return pairs if there are two pairs of matching ranks'''
        ranks = self.group_by_rank()
        if len(ranks[0][1]) >= 2 and len(ranks[1][1]) >= 2:
            return ranks[0][1] + ranks[1][1]
        return None
 
    def royal_flush(self):
        "Return cards if 10 through Ace if all in same suit"
        flush = self.straight_flush()
        if flush and flush[-1].rank == 'A':
            return flush
        return None
 
    def straight_flush(self):
        '''Return matching cards if straight is also a flush'''
        flush = self.flush()
        if flush:
            return Hand(flush).straight()
        return None
 
    def flush(self):
        '''Return matching cards if 5 or more cards have same suit'''
        suits = self.group_by_suit()
        if len(suits[0][1]) >= 5:
            return suits[0][1]
        return False
 
    def straight(self):
        '''Return matching cards if hand is superset of a straight set'''
        cards = set(self.cards)
        ranks = set([card.rank for card in cards])
        for straight in straights:
            if straight & ranks == straight:
                return [card for card in cards if card.rank in straight]
        return None

results = {}
 
def print_result(key, hand):
    print(key, hand)
    results[key] = results.get(key, 0) + 1
 
for _ in range(1000):
    deck = [Card(r, s) for s in card_suits for r in card_ranks]
    random.shuffle(deck)
    table = Hand().deal(deck, 5)
    hand = Hand().deal(deck, 2)
    both = table + hand
 
    of_a_kind = both.group_by_rank()
 
    if cards := both.royal_flush():
        print_result('Royal Flush', cards)
    elif cards := both.straight_flush():
        print_result('Straight Flush', cards)
    elif len(of_a_kind[0][1]) > 3:
        print_result('Four of a kind', of_a_kind[0][1])
    elif cards := both.full_house():
        print_result('Full House', cards)
    elif cards := both.flush():
        print_result('Flush', cards)
    elif cards := both.straight():
        print_result('Straight', cards)
    elif len(of_a_kind[0][1]) > 2:
        print_result('Three of a kind', of_a_kind[0][1])
 
print(results)
Reply


Messages In This Thread
why don't i get the answer i want - by CompleteNewb - Sep-02-2021, 10:59 PM
RE: why don't i get the answer i want - by deanhystad - Sep-03-2021, 08:38 AM

Possibly Related Threads…
Thread Author Replies Views Last Post
  I am getting the wrong answer, and not sure why riskeay 3 2,093 Nov-05-2020, 08:24 PM
Last Post: deanhystad
  Make the answer of input int and str enderfran2006 2 2,054 Oct-12-2020, 09:44 AM
Last Post: DeaD_EyE
  Keeps looping even after correct answer mcesmcsc 2 1,966 Dec-12-2019, 04:27 PM
Last Post: mcesmcsc
  I'm getting a wrong answer don't know where the bug is 357mag 4 2,872 Jul-07-2019, 11:21 PM
Last Post: DeaD_EyE
  How to answer subprocess prompt Monty 8 17,528 Feb-14-2018, 09:59 AM
Last Post: wavic

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020