Загрузка данных


Задача 3. Создайте класс «Магазин» с атрибутами название и список товаров. 
Каждый товар представлен классом «Товар» с атрибутами название, цена и количество. Напишите методы для добавления товара в магазин, удаления товара из магазина и вычисления общей стоимости товаров в магазине. 
Используйте магический метод __len__ для определения количества товаров в магазине.
Самостоятельно: 
1) выполните перегрузку операций сравнения < (__lt__(self, other)), 
> (__gt__(self, other)) и == (__eq__(self, other)) двух магазинов по их общим стоимостям товаров 
(т.е. тот магазин больше, где больше стоимость товаров).
2) напишите метод класса, который будет определять наименьшую стоимость товара
3) выполните перегрузку метода __mul__(self, other), который будет повышать цену товаров на некоторый процент (other), 
а также обратный метод __rmul__(self, other). Первый метод позволит умножать объект на процент, а второй - процент на объект.


Решение. 
1. Напишем класс Товар:

# описание класса Товар
class Product:
    # конструктор для задания названия товара, цены и количества
    def __init__(self):
        self.title=''
        self.cost=0.0
        self.count=0
    
    # метод ввода данных о товаре
    def set(self):
        self.title=input("Введите название товара ")
        self.cost=float(input("Введите цену "))
        self.count=int(input("Введите количество "))

    # магический метод для преобразования данных о товаре в строку
    def __str__(self):
        # считаем стоимость товара, как цена*количество
        s=self.count*self.cost
        # возвращаем название товара, цену, количество и стоимость
        return f"{self.title} {self.cost}руб.*{self.count}шт.={s}руб."

2. В главной программе проверим, что все методы созданного класса работают:

# описываем экземпляр класса
t1=Product()
# вводим значения для товара
t1.set()
# выводим данные о товаре с помощью магического метода
print(t1)

3. Если все, что описано в пункте 2 работает, то этот код закомментируйте. Он нам больше не понадобится в таком виде.

4. Описываем класс Магазин с минимальным количеством методов – конструктором, методом заполнения магазина и вывода информации о магазине:

# описываем класс Магазин
class Shop:
    # магический метод конструктор
    def __init__(self):
        # название магазина пустое
        self.name=''
        # список товара магазина изначально пуст
        self.list=[]
        # количество товаров в магазине равно 0
        self.size=0

    # метод заполнения данных о магазине и его товарах
    def set(self):
        # вводим название магазина
        self.name=input("Введите название магазина ")
        # запоминаем количество товаров
        self.size=int(input("Введите количество товаров "))
        # цикл заполнения списка товаров
        for i in range(self.size):
            # описываем экземпляр товара
            t=Product()
            # выводим поясняющий текст
            print("-"*20,i+1,"товар","-"*20)
            # вызываем метод ввода данных о товаре
            t.set()
            # записываем в список введенный товар
            self.list.append([t.title,t.cost,t.count])
        print("Создание списка товара магазина прошло успешно...")

    # метод вывода данных о магазине и его товарах
    def __str__(self):
        # для проверки формирования списка
        # чтобы убедиться, что сформирован вложенный список товаров
        return f"\nМагазин {self.name}: {self.list}"

В главной программе проверим, что объект магазин с товарами создается с помощью команд:

# описываем экземпляр класса Магазин
s=Shop()
# вводим данные о магазине
s.set()
# выводим данные о магазине
print("Начальные данные: \n",s)

5. После этого метод __str__ изменим так, чтобы можно было выводить товары в более удобном виде:

    # метод вывода данных о магазине и его товарах
    def __str__(self):
        # для проверки формирования списка
        # чтобы убедиться, что сформирован вложенный список товаров
        # return f"\nМагазин {self.name}: {self.list}"

        print(f"\nСписок товаров магазина {self.name}:")
        # выводим список товаров в удобном для пользователя виде
        return '\n'.join(f"{self.list[i][0]} {self.list[i][1]}руб.*{self.list[i][2]}шт.={self.list[i][1]*self.list[i][2]}руб." for i in range(self.size))

После этого еще раз запустим программу и посмотрим, в каком виде выводятся данные о магазине.

6. Реализуем метод добавления данных о товаре в магазин. В класс добавим метод:

    # метод добавления товара в магазин
    def append(self,title,cost,count):
        # добавляем в список товаров пришедшие параметры
        self.list.append([title,cost,count])
        # увеличиваем размер списка товаров магазина
        self.size+=1
        print("Добавление прошло успешно...")

А в главной программе проверим добавление командами:
# добавим один товар
s.append("rabbit",260,1)
# добавим второй товар
s.append("house",500,3)
print("-"*50)
# выведем обновленные данные о магазине, проверив, что добавление работает
print(s)

7. Выполним перегрузку метода удаления товара из списка. В класс допишем метод:

    # магический метод удаления товара из магазина
    # в методе будем удалять все товары с одинаковым названием
    def __delitem__(self, title):
        # счетчик для определения номера товара в списке
        i=0
        # количество удаленных товаров из списка
        k=0
        # цикл движения по списку товаров
        while i< len(self.list):
            # если название у товара совпадает с заданным названием title
            if self.list[i][0]==str(title):
                # то удаляем все о товаре с этим названием
                del self.list[i]
                # уменьшаем размер списка
                self.size-=1
                # количество удалённых элементов увеличиваем
                k+=1
            else:
                # если удаление не проходит,
                # то переходим на следующий элемент списка
                i+=1
        # выводи сообщение об удалении
        if k!=0:
            print("Удаление прошло успешно. Удалены",k,"товаров")
        else:
            print("Удаление не выполнено. Товаров с названием",str(title),"нет")

Проверим его работу в главной программе командой:

t1=input("Введите название для удаления ")
# удаляем товар  с введенным названием
del s[t1]
# выводим измененный список товаров магазина
print(s)

8. Напишем метод поиска товара по заданному названию

    # магический метод вывода информации о товаре с заданным названием
    def __getitem__(self,title):
        # создаем временный список из названий товаров
        temp=[self.list[i][0] for i in range(self.size)]
        # среди списка названий товаров определяем,
        # есть ли товар с таким названием
        if str(title) in temp:
            # если такой товар есть, то запоминаем его номер
            number=temp.index(str(title))
            # возвращаем данные о товаре с заданным названием
            return self.list[number]
        else:
            # если товара с заданным названием нет,
            # возвращаем соответствующий текст
            return "Товара с названием "+str(title)+" нет"

Проверим работу метода командой в главной программе:

t2=input("Введите название для поиска ")
print(s[t2])

9. Определим, сколько товаров в магазине с помощью перегрузки метода __len__:

    # магический метод вычисления длины списка товаров 
    def __len__(self):
        return len(self.list)

В главной программе определим количество товаров в магазине:
print("В магазине ",len(s),"товаров")


10. Для вычисления общей стоимости товаров перегрузим, например, операцию унарного плюса:

# магический метод унарный плюс
    def __pos__(self):
        # создаем временный список со стоимостью каждого товара
        temp=[self.list[i][1]*self.list[i][2] for i in range(len(self.list))]
        # вычисляем сумму этого списка
        return sum(temp)

Для проверки работы этого метода в главной программе выполним команду +s:
print("Общая стоимость товаров в магазине=", +s)  

11. Самостоятельно напишите остальные методы.