TheAlgorithms/Python · error · TypeError
Hand should be of type 'str': {hand!r}
Error message
Hand should be of type 'str': {hand!r} What it means
Raised by the PokerHand constructor in project_euler/problem_054/sol1.py when the hand argument is not a str. Hands are expected as a single string of five space-separated cards such as '6S 4C KC AS TH'; passing a list of cards, a tuple, or None triggers this TypeError before any parsing happens.
Source
Thrown at project_euler/problem_054/sol1.py:124
"""
Initialize hand.
Hand should of type str and should contain only five cards each
separated by a space.
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:
"""View on GitHub (pinned to f5988cc097)
Solutions
- Pass one space-separated string: PokerHand('6S 4C KC AS TH').
- Join list/tuple inputs: PokerHand(' '.join(cards)).
- Decode bytes before constructing: PokerHand(raw.decode()).
- Add a type guard or assert at the boundary where hands enter your pipeline.
Example fix
# before
hand = ['6S', '4C', 'KC', 'AS', 'TH']
p = PokerHand(hand) # TypeError
# after
p = PokerHand(' '.join(hand)) Defensive patterns
Strategy: type-guard
Validate before calling
if isinstance(cards, (list, tuple)):
hand = ' '.join(cards)
elif isinstance(hand_input, bytes):
hand = hand_input.decode()
else:
hand = hand_input
assert isinstance(hand, str)
PokerHand(hand) Type guard
def is_hand_string(value) -> bool:
return isinstance(value, str) Try / catch
try:
poker_hand = PokerHand(raw)
except TypeError:
poker_hand = PokerHand(' '.join(raw)) # retry with normalized input
except ValueError:
logger.error("malformed hand: %r", raw)
raise Prevention
- Keep hands as one space-separated string end-to-end in your pipeline.
- Join list-of-cards and decode bytes at the data-ingestion boundary.
- Add a type check in your loader so bad rows are logged with line numbers.
When it happens
Trigger: PokerHand(['6S','4C','KC','AS','TH']) (list instead of string), PokerHand(None), PokerHand(b'6S 4C') (bytes), or PokerHand(123). Any non-str type, even if it contains valid card text.
Common situations: Reading hands from CSV/pandas where a row splits into a list of fields; passing bytes from file reads without decode; refactoring from list-based to string-based API and missing a call site.
Related errors
- Parameter number must be int
- Parameters chain_length and number_limit must be int
- n must be an integer
- Hand should contain only 5 cards: {hand!r}
- check_bouncy() accepts only integer arguments
AI-assisted analysis of TheAlgorithms/Python@f5988cc097 (2026-08-14).
Data as JSON: /api/errors/30004b8bae5f2681.
Report an issue: GitHub.