As we look at the factory functions for creating Card objects, there are some alternative designs for the Card class. We might want to refactor the conversion of the rank number so that it is the responsibility of the Card class itself. This pushes the initialization down into each subclass.
This often requires some common initialization of a superclass as well as subclass-specific initialization. We need to follow the Don't Repeat Yourself (DRY) principle to keep the code from getting cloned into each of the subclasses.
This version of the Card3 class has an initializer at the superclass level that is used by each subclass, as shown in the following code snippet:
class Card3:
def __init__(
self, rank: str, suit: Suit, hard: int, soft: int
) -> None:
self.rank = rank
self.suit = suit
self.hard...