Домашнє завдання

Тема 25 · Класи й обʼєкти

Усі три рівні — про одну програму: маленький облік бібліотеки. Наскрізний приклад лекції (продажі) ми лишаємо позаду навмисно: клас треба вміти описати для своєї предметної області, а не лише повторити чужий.

Працюй у звичайному файлі biblioteka.py, а перевірки пиши поруч, унизу того самого файлу, під захисною умовою:

if __name__ == "__main__":
    # тут усі assert-и
    ...

Тоді файл можна і запускати (python3 biblioteka.py), і імпортувати з іншого місця. Якщо жоден assert не спрацював, програма закінчується мовчки — це і є «зроблено».


рівень 1Рівень 1 — База

Напиши клас Книга з полями назва, автор, рік, примірників і методом доступна(), що повертає True, якщо примірників більше нуля.

Обовʼязково:

Зроблено, якщо цей блок перевірок проходить без жодного спрацювання:

книга = Книга("Кобзар", "Шевченко", 1840, 3)
assert книга.доступна() is True
assert repr(книга) == "Книга('Кобзар', 'Шевченко', 1840)"   # свій формат — свій рядок

for погані in [("", "Шевченко", 1840, 3), ("Кобзар", "Шевченко", 1200, 3),
               ("Кобзар", "Шевченко", 1840, -1)]:
    try:
        Книга(*погані)
    except ValueError:
        pass
    else:
        raise AssertionError(f"перевірка не спрацювала: {погані}")

рівень 2Рівень 2 — Плюс

Додай клас Бібліотека, який зберігає книжки й веде журнал подій.

  1. У __init__ створи два поля: self.книжки = [] і self.журнал = [].
  2. Метод додати(книга) — з перевіркою isinstance(книга, Книга), інакше TypeError. Кожне додавання пише рядок у self.журнал.
  3. Метод видати(назва) — зменшує примірників на одиницю й повертає True; якщо книжки немає або примірників нуль, повертає False. Обидва випадки — у журнал.
  4. Атрибут класу максимум_на_руки = 5 (незмінне число!) і метод, який ним користується.
  5. __repr__ для бібліотеки: скільки назв і скільки примірників усього.

Зроблено, якщо:

python а, б = Бібліотека(), Бібліотека() а.додати(Книга("Кобзар", "Шевченко", 1840, 1)) assert len(а.журнал) == 1 and len(б.журнал) == 0 assert а.журнал is not б.журнал


рівень 3Рівень 3 — Виклик

Три задачі. Кожну можна зробити незалежно.

А. Пастка своїми руками. Свідомо зроби помилку: перенеси журнал = [] з __init__ у тіло класу Бібліотека. Напиши тест, який цю помилку ловить, — такий, що падає на зіпсованій версії й проходить на правильній. Поверни правильний варіант і залиш тест у файлі.

Б. Порахуй ціну гнучкості. Створи 200 000 обʼєктів Книга і заміряй памʼять (tracemalloc.get_traced_memory() до і після). Потім додай у клас __slots__ = ("назва", "автор", "рік", "примірників") і повтори замір.

В. Кому цей клас не потрібен. Знайди у власному коді (або напиши навмисно) клас, який складається лише з __init__ і методів отримати_X / встановити_X. Перепиши той самий сенс без класу.

Зроблено, якщо:

python try: книга.примірникив = 3 # одруківка except AttributeError: print("✅ __slots__ ловить одруківку")


Підказки