from jutge import read, read_many

class Card:
    """Represents a standard playing card.
    
    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']

    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 __lt__(self, other):
        """Compares this card to other, first by suit, then rank.

        returns: bool
        """
        t1 = self.suit, self.rank
        t2 = other.suit, other.rank
        return t1 < t2

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

    Attributes:
      cards: list of Card objects.
    """
    
    def __init__(self):
        """Initializes the Deck with 52 cards."""
        self.cards = list()
        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 = list()
        for card in self.cards:
            res.append(str(card))
        return '\n'.join(res)

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

        card: Card
        """
        self.cards.append(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 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())

    def read_cards(self):
        """Reads a deck of cards."""
        for _ in range(len(self.cards)):
            self.pop_card()
        for rank, _, suit in read_many(str, str, str):
            suit = Card.suit_names.index(suit)
            rank = Card.rank_names.index(rank)
            card = Card(suit, rank)
            self.add_card(card)

    def deal_hands(self, num_hands=2, num_cards=5):
        """Deals hands from the deck and returns Hand objects.

        num_hands: number of hands
        num_cards: number of cards per hand

        returns: list of Hand objects
        """
        hands = list()
        for i in range(num_hands):
            hand = Hand()
            self.move_cards(hand, num_cards)
            hands.append(hand)
        return hands

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

    def __init__(self, label=''):
        self.cards = list()
        self.label = label

class PokerDeck(Deck):
    """Represents a deck of cards that can deal Poker hands."""

    def deal_hands(self, num_hands=2, num_cards=5):
        """Deals hands from the deck and returns PokerHand objects.

        num_hands: number of hands
        num_cards: number of cards per hand

        returns: list of PokerHand objects
        """
        hands = list()
        for i in range(num_hands):
            hand = PokerHand()
            self.move_cards(hand, num_cards)
            hands.append(hand)
        return hands

class PokerHand(Hand):
# ...

num_hands = read(int)
num_cards = read(int)
deck = PokerDeck()
deck.read_cards()
for hand in deck.deal_hands(num_hands, num_cards):
    print(hand)
    print()
    hand.make_dictionaries()
    print('One pair:', hand.has_one_pair())
    print('Two pair:', hand.has_two_pair())
    print('Three of a kind:', hand.has_three_of_a_kind())
    print('Straight:', hand.has_straight())
    print('Flush:', hand.has_flush())
    print('Full house:', hand.has_full_house())
    print('Four of a kind:', hand.has_four_of_a_kind())
    print('Straight flush:', hand.has_straightflush())
    print()

