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

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

Класс LoyaltyCard: баллы только для чтения, начисление и списание с проверками, уровень карты — вычисляемое свойство. Покупки нескольких клиентов и золотые карты.

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

«Кофейная лавка» запускает карту лояльности. С каждой покупки на карту начисляется 5 % суммы баллами (округление вниз), баллами можно оплатить часть следующих покупок. Чем больше клиент потратил за всё время, тем выше уровень карты: до 5000 ₽ — «базовый», до 20 000 ₽ — «серебряный», от 20 000 ₽ — «золотой».

Баллы — те же деньги, поэтому главное требование — через публичный интерфейс баланс нельзя изменить в обход правил. В проекте пригодится весь модуль: внутренние атрибуты, свойства только для чтения, проверки и raise.

Шаг 1. Карта и начисление

[ ]Упражнение 1Класс LoyaltyCard решено

Допишите класс LoyaltyCard. LoyaltyCard("Анна") — новая карта: владелец в атрибуте owner, баллов 0, покупок на 0 ₽. Свойства только для чтения: points — текущие баллы, total — сумма всех покупок.

Метод earn(amount) регистрирует покупку на amount рублей: прибавляет её к сумме покупок, начисляет баллы — 5 % суммы с округлением вниз — и возвращает число начисленных баллов. Если сумма не больше нуля — ValueError, и на карте ничего не меняется.

class LoyaltyCard:
    def __init__(self, owner):
        ...

    @property
    def points(self):
        ...

    @property
    def total(self):
        ...

    def earn(self, amount):
        ...

Шаг 2. Уровень и списание

[ ]Упражнение 2Уровень карты и списание баллов решено

Добавьте в класс (скопируйте его из шага 1 и допишите):

  • свойство level — уровень по сумме покупок total: меньше 5000 — "базовый", меньше 20 000 — "серебряный", иначе — "золотой";
  • метод spend(points) — списывает баллы. Если points не больше нуля — ValueError("списать можно только положительное число баллов"), если баллов на карте меньше — ValueError("недостаточно баллов"); в обоих случаях баланс не меняется.
class LoyaltyCard:
    # скопируйте сюда __init__, points, total и earn из шага 1

    @property
    def level(self):
        ...

    def spend(self, points):
        ...

Шаг 3. Покупки Анны

[ ]Упражнение 3Начисления за месяц решено

Анна сделала за месяц четыре покупки — суммы в списке purchases. Заведите ей карту anna, зарегистрируйте покупки по порядку и сохраните в earned список начисленных за каждую баллов. В anna_points сохраните её баллы, в anna_level — уровень карты.

purchases = [1200, 3500, 800, 900]
anna = ...
earned = ...
anna_points = ...
anna_level = ...

Шаг 4. Оплата баллами

[ ]Упражнение 4Попытка списать лишнее решено

Анна хочет оплатить кофе 1000 баллами — у неё столько нет. Попробуйте списать 1000 баллов, перехватите ValueError и сохраните текст сообщения в error_text. Затем спишите 100 баллов и сохраните остаток в left.

error_text = ...
left = ...

[ ]Баланс не перепишешь
try:
    anna.points = 1_000_000
except AttributeError as error:
    print("не вышло:", error)
print(anna.points)
Выводсохранённый · нажмите «Выполнить», чтобы получить свой
не вышло: property 'points' of 'LoyaltyCard' object has no setter
220

Шаг 5. Золотые клиенты

[ ]Упражнение 5Кому золотую карту решено

В словаре clients — имена и суммы покупок каждого клиента за год. Заведите по карте на клиента, зарегистрируйте все его покупки и сохраните в cards словарь «имя → карта». В gold сохраните список имён клиентов с золотым уровнем — в порядке словаря.

clients = {
    "Анна": [1200, 3500, 800, 900],
    "Борис": [15000, 7000],
    "Вера": [300, 450],
    "Глеб": [9000, 9000, 2500],
}
cards = ...
gold = ...

Итог

[ ]Карты клиентов
for name, card in cards.items():
    print(f"{name}: {card.total} ₽, {card.points} баллов, уровень {card.level}")
Выводсохранённый · нажмите «Выполнить», чтобы получить свой
Анна: 6400 ₽, 320 баллов, уровень серебряный
Борис: 22000 ₽, 1100 баллов, уровень золотой
Вера: 750 ₽, 37 баллов, уровень базовый
Глеб: 20500 ₽, 1025 баллов, уровень золотой
Итог появится, когда решите все упражнения урока, — в нём ответы. Ячейку можно и выполнить.

У Бориса и Глеба — золотые карты: за год они потратили больше 20 000 ₽. Анна — на серебряном уровне, Вера — на базовом. И через интерфейс карты баланс не изменить мимо earn и spend: запись в points даёт AttributeError, а неверные суммы — ValueError с понятным сообщением.

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

Посмотрите на класс со стороны: снаружи видны только owner, points, total, level, earn и spend. Как карта хранит данные внутри — её личное дело; можно, например, начать хранить историю покупок списком, и код снаружи этого не заметит. В следующем модуле объекты научатся красиво печататься и сравниваться.

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

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

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