-
-
Notifications
You must be signed in to change notification settings - Fork 50.3k
feat(other): add grocery store cart model (v3) #14550
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
d28896c
9611435
4e7fa49
eedcb14
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,83 @@ | ||||||||||||||||||||||
| """ | ||||||||||||||||||||||
| Console-free grocery cart logic. | ||||||||||||||||||||||
| """ | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| class GroceryStoreCart: | ||||||||||||||||||||||
| """ | ||||||||||||||||||||||
| Maintain cart item quantities and compute totals. | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| >>> cart = GroceryStoreCart({"apple": 1.5, "milk": 2.0}) | ||||||||||||||||||||||
| >>> cart.add_item("apple", 2) | ||||||||||||||||||||||
| >>> cart.add_item("milk") | ||||||||||||||||||||||
| >>> round(cart.total_price(), 2) | ||||||||||||||||||||||
| 5.0 | ||||||||||||||||||||||
| >>> cart.remove_item("apple") | ||||||||||||||||||||||
| >>> round(cart.total_price(), 2) | ||||||||||||||||||||||
| 3.5 | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| >>> GroceryStoreCart({}) | ||||||||||||||||||||||
| Traceback (most recent call last): | ||||||||||||||||||||||
| ... | ||||||||||||||||||||||
| ValueError: price_catalog cannot be empty | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| >>> cart.add_item("bread") | ||||||||||||||||||||||
| Traceback (most recent call last): | ||||||||||||||||||||||
| ... | ||||||||||||||||||||||
| KeyError: "'bread' is not in the catalog" | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| >>> cart.add_item("apple", 0) | ||||||||||||||||||||||
| Traceback (most recent call last): | ||||||||||||||||||||||
| ... | ||||||||||||||||||||||
| ValueError: quantity must be positive | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| >>> cart.remove_item("milk", 0) | ||||||||||||||||||||||
| Traceback (most recent call last): | ||||||||||||||||||||||
| ... | ||||||||||||||||||||||
| ValueError: quantity must be positive | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| >>> empty_cart = GroceryStoreCart({"apple": 1.5}) | ||||||||||||||||||||||
| >>> empty_cart.remove_item("apple") | ||||||||||||||||||||||
| Traceback (most recent call last): | ||||||||||||||||||||||
| ... | ||||||||||||||||||||||
| KeyError: "'apple' is not present in the cart" | ||||||||||||||||||||||
| """ | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| def __init__(self, price_catalog: dict[str, float]) -> None: | ||||||||||||||||||||||
| if not price_catalog: | ||||||||||||||||||||||
| raise ValueError("price_catalog cannot be empty") | ||||||||||||||||||||||
| self.price_catalog = dict(price_catalog) | ||||||||||||||||||||||
| self.quantities: dict[str, int] = {} | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| def add_item(self, item: str, quantity: int = 1) -> None: | ||||||||||||||||||||||
| if item not in self.price_catalog: | ||||||||||||||||||||||
| msg = f"{item!r} is not in the catalog" | ||||||||||||||||||||||
| raise KeyError(msg) | ||||||||||||||||||||||
| if quantity <= 0: | ||||||||||||||||||||||
| raise ValueError("quantity must be positive") | ||||||||||||||||||||||
| self.quantities[item] = self.quantities.get(item, 0) + quantity | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| def remove_item(self, item: str, quantity: int = 1) -> None: | ||||||||||||||||||||||
| if quantity <= 0: | ||||||||||||||||||||||
| raise ValueError("quantity must be positive") | ||||||||||||||||||||||
| current = self.quantities.get(item, 0) | ||||||||||||||||||||||
| if current == 0: | ||||||||||||||||||||||
| msg = f"{item!r} is not present in the cart" | ||||||||||||||||||||||
| raise KeyError(msg) | ||||||||||||||||||||||
| if quantity > current: | ||||||||||||||||||||||
| raise ValueError("quantity exceeds amount present in the cart") | ||||||||||||||||||||||
| if (remaining := current - quantity) > 0: | ||||||||||||||||||||||
| self.quantities[item] = remaining | ||||||||||||||||||||||
| else: | ||||||||||||||||||||||
| self.quantities.pop(item, None) | ||||||||||||||||||||||
|
Comment on lines
+69
to
+72
|
||||||||||||||||||||||
| if (remaining := current - quantity) > 0: | |
| self.quantities[item] = remaining | |
| else: | |
| self.quantities.pop(item, None) | |
| if quantity > current: | |
| raise ValueError("quantity exceeds amount present in the cart") | |
| if quantity == current: | |
| self.quantities.pop(item, None) | |
| else: | |
| self.quantities[item] = current - quantity |
Copilot
AI
Apr 13, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This total_price() return line is likely over the repo’s configured line-length limit (ruff/pycodestyle E501). Please wrap the sum(...) call across multiple lines to avoid lint failures.
| self.price_catalog[item] * qty for item, qty in self.quantities.items() | |
| self.price_catalog[item] * qty | |
| for item, qty in self.quantities.items() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The doctest only covers the happy path. Since
__init__(),add_item(), andremove_item()introduce several error branches (empty catalog, unknown items, non-positive quantities), please add doctest cases that assert the expected exceptions/messages so these behaviors are exercised by CI.