In [6]:
class StatsList:
    """
    Stores a list of number snad provides some simple
    statistics
    """
    lst: list[float]
    sum: float
    product: float
    min: float
    max: float
    
    def __init__(self) -> None:
        self.lst = []
        self.sum = 0.0
        self.product = 1.0
        self.min = 0.0
        self.max = 0.0
        
    def append(self, val: float) -> None:
        self.lst.append(val)
        self.sum += val
        self.product *= val
        
        if len(self.lst) == 1:
            self.min = val
            self.max = val
        
        if val < self.min:
            self.min = val
        if val > self.max:
            self.max = val
            
    # if your statslist has other methods from class that is okay! Only the rebuild_invariants is 
    # part of this solution
    
    def rebuild_invariants(self) -> None:
        self.sum = 0.0
        self.product = 1.0
        for num in self.lst:
            self.sum += num
            self.product *= num
        self.max = max(self.lst)
        self.min = min(self.lst)

sl = StatsList()
sl.append(2.0)
sl.append(3.0)
# Oops – this line bypasses the invariants:
sl.lst.append(10.0)
print([f"Sum = {sl.sum}", f"Product = {sl.product}",  f"Min = {sl.min}",  f"Max = {sl.max}"])
sl.rebuild_invariants()
print([f"Sum = {sl.sum}", f"Product = {sl.product}",  f"Min = {sl.min}",  f"Max = {sl.max}"])
['Sum = 5.0', 'Product = 6.0', 'Min = 2.0', 'Max = 3.0']
['Sum = 15.0', 'Product = 60.0', 'Min = 2.0', 'Max = 10.0']
In [8]:
# cards class
class Card:
    """Stores information about a card"""
    value: str
    suit: str

    def __init__(self, value:str, suit:str) -> None:
        self.value = value
        self.suit = suit
        
    def __repr__(self) -> str:
        return f"{self.value} of {self.suit}"
    
    def __eq__(self, other) -> bool:
        return self.value == other.value
    
    def compare(self, other) -> bool:
        vals = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
        self_val = 0
        other_val = 0
        for i in range(len(vals)):
            if self.value == vals[i]:
                self_val = i
            if other.value == vals[i]:
                other_val = i
        return(self_val > other_val)
    
    def good_pair(self, other) -> None:
        vals = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
        self_val = 0
        other_val = 0
        
        for i in range(len(vals)):
            if self.value == vals[i]:
                self_val = i
            if other.value == vals[i]:
                other_val = i
        
        if self.suit == other.suit:
            print("A pair of the same suit :)")
        elif self.value == other.value:
            print("A pair of the same values :)")
        elif abs(self_val - other_val) == 1:
            print("A consective pair :)")
        else:
            print("your cards are bad :(")
    
# Cards for testing
card1 = Card("A", "Hearts")
card2 = Card("5", "Spades")
card3 = Card("A", "Clubs")

print(card1)
print(card1 == card3)
print(card2.compare(card1))
card1.good_pair(card3)
card2.good_pair(card3)
A of Hearts
True
True
A pair of the same values :)
your cards are bad :(
In [ ]: