Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 99 additions & 0 deletions Solve Task 2/cart.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
from typing import Final
from crud import (
read_product,
update_product,
)
from storage import (
QUANTITY_INDEX,
NAME_INDEX,
PRICE_INDEX,
Product)

CartLine = tuple[int, int]
LINE_PRODUCT_ID_INDEX: Final = 0
LINE_QUANTITY_INDEX: Final = 1


def find_cart_line(cart: list[CartLine],
product_id: int,) -> CartLine | None:
for line in cart:
if line[LINE_PRODUCT_ID_INDEX] == product_id:
return line
print(f"Product {product_id} is not in the cart/")
return None


def add_to_cart(storage: list[Product],
cart: list[CartLine],
product_id: int,
quantity: int) -> CartLine | None:
product = read_product(storage, product_id)
if product is None:
return product
storage_quantity = product[QUANTITY_INDEX]
if storage_quantity < quantity:
print(f"Not enough stock for product {product_id}: "
f"{storage_quantity} available, "
f"{quantity} requested.")
return None

new_field = (
product[NAME_INDEX],
product[PRICE_INDEX],
storage_quantity - quantity
)
update_product(storage, product_id, new_field)

for index, line in enumerate(cart):
if line[LINE_PRODUCT_ID_INDEX] == product_id:
new_line: CartLine = (
product_id,
line[LINE_QUANTITY_INDEX] + quantity
)
cart[index] = new_line
return new_line
new_line: CartLine = (product_id, quantity)
cart.append(new_line)
return new_line


def remove_from_cart(storage: list[Product],
cart: list[CartLine],
product_id: int,
quantity: int) -> CartLine | None:
cart_line = find_cart_line(cart, product_id)
product = read_product(storage, product_id)
if cart_line is None:
return cart_line
if cart_line[LINE_QUANTITY_INDEX] < quantity:
print(f"Cart holds only {cart_line[LINE_QUANTITY_INDEX]} "
f"unit(s) of product {product_id}, cannot remove {quantity}.")
return None
if product is None:
return None
new_quantity = product[QUANTITY_INDEX] + quantity
new_fields = (
product[NAME_INDEX],
product[PRICE_INDEX],
new_quantity,
)
update_product(
storage,
product_id,
new_fields,
)
new_line: CartLine = (
product_id,
cart_line[LINE_QUANTITY_INDEX] - quantity,
)
new_line: CartLine = (
product_id,
cart_line[LINE_QUANTITY_INDEX]-quantity
)
if new_line[LINE_QUANTITY_INDEX] == 0:
cart.remove(cart_line)
return new_line
for index, line in enumerate(cart):
if line == cart_line:
cart[index] = new_line
return new_line
65 changes: 65 additions & 0 deletions Solve Task 2/crud.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
from decimal import Decimal
from storage import (
PRODUCT_ID_MIN,
PRODUCT_ID_INDEX,
NAME_INDEX,
Product,
)
from utils import normalize_price


def create_product(storage: list[Product],
fields: tuple[str, Decimal, int]) -> int | None:
product_name, product_price, product_quantity = fields
for product in storage:
if product_name == product[NAME_INDEX]:
print(f"Product name {product_name} is already taken.")
return None
product_id = generate_product_id(storage)
storage.append((
product_id,
product_name,
normalize_price(product_price),
product_quantity
))
return product_id


def generate_product_id(storage: list[Product]) -> int:
if not storage:
return PRODUCT_ID_MIN
MAX_INDEX = max(product[PRODUCT_ID_INDEX] for product in storage)
return MAX_INDEX + 1


def read_product(storage: list[Product], product_id: int) -> Product | None:
for product in storage:
if product[PRODUCT_ID_INDEX] == product_id:
return product
print(f"No product with id {product_id}")
return None


