python-tutorial icon indicating copy to clipboard operation
python-tutorial copied to clipboard

Errors found in the `object_oriented_programming_advanced` notebook

Open yakutovicha opened this issue 1 year ago • 4 comments

yakutovicha avatar Dec 12 '23 09:12 yakutovicha

Typo in Music Streaming Service exercise: Class User should have attribute username and not name

despadam avatar Dec 12 '23 09:12 despadam

In the "Banking system" exercise, clarify which kind of interest we want to compute. In the tests we are computing a "simple" interest, while someone might attempt to calculate a "compound" interest. We have to make it clear.

edoardob90 avatar Dec 12 '23 10:12 edoardob90

In "Store Inventory" exercise, solution with 'pop("type")' method does not pass the tests even though it outputs the correct result.

Code example that works but fails the tests:

computers = [
    {
        "type": "PC",
        "name": "pc_1",
        "price": 1500,
        "quantity": 1,
        "expansion_slots": 2
    },
    {
        "type": "Laptop",
        "name": "laptop_1",
        "price": 1200,
        "quantity": 4,
        "battery_life": 6
    }
]

class Computer:
    def __init__(self,name,price,quantity):
        self.name = name
        self.price = price
        self.quantity = quantity
    
    def __str__(self):
        return f"Computer with name '{self.name}', price {self.price} CHF and quantity {self.quantity}."
    
class PC(Computer):
    def __init__(self,name,price,quantity,expansion_slots):
        super().__init__(name,price,quantity)
        self.expansion_slots = expansion_slots
    
    def __str__(self):
        return super().__str__() + f" This PC has {self.expansion_slots} expansion slots."
    
class Laptop(Computer):
    def __init__(self,name,price,quantity,battery_life):
        super().__init__(name,price,quantity)
        self.battery_life = battery_life
    
    def __str__(self):
        return super().__str__() + f" This laptop has a battery life of {self.battery_life} hours."

inventory = []
for computer in computers:
    if computer["type"] == "Computer":
        computer.pop("type")
        inventory.append(Computer(**computer))
    elif computer["type"] == "PC":
        computer.pop("type")
        inventory.append(PC(**computer))
    elif computer["type"] == "Laptop":
        computer.pop("type")
        inventory.append(Laptop(**computer))

sol = []
for it in inventory:
    sol.append(str(it))

print(sol)

GCatarina avatar Dec 12 '23 13:12 GCatarina

In the first exercise, it is not possible to use the define decorator to define Mother and Father classes:

from attrs import define

@define
class Mother:
    eye_color_mother: str

@define
class Father:
    eye_color_father: str

class Child(Mother, Father):
    def __init__(self, eye_color_mother: str, eye_color_father: str):
        Mother.__init__(self, eye_color_mother)
        Father.__init__(self, eye_color_father)
        self.eye_color = self.set_eye_color()

    def set_eye_color(self):
        if self.eye_color_mother == self.eye_color_father:
            return self.eye_color_mother
        return "brown"

An attempt to create a class results in the following error:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[2], line 9
      5 @define
      6 class Father:
      7     eye_color_father: str
----> 9 class Child(Mother, Father):
     10     def __init__(self, eye_color_mother: str, eye_color_father: str):
     11         Mother.__init__(self, eye_color_mother)

TypeError: multiple bases have instance lay-out conflict

Replacing the @define decorator with dataclass fixes the issue. But it is still not clear why define is not working.

Some hints from the stackoverflow.

yakutovicha avatar Dec 12 '23 13:12 yakutovicha