Нашли ошибку?
Скачать чистый
мини-проект≈ 20 минупражнения: 0 из 5

Мини-проект: прайс-лист

Два прайса поставщика сводятся в один: товары с __repr__, __eq__ и __hash__, дубли убирает set, сортировка по цене и по названию, товары, у которых изменилась цена.

Python запустится при первом выполнении

Поставщик прислал «Кофейной лавке» два прайса — утренний и вечерний. Многие позиции в них повторяются, а у некоторых за день изменилась цена. Нужно свести прайсы в один без повторов, отсортировать его и найти товары с новой ценой. Всё это делается магическими методами модуля: __repr__, __eq__, __hash__ и __lt__.

Шаг 1. Товар

[ ]Упражнение 1Товар для прайса решено

Допишите класс Product:

  • __repr__ возвращает Product('Латте', 220);
  • товары равны, если совпадают и название, и цена; сравнение с чужим типом — NotImplemented;
  • __hash__ согласован с __eq__, чтобы товары можно было класть в set.
class Product:
    def __init__(self, name, price):
        self.name = name
        self.price = price

    def __repr__(self):
        ...

    def __eq__(self, other):
        ...

    def __hash__(self):
        ...

Шаг 2. Порядок в прайсе

В уроке о сортировке был совет: если у товаров несколько равноправных порядков, __lt__ не объявляют, а передают key=. Здесь случай другой: прайс поставщика по договорённости всегда идёт от дешёвого к дорогому, и этот порядок — естественный для прайса. Поэтому зададим его в классе.

[ ]Упражнение 2Сначала дешёвые решено

Добавьте в класс (скопируйте его из шага 1 целиком) метод __lt__: товар «меньше», если он дешевле, а при равной цене — если его название раньше по алфавиту. Сравнение с чужим типом — NotImplemented.

class Product:
    # скопируйте сюда __init__, __repr__, __eq__ и __hash__ из шага 1

    def __lt__(self, other):
        ...

Шаг 3. Два прайса в один

[ ]Упражнение 3Без повторов решено

По спискам пар morning и evening создайте товары и сохраните в all_items общий список — сначала утренние, потом вечерние. В unique сохраните множество (set) товаров без повторов, а в n_dupes — сколько позиций оказались повторами.

morning = [("Латте", 220), ("Чай", 120), ("Раф", 260), ("Какао", 190), ("Эспрессо", 150)]
evening = [("Чай", 120), ("Латте", 240), ("Эспрессо", 150), ("Капучино", 220), ("Раф", 260)]
all_items = ...
unique = ...
n_dupes = ...

Шаг 4. Прайс по цене

[ ]Упражнение 4Сортировка решено

Сохраните в price_list список товаров из unique, отсортированный по естественному порядку товаров (шаг 2), а в cheapest3 — названия трёх самых дешёвых.

price_list = ...
cheapest3 = ...

[ ]Сводный прайс
for p in price_list:
    print(p)
Выводсохранённый · нажмите «Выполнить», чтобы получить свой
Product('Чай', 120)
Product('Эспрессо', 150)
Product('Какао', 190)
Product('Капучино', 220)
Product('Латте', 220)
Product('Латте', 240)
Product('Раф', 260)
Вывод появится, когда решите упражнение «Сортировка», — иначе он подскажет ответ. Ячейку можно и выполнить.

Шаг 5. Что подорожало

Один и тот же товар с разными ценами — это два разных товара для __eq__: в unique остались оба.

[ ]Упражнение 5Товары с новой ценой решено

Сохраните в alphabet названия всех товаров unique по алфавиту (повторяющиеся названия — подряд), а в changed — список названий, которые встречаются в unique больше одного раза, то есть товаров, у которых за день изменилась цена. Каждое название — один раз, по алфавиту.

alphabet = ...
changed = ...

Итог

[ ]Отчёт по прайсам
print(f"позиций в двух прайсах: {len(all_items)}, повторов: {n_dupes}")
print("сводный прайс:", price_list)
for name in changed:
    prices = sorted(p.price for p in unique if p.name == name)
    print(f"изменилась цена: {name}, цены в прайсах {prices}")
Выводсохранённый · нажмите «Выполнить», чтобы получить свой
позиций в двух прайсах: 10, повторов: 3
сводный прайс: [Product('Чай', 120), Product('Эспрессо', 150), Product('Какао', 190), Product('Капучино', 220), Product('Латте', 220), Product('Латте', 240), Product('Раф', 260)]
изменилась цена: Латте, цены в прайсах [220, 240]
Итог появится, когда решите все упражнения урока, — в нём ответы. Ячейку можно и выполнить.

Из десяти позиций двух прайсов три оказались повторами, в сводном прайсе семь товаров. Цена за день изменилась только у латте: утром 220 ₽, вечером 240 ₽. Заметьте, как удобно смотреть на такие списки, когда у товара есть __repr__: print(price_list) сразу показывает и названия, и цены.

Выводы с ответами появятся, когда решите все упражнения урока.

В проекте два порядка: естественный порядок прайса (по цене) задан в классе, а порядок по алфавиту — снаружи, ключом. Если бы ни один порядок не был главным, честнее было бы обойтись одним key=, как советует урок о сортировке. В следующем модуле появятся иерархии классов: разные виды скидок, которые касса применяет одинаково.

Практика по модулю

Задачи по ООП в Python для самостоятельной практики появятся в разделе «Задачи → ООП в Python».

Нашли ошибку?