fix(curriculum): use built-in list in workshop discount calculator (#66106)

This commit is contained in:
Aditya Singh
2026-02-27 19:54:43 +05:30
committed by GitHub
parent a0a0236d69
commit f7961efa45
11 changed files with 41 additions and 139 deletions

View File

@@ -1,89 +0,0 @@
---
id: 68e52994bc7ea2e3dec530a0
title: Step 23
challengeType: 20
dashedName: step-23
---
# --description--
Now you need a way to manage multiple discount strategies and find the best price. At the top of your file, after the existing import, add an import for the `List` type from the `typing` module:
```py
from typing import List
```
This allows you to specify that a function parameter is a list containing specific types of objects.
# --hints--
You should import `List` from the `typing` module as mentioned in the instructions after the existing imports.
```js
({
test: () => runPython(`assert _Node(_code).find_imports()[1].is_equivalent("from typing import List")`)
})
```
# --seed--
## --seed-contents--
```py
from abc import ABC, abstractmethod
--fcc-editable-region--
--fcc-editable-region--
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
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))
```

View File

@@ -1,15 +1,17 @@
---
id: 68e52994bc7ea2e3dec530a1
title: Step 24
title: Step 23
challengeType: 20
dashedName: step-24
dashedName: step-23
---
# --description--
Now you need a way to manage multiple discount strategies and find the best price.
Create a class named `DiscountEngine`. This class will manage all discount strategies and calculate the best price for a product.
Give it an `__init__` method that takes `self` and `strategies` as parameters, where `strategies` has a type hint of `List[DiscountStrategy]`. The return type of the method should be `None`. Inside the `__init__` method, store `strategies` as an instance attribute.
Give it an `__init__` method that takes `self` and `strategies` as parameters, where `strategies` has a type hint of `list[DiscountStrategy]`. Using `list[DiscountStrategy]` specifies that the parameter is a list containing `DiscountStrategy` objects. The return type of the method should be `None`. Inside the `__init__` method, store `strategies` as an instance attribute.
# --hints--
@@ -29,11 +31,11 @@ Your `DiscountEngine` class should have an `__init__` method.
})
```
Your `__init__` method should have parameters `self` and `strategies: List[DiscountStrategy]`.
Your `__init__` method should have parameters `self` and `strategies: list[DiscountStrategy]`.
```js
({
test: () => runPython(`assert _Node(_code).find_class("DiscountEngine").find_function("__init__").has_args("self, strategies: List[DiscountStrategy]")`)
test: () => runPython(`assert _Node(_code).find_class("DiscountEngine").find_function("__init__").has_args("self, strategies: list[DiscountStrategy]")`)
})
```
@@ -61,7 +63,6 @@ You should assign `strategies` to `self.strategies` inside your `__init__` metho
```py
from abc import ABC, abstractmethod
from typing import List
class Product:
def __init__(self, name: str, price: float) -> None:

View File

@@ -1,8 +1,8 @@
---
id: 68e52994bc7ea2e3dec530a2
title: Step 25
title: Step 24
challengeType: 20
dashedName: step-25
dashedName: step-24
---
# --description--
@@ -43,7 +43,6 @@ Your `calculate_best_price` method should have a return type hint of `-> float`.
```py
from abc import ABC, abstractmethod
from typing import List
class Product:
def __init__(self, name: str, price: float) -> None:
@@ -90,7 +89,7 @@ class PremiumUserDiscount(DiscountStrategy):
return product.price * 0.8
class DiscountEngine:
def __init__(self, strategies: List[DiscountStrategy]) -> None:
def __init__(self, strategies: list[DiscountStrategy]) -> None:
self.strategies = strategies
--fcc-editable-region--

View File

@@ -1,8 +1,8 @@
---
id: 68e52994bc7ea2e3dec530a3
title: Step 26
title: Step 25
challengeType: 20
dashedName: step-26
dashedName: step-25
---
# --description--
@@ -25,7 +25,6 @@ Inside `calculate_best_price`, you should create a list named `prices` containin
```py
from abc import ABC, abstractmethod
from typing import List
class Product:
def __init__(self, name: str, price: float) -> None:
@@ -72,7 +71,7 @@ class PremiumUserDiscount(DiscountStrategy):
return product.price * 0.8
class DiscountEngine:
def __init__(self, strategies: List[DiscountStrategy]) -> None:
def __init__(self, strategies: list[DiscountStrategy]) -> None:
self.strategies = strategies
--fcc-editable-region--

