Python Class Activity: Building a Basic Book Class

Objective

By the end of this activity, you will:

  1. Understand how to define a class in Python.
  2. Create a constructor method (__init__) to initialize object attributes.
  3. Define and use instance methods.
  4. Create objects (instances) of your class and call methods on them.

Activity Instructions

Step 1: Create a Basic Class

  1. Open your Python environment (codeboard.io).
  2. Start by defining a class called Book.
class Book:
pass # We'll fill this in as we go!

Step 2: Add Attributes Using the __init__ Method

  1. In the Book class, add an __init__ method. This method will initialize the attributes of the Book class.
  2. Each book should have the following attributes:
    • title: The title of the book.
    • author: The author of the book.
    • pages: The number of pages in the book.
    • read: A boolean attribute to track if the book has been read (default to False).
  3. Update your class:
class Book:
def __init__(self, title, author, pages):
self.title = title
self.author = author
self.pages = pages
self.read = False # Default value

Step 3: Create an Instance of the Book Class

  1. Now, let’s create a Book object.
my_book = Book("The Great Gatsby", "F. Scott Fitzgerald", 180)
  1. Print the title, author, and pages attributes of my_book to confirm they are set correctly:
print("Title:", my_book.title)
print("Author:", my_book.author)
print("Pages:", my_book.pages)
print("Read:", my_book.read)

Step 4: Add a Method to Mark the Book as Read

  1. Add a method called mark_as_read to the Book class. This method should change the read attribute to True.
  2. Update your class with the new method:
class Book:
def __init__(self, title, author, pages):
self.title = title
self.author = author
self.pages = pages
self.read = False

def mark_as_read(self):
self.read = True
  1. Now, call the mark_as_read method on my_book and check if it worked:
my_book.mark_as_read()
print("Read:", my_book.read)

Step 5: Add a __str__ Method

  1. The __str__ method is used to provide a readable string representation of an object.
  2. Add a __str__ method to display the book’s information:
class Book:
def __init__(self, title, author, pages):
self.title = title
self.author = author
self.pages = pages
self.read = False

def mark_as_read(self):
self.read = True

def __str__(self):
read_status = "Yes" if self.read else "No"
return "Title: "+self.title+", Author: "+self.author+", Pages: "+str(self.pages)+", Read: "
  1. Now, print the my_book object:
print(my_book)

Step 6: Add a Class and Instance Variables

  1. Create a class called Book.
  2. Add a class variable called total_books, which will keep track of the total number of books created.
class Book:
# Class variable to keep track of the total number of books
total_books = 0

def __init__(self, title, author, pages):
self.title = title # Instance variable
self.author = author # Instance variable
self.pages = pages # Instance variable
self.read = False # Instance variable to track if the book has been read
Book.total_books += 1 # Update the class variable

# Test by creating a few book objects and printing the total_books
book1 = Book("The Catcher in the Rye", "J.D. Salinger", 234)
book2 = Book("To Kill a Mockingbird", "Harper Lee", 281)

print("Total books created:", Book.total_books)

Discussion Point: Notice that total_books is a class variable. This means it’s shared among all instances of Book. The instance variables (title, author, pages, read) are unique to each object.

Step 7: Understanding Local Variables vs. Instance Variables

  1. Add a method called get_summary to the Book class that briefly describes the book.
  2. Inside get_summary, create a local variable called summary.
class Book:
total_books = 0

def __init__(self, title, author, pages):
self.title = title
self.author = author
self.pages = pages
self.read = False
Book.total_books += 1

def get_summary(self):
summary = f"{self.title} by {self.author}, {self.pages} pages." # Local variable
return summary

# Test by creating a book and calling get_summary
book = Book("1984", "George Orwell", 328)
print(book.get_summary())

Discussion Point: Here, summary is a local variable—it exists only within the get_summary method. In contrast, title, author, and pages are instance variables that are available to other methods in the Book class.


Step 8: Add Getters, Setters, and Mutators

  1. Add getter methods for each attribute (e.g., get_title, get_author, get_pages).
  2. Add setter methods for each attribute (e.g., set_title, set_pages).
  3. Add a mutator method called mark_as_read to change the read status to True.
class Book:
total_books = 0

def __init__(self, title, author, pages):
self.title = title
self.author = author
self.pages = pages
self.read = False
Book.total_books += 1

# Getter methods
def get_title(self):
return self.title

def get_author(self):
return self.author

def get_pages(self):
return self.pages

# Setter methods
def set_title(self, title):
self.title = title

def set_pages(self, pages):
self.pages = pages

# Mutator to mark the book as read
def mark_as_read(self):
self.read = True

# Test the getters, setters, and mutator
book = Book("Pride and Prejudice", "Jane Austen", 432)
print("Title:", book.get_title())
book.set_title("Pride &

Step 9: Test Your Knowledge

  1. Create more books: Create additional instances of Book with different titles, authors, and page counts.
  2. Mark books as read: Use the mark_as_read method on some books and print them to see the change.
  3. Add a new method: Add a method to the Book class that calculates the estimated time to finish reading based on a given reading speed (e.g., time_to_finish(reading_speed), where reading_speed is pages per hour).

Step 10: Bonus Challenge

  1. Create a Library Class:
    • This class should store multiple Book objects in a list.
    • It should have methods to:
      • Add a book to the library.
      • Display all books in the library.
      • List only books that haven’t been read.

Example Solution for the Bonus Challenge

class Library:
def __init__(self):
self.books = []

def add_book(self, book):
self.books.append(book)

def display_books(self):
for book in self.books:
print(book)

def display_unread_books(self):
print("Unread Books:")
for book in self.books:
if not book.read:
print(book)

# Example Usage
library = Library()
library.add_book(my_book)
library.display_books()
library.display_unread_books()

Reflection Questions

  1. What is the purpose of the self parameter in class methods?
  2. Why do we use the __init__ method?
  3. How does the mark_as_read method change the object’s state?

Scroll to Top