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
- Normalize whitespace before constructing: PokerHand(' '.join(hand.split())).
- Validate card count upstream: assert len(hand.split()) == 5.
- Fix the data source (strip trailing newlines/spaces, correct column counts).
- 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
- Normalize whitespace with ' '.join(line.split()) before parsing.
- Strip trailing newlines when reading files line by line.
- Validate 5 tokens per row when loading batch data; skip-and-log bad rows.
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
- a gon ring should have a length that is a multiple of 3
- Parameter nth must be greater than or equal to one.
- n must be >= 0
- gon_side must be in the range [3, 5]
- Please enter an integer greater than 0
AI-assisted analysis of TheAlgorithms/Python@f5988cc097 (2026-08-14).
Data as JSON: /api/errors/33998cd470493485.
Report an issue: GitHub.