From 98102422ec23894152621dae6e8aa8c66797973c Mon Sep 17 00:00:00 2001 From: Dmitry Date: Wed, 10 Apr 2024 12:06:47 +0300 Subject: [PATCH] + 3.1.6 --- mod_oop/3.1_6_shop.py | 123 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 mod_oop/3.1_6_shop.py diff --git a/mod_oop/3.1_6_shop.py b/mod_oop/3.1_6_shop.py new file mode 100644 index 0000000..a8f1964 --- /dev/null +++ b/mod_oop/3.1_6_shop.py @@ -0,0 +1,123 @@ +""" + https://stepik.org/lesson/701986/step/6?unit=702087 + + Вы создаете интернет-магазин. Для этого нужно объявить два класса: + +Shop - класс для управления магазином в целом; +Product - класс для представления отдельного товара. + +Объекты класса Shop следует создавать командой: +>>> shop = Shop("название магазина") + +В каждом объекте класса Shop должно создаваться локальное свойство: +goods - список товаров (изначально список пустой). + +А также в классе объявить методы: +add_product(self, product) - добавление нового товара в магазин (в конец списка goods); +remove_product(self, product) - удаление товара product из магазина (из списка goods); + +Объекты класса Product следует создавать командой: +p = Product(название, вес, цена) +>>> p = Product("название", 123, 4.56) + +В них автоматически должны формироваться локальные атрибуты: +id - уникальный идентификационный номер товара (генерируется автоматически как целое положительное число от 1 и далее); +name - название товара (строка); +weight - вес товара (целое или вещественное положительное число); +price - цена (целое или вещественное положительное число). + +В классе Product через магические методы (подумайте какие) осуществить проверку на тип присваиваемых данных локальным атрибутам объектов класса +(например, id - целое число, name - строка и т.п.). Если проверка не проходит, то генерировать исключение командой: +raise TypeError("Неверный тип присваиваемых данных.") +>>> Product("название", "вес", 4.56) +Traceback (most recent call last): + ... +TypeError: Неверный тип присваиваемых данных. + +>>> Product("название", -1, 4.56) +Traceback (most recent call last): + ... +TypeError: Неверный тип присваиваемых данных. + +>>> Product("название", 1, -4.56) +Traceback (most recent call last): + ... +TypeError: Неверный тип присваиваемых данных. + +Также в классе Product с помощью магического(их) метода(ов) запретить удаление локального атрибута id. При попытке это сделать генерировать исключение: +raise AttributeError("Атрибут id удалять запрещено.") +>>> del Product("название", 123, 4.56).id +Traceback (most recent call last): + ... +AttributeError: Атрибут id удалять запрещено. + +Пример использования классов (в программе эти строчки не писать): +shop = Shop("Балакирев и К") +book = Product("Python ООП", 100, 1024) +shop.add_product(book) +shop.add_product(Product("Python", 150, 512)) +for p in shop.goods: + print(f"{p.name}, {p.weight}, {p.price}") + +>>> shop = Shop("Балакирев и К") +>>> book = Product("Python ООП", 100, 1024) +>>> shop.add_product(book) +>>> shop.add_product(Product("Python", 150, 512)) +>>> [f"{p.name}, {p.weight}, {p.price}" for p in shop.goods] +['Python ООП, 100, 1024', 'Python, 150, 512'] + +P.S. На экран ничего выводить не нужно. +""" + +from typing import TypeAlias, Union + + +class Shop: + def __init__(self, name): + self.name, self.goods = name, [] + + def add_product(self, product): + self.goods.append(product) + + def remove_product(self, product): + self.goods.remove(product) + + +Number: TypeAlias = Union[int, float] + + +class Product: + __last_id: int = 0 + id: int + name: str + weight: Number + price: Number + + def __new__(cls, *args, **kwargs): + cls.__last_id += 1 + return super().__new__(cls) + + def __init__(self, name: str, weight: Number, price: Number): + self.id = self.__last_id + self.name, self.weight, self.price = name, weight, price + + def __setattr__(self, name: str, value): + typ = self.__annotations__.get(name, object) + if not isinstance(value, typ) or (typ is Number and value < 1): + raise TypeError("Неверный тип присваиваемых данных.") + super().__setattr__(name, value) + + def __delattr__(self, name: str) -> None: + if name == "id": + raise AttributeError("Атрибут id удалять запрещено.") + + +def tests(): + ... + + +if __name__ == "__main__": + import doctest + + doctest.testmod() + tests()