py_stepik/mod_oop/2.3_11_supershop.py
2024-04-09 17:32:49 +03:00

109 lines
3.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# https://stepik.org/lesson/701985/step/11?unit=702086
from typing import Protocol
class Validator(Protocol):
def validate(self, value: str) -> bool:
...
class ValidatedField:
ValueValidator: Validator
def __init__(self, *args, **kwargs):
self.validator = self.ValueValidator(*args, **kwargs)
def __set_name__(self, owner, name):
self.name = "_" + name
def __get__(self, instance, owner):
return getattr(instance, self.name)
def __set__(self, instance, value):
if self.validator.validate(value):
setattr(instance, self.name, value)
class StringValue(ValidatedField):
class ValueValidator(Validator):
def __init__(self, min_length, max_length):
self.min_length, self.max_length = min_length, max_length
def validate(self, value: str) -> bool:
return (
isinstance(value, str)
and self.min_length <= len(value) <= self.max_length
)
class PriceValue(ValidatedField):
class ValueValidator(Validator):
def __init__(self, max_value):
self.max_value = max_value
def validate(self, value: str) -> bool:
return isinstance(value, int) and 0 <= value <= self.max_value
class Product:
name = StringValue(min_length=2, max_length=50)
price = PriceValue(max_value=10000)
def __init__(self, name, price):
self.name = name
self.price = price
class SuperShop:
def __init__(self, name):
self.name = name
self.goods: list[Product] = []
def add_product(self, product: Product):
self.goods.append(product)
def remove_product(self, product: Product):
self.goods.remove(product)
shop = SuperShop("У Балакирева")
shop.add_product(Product("Курс по Python", 0))
shop.add_product(Product("Курс по Python ООП", 2000))
for p in shop.goods:
print(f"{p.name}: {p.price}")
def tests():
shop = SuperShop("У Балакирева")
shop.add_product(Product("name", 100))
shop.add_product(Product("name", 100))
assert (
shop.name == "У Балакирева"
), "атрибут name объекта класса SuperShop содержит некорректное значение"
for p in shop.goods:
assert p.price == 100, "дескриптор price вернул неверное значение"
assert p.name == "name", "дескриптор name вернул неверное значение"
t = Product("name 123", 1000)
shop.add_product(t)
shop.remove_product(t)
assert (
len(shop.goods) == 2
), "неверное количество товаров: возможно некорректно работают методы add_product и remove_product"
assert hasattr(shop.goods[0], "name") and hasattr(shop.goods[0], "price")
t = Product(1000, "name 123")
if hasattr(t, "_name"):
assert type(t.name) == str, "типы поля name должнен быть str"
if hasattr(t, "_price"):
assert type(t.price) in (
int,
float,
), "тип поля price должнен быть int или float"
tests()