Define a class `PlayingCard`. Each card has a `suit` (one of `'clubs'`, `'diamonds'`, `'hearts'`, `'spades'`) and a `rank` (an integer from 2 to 14 inclusive, where 11 = Jack, 12 = Queen, 13 = King, 14 = Ace). The constructor signature is `__init__(self, suit: str, rank: int)`. It must raise `ValueError` for invalid suit or rank. Implement the following methods:
- `color` property: returns `'black'` for clubs/spades and `'red'` for diamonds/hearts.
- `name` property: returns a string like `'Ace of Spades'`, `'10 of Hearts'`, `'King of Diamonds'`, `'2 of Clubs'`. For ranks 2–10 use the integer as the name; for 11–14 use `'Jack'`, `'Queen'`, `'King'`, `'Ace'`.
- `__repr__`: returns the same as `name`.
- `__eq__`: two cards are equal if they have the same suit and rank.
- `__lt__` and `__le__`: order by rank first, then suit rank order: clubs=1, diamonds=2, hearts=3, spades=4 (ascending).
- `__gt__` and `__ge__`: inverse of the less-than operations.
Implement `__hash__` so that equal cards have the same hash (based on suit and rank).
Additionally, provide three top-level helper functions:
- `create_card(suit, rank)` that returns a dict with keys `'suit'`, `'rank'`, `'color'`, `'name'` from a valid PlayingCard.
- `invalid_suit(suit, rank)` that returns the string `'ValueError'` if constructing a PlayingCard with the given suit and rank raises a `ValueError`; otherwise it should raise an `AssertionError` (do not catch any other exceptions).
- `invalid_rank(suit, rank)` that returns the string `'ValueError'` if constructing a PlayingCard with the given suit and rank raises a `ValueError`; otherwise it should raise an `AssertionError` (do not catch any other exceptions).
Constraints
`suit` is a string; `rank` is an integer between 2 and 14 inclusive. Invalid inputs raise `ValueError`. All methods must be implemented without external libraries.
Example
>>> c = PlayingCard('spades', 14)
>>> c.color
'black'
>>> c.name
'Ace of Spades'
>>> d = PlayingCard('hearts', 14)
>>> c > d
True
>>> c == PlayingCard('spades', 14)
True
>>> len({c, d})
2
>>> create_card('spades', 14)
{'suit': 'spades', 'rank': 14, 'color': 'black', 'name': 'Ace of Spades'}
>>> invalid_suit('invalid', 5)
'ValueError'
>>> invalid_rank('hearts', 15)
'ValueError'
10 points
~15 min
Recent Submissions
No submissions yet — hit Run Tests to try!
Hints
Map suit names to a numeric order for comparisons.
Use a dictionary to map face ranks 11–14 to names.
Implement __eq__ and __lt__, then derive __le__, __gt__, __ge__.
For invalid_suit and invalid_rank, wrap PlayingCard construction in try/except ValueError.
Python 3
All tests passed!
Test Results
Press Ctrl+Enter or click Run Tests to execute your code.