Skip to content

feat(curriculum): add discount calculator workshop#62644

Merged
Dario-DC merged 32 commits intofreeCodeCamp:mainfrom
zairahira:feat/add-abstraction-workshop
Nov 4, 2025
Merged

feat(curriculum): add discount calculator workshop#62644
Dario-DC merged 32 commits intofreeCodeCamp:mainfrom
zairahira:feat/add-abstraction-workshop

Conversation

@zairahira
Copy link
Copy Markdown
Member

@zairahira zairahira commented Oct 9, 2025

Checklist:

Closes freeCodeCamp/CurriculumExpansion#989

Requires curriculum helpers to have the changes in freeCodeCamp/curriculum-helpers#509

@github-actions github-actions bot added scope: curriculum Lessons, Challenges, Projects and other Curricular Content in curriculum directory. platform: learn UI side of the client application that needs familiarity with React, Gatsby etc. scope: i18n language translation/internationalization. Often combined with language type label labels Oct 9, 2025
Copy link
Copy Markdown
Contributor

@Dario-DC Dario-DC left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left comments to write the missing tests (they should work but I did not verify)

@zairahira zairahira added full stack cert status: waiting review To be applied to PR's that are ready for QA, especially when additional review is pending. labels Oct 10, 2025
@zairahira zairahira marked this pull request as ready for review October 10, 2025 15:49
@zairahira zairahira requested a review from a team October 10, 2025 15:49
@zairahira zairahira added status: waiting update Is awaiting update, after feedback or request for changes status: waiting review To be applied to PR's that are ready for QA, especially when additional review is pending. and removed status: waiting review To be applied to PR's that are ready for QA, especially when additional review is pending. status: waiting update Is awaiting update, after feedback or request for changes labels Oct 15, 2025
@zairahira zairahira requested a review from Dario-DC October 15, 2025 08:05
Copy link
Copy Markdown
Contributor

@Dario-DC Dario-DC left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add the return type to the methods that don't have one. -> None for __init__ methods and -> str for __str__.

@Dario-DC Dario-DC added status: waiting update Is awaiting update, after feedback or request for changes and removed status: waiting review To be applied to PR's that are ready for QA, especially when additional review is pending. labels Oct 15, 2025
@zairahira
Copy link
Copy Markdown
Member Author

@Dario-DC, before i make changes to the instructions and add tests, can you verify if this should be the final solution after adding return types to __init__ and __str__?

Code updated
from abc import ABC, abstractmethod
from typing import List

class Product:
    def __init__(self, name: str, price: float) -> None:
        self.name = name
        self.price = 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: float) -> 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: float) -> 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.80  # 20% off for premium users

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]
        for strategy in self.strategies:
            if strategy.is_applicable(product, user_tier):
                discounted = strategy.apply_discount(product)
                prices.append(discounted)
        return min(prices)

if __name__ == '__main__':
    product = Product('Wireless Mouse', 50.0)
    user_tier = 'Premium'
    strategies = [
        PercentageDiscount(10),
        FixedAmountDiscount(5),
        PremiumUserDiscount()
    ]
    engine = DiscountEngine(strategies)
    best_price = engine.calculate_best_price(product, user_tier)
    print(f'Best price for {product.name} for {user_tier} user: ${best_price:.2f}')

@Dario-DC
Copy link
Copy Markdown
Contributor

@Dario-DC, before i make changes to the instructions and add tests, can you verify if this should be the final solution after adding return types to __init__ and __str__?

@zairahira the Product class should also have

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

I've just realized that __str__ is not part of the solution at the moment. So it should be added there as well

Copy link
Copy Markdown
Contributor

@majestic-owl448 majestic-owl448 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

almost there

Co-authored-by: Ilenia <26656284+ilenia-magoni@users.noreply.github.com>
@majestic-owl448 majestic-owl448 added status: waiting update Is awaiting update, after feedback or request for changes and removed status: waiting review To be applied to PR's that are ready for QA, especially when additional review is pending. labels Oct 25, 2025
Co-authored-by: Ilenia <26656284+ilenia-magoni@users.noreply.github.com>
@zairahira zairahira added status: waiting review To be applied to PR's that are ready for QA, especially when additional review is pending. and removed status: waiting update Is awaiting update, after feedback or request for changes labels Oct 27, 2025
@majestic-owl448 majestic-owl448 added the MERGE CONFLICT! To be applied to PR's that have a merge conflict and need updating label Oct 28, 2025
zairahira and others added 3 commits October 29, 2025 12:14
Co-authored-by: Dario <105294544+Dario-DC@users.noreply.github.com>
Co-authored-by: Dario <105294544+Dario-DC@users.noreply.github.com>
@Dario-DC Dario-DC added status: waiting update Is awaiting update, after feedback or request for changes and removed status: waiting review To be applied to PR's that are ready for QA, especially when additional review is pending. MERGE CONFLICT! To be applied to PR's that have a merge conflict and need updating labels Oct 29, 2025
@zairahira zairahira added status: waiting review To be applied to PR's that are ready for QA, especially when additional review is pending. and removed status: waiting update Is awaiting update, after feedback or request for changes labels Oct 31, 2025
@Dario-DC Dario-DC merged commit 4afe2da into freeCodeCamp:main Nov 4, 2025
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

platform: learn UI side of the client application that needs familiarity with React, Gatsby etc. scope: curriculum Lessons, Challenges, Projects and other Curricular Content in curriculum directory. scope: i18n language translation/internationalization. Often combined with language type label status: waiting review To be applied to PR's that are ready for QA, especially when additional review is pending.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add abstraction workshop to main with steps and tests

4 participants