PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteiTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
Build a small library-management program around three objects: Book for a book’s state, Borrower for a member and their loans, and Library to coordinate the collection and borrowing operations. The most important design rule is to keep checkout and return consistent: when a book’s availability changes, the borrower’s loan record must change at the same time.
How should you model the library?
Start with the things your program needs to represent, then give each object a clear responsibility. In a first version, a book can represent one borrowable copy. If the program later needs to track several copies of the same title, model copies separately rather than treating a title as a single available item.
Book: stores a title, author, and availability. An identifier can distinguish it from other books with the same title.Borrower: stores a member’s identity and the books currently checked out to them.Library: owns or coordinates the inventory and provides operations such as adding, searching, listing, checking out, and returning books.
This is a composition-based design: a library contains books and works with borrowers. It gives each object a useful role without requiring a hierarchy of specialized subclasses.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →How do checkout and return work?
Treat each operation as a state transition. A checkout should confirm that the book belongs to the library and is available before marking it unavailable and adding it to the borrower’s loans. A return should confirm that the borrower has the book, then mark it available and remove it from that loan record.
#1 Best Overall
Here is a compact in-memory example. It uses object identity to check collection membership; an application that loads or reconstructs objects from storage should instead use stable identifiers.
class Book:
def __init__(self, title, author, book_id):
self.title = title
self.author = author
self.book_id = book_id
self.available = True
class Borrower:
def __init__(self, name, borrower_id):
self.name = name
self.borrower_id = borrower_id
self.borrowed_books = []
class Library:
def __init__(self):
self.books = []
def add_book(self, book):
self.books.append(book)
def checkout_book(self, book, borrower):
if book not in self.books:
raise ValueError("Book is not in this library")
if not book.available:
raise ValueError("Book is already checked out")
book.available = False
borrower.borrowed_books.append(book)
def return_book(self, book, borrower):
if book not in borrower.borrowed_books:
raise ValueError("This borrower does not have this book")
borrower.borrowed_books.remove(book)
book.available = True
The checks happen before either side of the relationship is changed, so an invalid operation does not leave the book marked unavailable without a matching loan entry. For a program used by multiple people or threads, or one with a database, the two updates also need to be treated as one transaction so another operation cannot observe a half-finished change.
Rank #2
What does this project teach about OOP?
Encapsulation: keep related state and behavior together
A Book holds its own availability, and a Borrower holds its loan list. The library’s checkout and return methods coordinate changes to both. This makes the rules visible in operations instead of scattering them through a menu or command-line interface. In Python, an underscore-prefixed name signals that an attribute or method is intended for internal use, but it does not make that instance variable inaccessible; this is a convention, not enforced privacy.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Abstraction: expose actions, not internal bookkeeping
A caller can request checkout_book or return_book without directly editing the library’s collection, the book’s availability, and the borrower’s list. That small interface is easier to use correctly and gives you one place to enforce rules such as membership and availability.
Composition: represent the relationships you actually have
A library has a collection of books and interacts with borrowers. Representing those relationships with objects is a natural starting point. Inheritance is available in Python, but a beginner project does not need a subclass for every type of book or member. Add a subclass or override a method when there is genuinely shared behavior and a meaningful variation in that behavior.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.How far should the first version go?
Keep the scope tied to what you want to learn. An in-memory model is enough to practice objects and state transitions. A more structured project can add persistence, a separate interface, and rules for loans without making those features prerequisites for learning OOP.
| Area | Small learning version | More structured version |
|---|---|---|
| Domain and organization | Book, Borrower, and Library coordinate the core behavior (Pluralsight lab description: Guided: Build a Library System with Python). |
Models plus dedicated services and exceptions, as described by the educational Library-Management-OOP project (version 2.0.0): project page. |
| Persistence | In-memory collections; state is lost when the program exits. | JSON storage and configuration, features listed by the project page above. |
| Interface | Direct method calls or a simple menu. | A separate command-line interface layer, listed by the project page above. |
| Best fit | Practicing object state and collaboration. | Practicing modularity and a broader feature set. |
The larger example also lists members, due dates, overdue handling, and search. Those are useful extensions when the basic workflow is working, not requirements for every library program. The Pluralsight page describes its guided lab as intermediate, lasting 45 minutes, and lists July 16, 2026 as its last-updated date; check the page for current availability and details.
Quick Recap
Best Value
What should you add after the core workflow?
- Stable identifiers: use a unique book or copy ID for membership checks and lookups, especially if objects are loaded from JSON or rebuilt between runs.
- Validation: reject duplicate identifiers, unknown borrowers, unavailable books, and returns that do not match an active loan.
- Persistence: save and reload records if the program must retain state after it closes. JSON is one option for a learning project; ensure saved book and borrower records refer to the same stable IDs.
- Search and listing: offer title, author, or ID lookups without making the interface manipulate the underlying collections directly.
- Due dates and overdue handling: add these when the loan rules require them, and make the policy explicit rather than embedding unexplained date checks in the interface.
- Tests: check successful checkout and return as well as failure cases, including an unknown book, an already borrowed book, and a return by the wrong borrower.
- Separate layers: as the program grows, keep domain models, service logic, persistence utilities, configuration, exceptions, and interface code in distinct areas. This is an organizational option, not a prerequisite for the small version.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