def update_product(
storage: list[Product],
product_id: int,
fields: tuple[str, Decimal, int],
) -> Product | None:
for index, product in enumerate(storage):
if product[PRODUCT_ID_INDEX] == product_id:
new_name, new_price, new_quantity = fields
norm_price = normalize_price(new_price)
NEW_PRODUCT = (product_id, new_name, norm_price, new_quantity)
storage[index] = NEW_PRODUCT
return NEW_PRODUCT
print(f"No product with id {product_id}")
return None


def delete_product(storage: list[Product], product_id: int) -> int | None:
for index, product in enumerate(storage):
if product[PRODUCT_ID_INDEX] == product_id:
storage.pop(index)
return product_id
print(f"No product with id {product_id}.")
return None
11 changes: 11 additions & 0 deletions Solve Task 2/storage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from decimal import Decimal
from typing import Final

Product = tuple[int, str, Decimal, int]

PRODUCT_ID_INDEX: Final[int] = 0
NAME_INDEX: Final[int] = 1
PRICE_INDEX: Final[int] = 2
QUANTITY_INDEX: Final[int] = 3

PRODUCT_ID_MIN: Final[int] = 1
9 changes: 9 additions & 0 deletions Solve Task 2/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from typing import Final
from decimal import Decimal, ROUND_HALF_UP

PRICE_PRECISION: Final[int] = 2
PRICE_STEP: Final = Decimal(1).scaleb(-PRICE_PRECISION)


def normalize_price(price: Decimal) -> Decimal:
return price.quantize(PRICE_STEP, rounding=ROUND_HALF_UP)
129 changes: 129 additions & 0 deletions src/part2/cart.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
from typing import Final

from .crud import read_product, update_product
from .storage import (
NAME_INDEX,
PRICE_INDEX,
QUANTITY_INDEX,
Product,
)


CartLine = tuple[int, int]

LINE_PRODUCT_ID_INDEX: Final[int] = 0
LINE_QUANTITY_INDEX: Final[int] = 1


def find_cart_line(
cart: list[CartLine],
product_id: int,
) -> CartLine | None:
for line in cart:
if line[LINE_PRODUCT_ID_INDEX] == product_id:
return line

print(f"Product {product_id} is not in the cart")
return None


def add_to_cart(
storage: list[Product],
cart: list[CartLine],
product_id: int,
quantity: int,
) -> CartLine | None:
product = read_product(storage, product_id)

if product is None:
return None

storage_quantity = product[QUANTITY_INDEX]

if storage_quantity < quantity:
print(
f"Not enough stock for product {product_id}: "
f"{storage_quantity} available, "
f"{quantity} requested."
)
return None

new_fields = (
product[NAME_INDEX],
product[PRICE_INDEX],
storage_quantity - quantity,
)

update_product(
storage,
product_id,
new_fields,
)

for index, line in enumerate(cart):
if line[LINE_PRODUCT_ID_INDEX] == product_id:
new_line = (
product_id,
line[LINE_QUANTITY_INDEX] + quantity,
)
cart[index] = new_line
return new_line

new_line = (product_id, quantity)
cart.append(new_line)
return new_line


def remove_from_cart(
storage: list[Product],
cart: list[CartLine],
product_id: int,
quantity: int,
) -> CartLine | None:
cart_line = find_cart_line(cart, product_id)

if cart_line is None:
return None

if cart_line[LINE_QUANTITY_INDEX] < quantity:
print(
f"Cart holds only {cart_line[LINE_QUANTITY_INDEX]} "
f"unit(s) of product {product_id}, "
f"cannot remove {quantity}."
)
return None

product = read_product(storage, product_id)

if product is None:
return None

new_quantity = product[QUANTITY_INDEX] + quantity

new_fields = (
product[NAME_INDEX],
product[PRICE_INDEX],
new_quantity,
)

update_product(
storage,
product_id,
new_fields,
)

new_line: CartLine = (
product_id,
cart_line[LINE_QUANTITY_INDEX] - quantity,
)

if new_line[LINE_QUANTITY_INDEX] == 0:
cart.remove(cart_line)
return new_line

for index, line in enumerate(cart):
if line == cart_line:
cart[index] = new_line
return new_line

return None
Loading
Loading