Course 1.1Lesson 5 of 5
In this project we build a library system with two classes. A Book knows its title and author and who has it, and a Library keeps a list of books and a log, and can add a book, find a book by title ignoring capitals, lend a book to a person, take it back, and list the books that are available. The rules live inside the classes: a book that does not exist, a book that is already out and a return of a book that is not out are refused with a ValueError. We plan the classes and a table of expected states, build the program, test the refused actions, and extend the library with due dates and a limit on the books of a person.
Try the code and the simulations beside the lesson.
After this lesson you can
A small library lends books. It must know which books it has, who has borrowed each one, and a record of what happened. It must refuse the actions that make no sense: to borrow a book that does not exist, to borrow a book that is already out, and to return a book that is not out.
A good way to find the classes: look for the nouns of the description, and ask what each one knows and does.
| Noun | It knows | It does |
|---|---|---|
Book | its title, its author, who has it | says whether it is available |
Library | its list of books, the log | adds a book, finds a book, lends, takes back, lists the available |
The person is just a name here, a text. It does not need a class yet. (You could make one later, if a person must have a limit or an address.)
Work out what should happen, before you write any code. The library has Dune, Emma and Ulysses. Six actions are run.
| Action | Result | Who has what |
|---|---|---|
Asha borrows dune | ok (capitals do not matter) | Asha has Dune |
Ravi borrows Dune | refused: Dune is with Asha | no change |
Meera borrows Hamlet | refused: no such book | no change |
give back Dune | ok | nobody has it |
give back Dune again | refused: the book is not out | no change |
Ravi borrows Emma | ok | Ravi has Emma |
At the end the available books are Dune and Ulysses.
The row of the table that matters most is "no change". After a refused action, the state must be exactly as it was. Add to your test:
| Test | Expected |
|---|---|
| borrow a book that is out | refused, and the borrower is unchanged |
| return a book twice | the second is refused, and the log has one return |
| a library with no books | available() gives [], and every borrow is refused |
| two libraries | adding a book to one does not add it to the other |
The last row tests the shared default trap. It would fail if self.books were a default list.
Every method checks its rule first and changes the state last, so a refused call never leaves a half-made change.
Pick one or two, and do them without looking at a solution. Write the expected states first.
books_of(person) helps.Library.count_out() gives the number of books that are out.datetime module.by_author(name) gives the titles.Member class. A member has a name, a list of the books that the member holds, and a limit.Library.__init__.lower() on both.borrower before the log is written.Start with two quick questions. Each New numbers gives you a fresh one, so you can practise as long as you like.
Then the labs and the problems:
Try each one on your own first. If you are stuck, open a hint. Then check with Show the answer.
Library.__init__ make self.books = [] inside, and not as a default parameter?borrow check the rules?Every lesson is open to read. Enrolling also lets you:
Log in to join the discussion.
Loading…
This lesson is free to read. Enroll free to keep your place and take the tests.