Skip to content
BetaDE
Lesson 28 of 35Python

Python · Lesson 28 · 60 minutes

Boss level: the library

What you'll learn

  • Design your own class with several methods
  • Report errors with your own exceptions
  • Save data in a file and load it again

The intermediate boss

In the intermediate stage you learned to catch errors, write files, build your own classes and test code. Now it all comes together: a small management program, just like real libraries use.

Reminder: raising exceptions yourself

A good class reports errors loudly instead of quietly doing the wrong thing:

class Safe:
    def __init__(self, code):
        self.code = code
        self.open = False

    def unlock(self, attempt):
        if attempt != self.code:
            raise ValueError("Wrong code!")
        self.open = True


s = Safe(1234)
try:
    s.unlock(1111)
except ValueError as error:
    print("Caught:", error)

Reminder: writing files

with open("list.txt", "w") as file:
    for name, age in [("Ana", 12), ("Ben", 13)]:
        file.write(f"{name};{age}\n")

print(open("list.txt").read())

Strategy for the boss

  1. Data first: self.books is a dictionary title → True/False. Everything else works with it.
  2. Then method by method: test each one straight away with a few lines below the class.
  3. Error cases last: what happens with unknown books or books that are already lent out?

Keep building: a method load(filename) that reads a saved file back in – then your library even survives the end of the program.

Your task

Your turn

Build the class Library. add(title) adds a book (available). lend(title) lends it out – unknown titles raise a KeyError, books that are already lent raise a ValueError. give_back(title) makes it available again. available() returns a sorted list of the available titles. save(filename) writes one line per book, Title;yes or Title;no (available or not).

class Library:
    def __init__(self):
        self.books = {}  # title → True (available) or False (lent out)

    def add(self, title):
        pass

    def lend(self, title):
        pass

    def give_back(self, title):
        pass

    def available(self):
        pass

    def save(self, filename):
        pass


library = Library()
library.add("Momo")
library.add("Matilda")
library.lend("Momo")
print(library.available())

Solve it without hints to earn a ⭐ on your progress page.

Show solution

Try it yourself first – mistakes teach you the most. Here is one possible solution:

class Library:
    def __init__(self):
        self.books = {}  # title → True (available) or False (lent out)

    def add(self, title):
        self.books[title] = True

    def lend(self, title):
        if title not in self.books:
            raise KeyError(title)
        if not self.books[title]:
            raise ValueError(f"{title} is already lent out")
        self.books[title] = False

    def give_back(self, title):
        self.books[title] = True

    def available(self):
        return sorted(title for title, free in self.books.items() if free)

    def save(self, filename):
        with open(filename, "w") as file:
            for title, free in self.books.items():
                file.write(f"{title};{'yes' if free else 'no'}\n")


library = Library()
library.add("Momo")
library.add("Matilda")
library.lend("Momo")
print(library.available())