Build a Discount Calculator - step 26

In step 26 I have tried several different approaches, as you can see from what is commented out. I am stuck, and need a nudge in the right direction.

from abc import ABC, abstractmethod

class Product:
    def __init__(self, name: str, price: float) -> None:
        self.name = name
        self.price = price

    def __str__(self) -> str:
        return f'{self.name} - ${self.price}'

class DiscountStrategy(ABC):
    @abstractmethod
    def is_applicable(self, product: Product, user_tier: str) -> bool:
        pass

    @abstractmethod
    def apply_discount(self, product: Product) -> float:
        pass

class PercentageDiscount(DiscountStrategy):
    def __init__(self, percent: int) -> None:
        self.percent = percent

    def is_applicable(self, product: Product, user_tier: str) -> bool:
        return self.percent <= 70

    def apply_discount(self, product: Product) -> float:
        return product.price * (1 - self.percent / 100)

class FixedAmountDiscount(DiscountStrategy):
    def __init__(self, amount: int) -> None:
        self.amount = amount

    def is_applicable(self, product: Product, user_tier: str) -> bool:
        return product.price * 0.9 > self.amount

    def apply_discount(self, product: Product) -> float:
        return product.price - self.amount

class PremiumUserDiscount(DiscountStrategy):
    def is_applicable(self, product: Product, user_tier: str) -> bool:
        return user_tier.lower() == 'premium'

    def apply_discount(self, product: Product) -> float:
        return product.price * 0.8

class DiscountEngine:
    def __init__(self, strategies: list[DiscountStrategy]) -> None:
        self.strategies = strategies

    def calculate_best_price(self, product: Product, user_tier: str) -> float:
        prices = [product.price]
        print(prices)
        for strategy in self.strategies:
            if strategy.is_applicable(product, user_tier):
                discounted = apply_discount(product)
                prices.append(discounted)
#                discounted = apply_discount(self.product)
#                prices.append(discounted)
#                prices.append(apply_discount(self.product))


product = Product('Wireless Mouse', 50.0)
print(product)

discount = PercentageDiscount(10)
print(discount.apply_discount(product))

fixed_discount = FixedAmountDiscount(5)
print(fixed_discount.apply_discount(product))

#premium_discount = PremiumUserDiscount()
#user_tier = 'premium'
#best_price = DiscountEngine.calculate_best_price(product, user_tier)

hey there, would you mind providing the link to this challenge?

Now create a for loop that iterates over self.strategies. For each strategy, check if it’s applicable using the is_applicable method. If it is, calculate the discounted price using apply_discount and store it in a variable named discounted. Then, append the discounted price to the prices list.
and
If a strategy is applicable, you should call apply_discount and append the result to prices.

thank you for the instructions, but can you please give the link to the challenge?

Is this it? I’m not sure what you mean

thank you for that!

is apply_discount a function, or a method?

Its a method, which exists in each of three discount types. Does this affect how it is called?

yes, consider how you called the is_applicable method for example, vs how you called print function

I think the format of the call is correct, but I am weak on finding the correct link through the classes. My call is to self.apply_discount(product). Clearly that is wrong, but I am lost as to how to qualify it and load its arguments

self in this case is DiscountEngine, does apply_discount exist in this class? or is it in a different one?

Its in three different ones. What info or pointers do I have? That’s my problem. It must be strategy! Thanks for the pointers.

isn’t also is_applicable in three different ones? how are you using that one?

The same. A method depending on strategy

so now do you manage to write the code?

Got it, thanks very much.