TheAlgorithms/Python · error · ValueError

Hand should contain only 5 cards: {hand!r}

Error message

Hand should contain only 5 cards: {hand!r}

What it means

Raised by the PokerHand constructor in project_euler/problem_054/sol1.py when hand.split(' ') does not yield exactly 5 tokens. The parser expects exactly five two-character cards separated by single spaces; 4 or 6 cards, trailing spaces, or tab/multiple-space separators all change the token count and trigger this ValueError.

Source

Thrown at project_euler/problem_054/sol1.py:128

        The cards should be of the following format:
        [card value][card suit]

        The first character is the value of the card:
        2, 3, 4, 5, 6, 7, 8, 9, T(en), J(ack), Q(ueen), K(ing), A(ce)

        The second character represents the suit:
        S(pades), H(earts), D(iamonds), C(lubs)

        For example: "6S 4C KC AS TH"
        """
        if not isinstance(hand, str):
            msg = f"Hand should be of type 'str': {hand!r}"
            raise TypeError(msg)
        # split removes duplicate whitespaces so no need of strip
        if len(hand.split(" ")) != 5:
            msg = f"Hand should contain only 5 cards: {hand!r}"
            raise ValueError(msg)
        self._hand = hand
        self._first_pair = 0
        self._second_pair = 0
        self._card_values, self._card_suit = self._internal_state()
        self._hand_type = self._get_hand_type()
        self._high_card = self._card_values[0]

    @property
    def hand(self):
        """Returns the self hand"""
        return self._hand

    def compare_with(self, other: PokerHand) -> str:
        """
        Determines the outcome of comparing self hand with other hand.
        Returns the output as 'Win', 'Loss', 'Tie' according to the rules of
        Texas Hold'em.

View on GitHub (pinned to f5988cc097)

Solutions

  1. Normalize whitespace before constructing: PokerHand(' '.join(hand.split())).
  2. Validate card count upstream: assert len(hand.split()) == 5.
  3. Fix the data source (strip trailing newlines/spaces, correct column counts).
  4. Log the offending line to find malformed rows in batch processing.

Example fix

# before
raw = '6S 4C KC AS TH '\n p = PokerHand(raw)  # ValueError: 6 tokens from trailing space

# after
p = PokerHand(' '.join(raw.split()))
Defensive patterns

Strategy: validation

Validate before calling

tokens = ' '.join(raw_line.split()).split(' ')
if len(tokens) != 5:
    raise ValueError(f"expected 5 cards, got {len(tokens)}: {raw_line!r}")
hand = PokerHand(' '.join(tokens))

Type guard

def is_five_card_hand(line: str) -> bool:
    return isinstance(line, str) and len(line.split()) == 5

Try / catch

try:
    hand = PokerHand(line)
except ValueError as e:
    logger.warning("skipping malformed line %r: %s", line, e)
    continue

Prevention

When it happens

Trigger: PokerHand('6S 4C KC AS') (4 cards), PokerHand('6S 4C KC AS TH 2D') (6 cards), PokerHand('6S 4C KC AS TH ') (trailing space -> 6 tokens), or tab-separated input like '6S\t4C\tKC\tAS\tTH' (split on ' ' yields 1 token).

Common situations: Dirty data files with trailing whitespace or double spaces; lines from the classic p054_poker.txt split incorrectly; CSV rows where a field was dropped or extra column added.

Related errors


AI-assisted analysis of TheAlgorithms/Python@f5988cc097 (2026-08-14). Data as JSON: /api/errors/33998cd470493485. Report an issue: GitHub.