View File

@@ -1,8 +1,8 @@
---
id: 68e52994bc7ea2e3dec530a4
title: Step 27
title: Step 26
challengeType: 20
dashedName: step-27
dashedName: step-26
---
# --description--
@@ -47,7 +47,6 @@ assert _Node(_code).find_class("DiscountEngine").find_function("calculate_best_p
```py
from abc import ABC, abstractmethod
from typing import List
class Product:
def __init__(self, name: str, price: float) -> None:
@@ -94,7 +93,7 @@ class PremiumUserDiscount(DiscountStrategy):
return product.price * 0.8
class DiscountEngine:
def __init__(self, strategies: List[DiscountStrategy]) -> None:
def __init__(self, strategies: list[DiscountStrategy]) -> None:
self.strategies = strategies
--fcc-editable-region--

View File

@@ -1,8 +1,8 @@
---
id: 68e52994bc7ea2e3dec530a5
title: Step 28
title: Step 27
challengeType: 20
dashedName: step-28
dashedName: step-27
---
# --description--
@@ -27,7 +27,6 @@ Your `calculate_best_price` method should return the minimum value from the `pri
```py
from abc import ABC, abstractmethod
from typing import List
class Product:
def __init__(self, name: str, price: float) -> None:
@@ -74,7 +73,7 @@ class PremiumUserDiscount(DiscountStrategy):
return product.price * 0.8
class DiscountEngine:
def __init__(self, strategies: List[DiscountStrategy]) -> None:
def __init__(self, strategies: list[DiscountStrategy]) -> None:
self.strategies = strategies
def calculate_best_price(self, product: Product, user_tier: str) -> float:

View File

@@ -1,8 +1,8 @@
---
id: 68e52994bc7ea2e3dec530a6
title: Step 30
title: Step 29
challengeType: 20
dashedName: step-30
dashedName: step-29
---
# --description--
@@ -51,7 +51,6 @@ You should create a list named `strategies` containing `PercentageDiscount(10)`,
```py
from abc import ABC, abstractmethod
from typing import List
class Product:
def __init__(self, name: str, price: float) -> None:
@@ -98,7 +97,7 @@ class PremiumUserDiscount(DiscountStrategy):
return product.price * 0.8
class DiscountEngine:
def __init__(self, strategies: List[DiscountStrategy]) -> None:
def __init__(self, strategies: list[DiscountStrategy]) -> None:
self.strategies = strategies
def calculate_best_price(self, product: Product, user_tier: str) -> float:

View File

@@ -1,8 +1,8 @@
---
id: 68e52994bc7ea2e3dec530a7
title: Step 32
title: Step 31
challengeType: 20
dashedName: step-32
dashedName: step-31
---
# --description--
@@ -41,7 +41,6 @@ Your output should match the format: `Best price for {product.name} for {user_ti
```py
from abc import ABC, abstractmethod
from typing import List
class Product:
def __init__(self, name: str, price: float) -> None:
@@ -88,7 +87,7 @@ class PremiumUserDiscount(DiscountStrategy):
return product.price * 0.8
class DiscountEngine:
def __init__(self, strategies: List[DiscountStrategy]) -> None:
def __init__(self, strategies: list[DiscountStrategy]) -> None:
self.strategies = strategies
def calculate_best_price(self, product: Product, user_tier: str) -> float:
@@ -122,7 +121,6 @@ if __name__ == '__main__':
```py
from abc import ABC, abstractmethod
from typing import List
class Product:
def __init__(self, name: str, price: float) -> None:
@@ -168,7 +166,7 @@ class PremiumUserDiscount(DiscountStrategy):
return product.price * 0.8 # 20% off for premium users
class DiscountEngine:
def __init__(self, strategies: List[DiscountStrategy]) -> None:
def __init__(self, strategies: list[DiscountStrategy]) -> None:
self.strategies = strategies
def calculate_best_price(self, product: Product, user_tier: str) -> float:

View File

@@ -1,8 +1,8 @@
---
id: 68e7a24b2482bd5fa88774fa
title: Step 29
title: Step 28
challengeType: 20
dashedName: step-29
dashedName: step-28
---
# --description--
@@ -65,7 +65,6 @@ You should not have the line `print(fixed_discount.apply_discount(product))` in
```py
from abc import ABC, abstractmethod
from typing import List
class Product:
def __init__(self, name: str, price: float) -> None:
@@ -112,7 +111,7 @@ class PremiumUserDiscount(DiscountStrategy):
return product.price * 0.8
class DiscountEngine:
def __init__(self, strategies: List[DiscountStrategy]) -> None:
def __init__(self, strategies: list[DiscountStrategy]) -> None:
self.strategies = strategies
def calculate_best_price(self, product: Product, user_tier: str) -> float:

View File

@@ -1,8 +1,8 @@
---
id: 68efb04d5ea87cf267192ed4
title: Step 31
title: Step 30
challengeType: 20
dashedName: step-31
dashedName: step-30
---
# --description--
@@ -34,7 +34,6 @@ You should call `engine.calculate_best_price(product, user_tier)` and store the
```py
from abc import ABC, abstractmethod
from typing import List
class Product:
def __init__(self, name: str, price: float) -> None:
@@ -81,7 +80,7 @@ class PremiumUserDiscount(DiscountStrategy):
return product.price * 0.8
class DiscountEngine:
def __init__(self, strategies: List[DiscountStrategy]) -> None:
def __init__(self, strategies: list[DiscountStrategy]) -> None:
self.strategies = strategies
def calculate_best_price(self, product: Product, user_tier: str) -> float:

View File

@@ -27,16 +27,15 @@
{ "id": "68e52994bc7ea2e3dec5309d", "title": "Step 20" },
{ "id": "68e52994bc7ea2e3dec5309e", "title": "Step 21" },
{ "id": "68e52994bc7ea2e3dec5309f", "title": "Step 22" },
{ "id": "68e52994bc7ea2e3dec530a0", "title": "Step 23" },
{ "id": "68e52994bc7ea2e3dec530a1", "title": "Step 24" },
{ "id": "68e52994bc7ea2e3dec530a2", "title": "Step 25" },
{ "id": "68e52994bc7ea2e3dec530a3", "title": "Step 26" },
{ "id": "68e52994bc7ea2e3dec530a4", "title": "Step 27" },
{ "id": "68e52994bc7ea2e3dec530a5", "title": "Step 28" },
{ "id": "68e7a24b2482bd5fa88774fa", "title": "Step 29" },
{ "id": "68e52994bc7ea2e3dec530a6", "title": "Step 30" },
{ "id": "68efb04d5ea87cf267192ed4", "title": "Step 31" },
{ "id": "68e52994bc7ea2e3dec530a7", "title": "Step 32" }
{ "id": "68e52994bc7ea2e3dec530a1", "title": "Step 23" },
{ "id": "68e52994bc7ea2e3dec530a2", "title": "Step 24" },
{ "id": "68e52994bc7ea2e3dec530a3", "title": "Step 25" },
{ "id": "68e52994bc7ea2e3dec530a4", "title": "Step 26" },
{ "id": "68e52994bc7ea2e3dec530a5", "title": "Step 27" },
{ "id": "68e7a24b2482bd5fa88774fa", "title": "Step 28" },
{ "id": "68e52994bc7ea2e3dec530a6", "title": "Step 29" },
{ "id": "68efb04d5ea87cf267192ed4", "title": "Step 30" },
{ "id": "68e52994bc7ea2e3dec530a7", "title": "Step 31" }
],
"blockLabel": "workshop",
"usesMultifileEditor": true,