DEV Community

Cover image for Abstract Classes in Python
Sarah Schlueter
Sarah Schlueter

Posted on

Abstract Classes in Python

Hey everyone! I've been working on HackerRank's coding challenges and decided to start documenting what I learn so that I can learn it on a deeper level and also maybe help anyone else out there also learning.

Today I am working on HackerRank's 30 Days of Code Challenges - Day 13: Abstract Classes.(https://www.hackerrank.com/challenges/30-abstract-classes)

I've been working a lot in C# for school lately, but I was previously learning Python over the summer, so I will do this challenge in Python3 as a refresher.

The task is as follows:

Given a Book class, write a MyBook class that does the following:

  • Inherits from Book
  • Has a parameterized constructor taking these 3 parameters:
    1. string title
    2. string author
    3. int price
  • Implements the Book class' abstract display() method so it prints these 3 lines:
    1. Title:, a space, and then the current instance's title.
    2. Author:, a space, and then the current instance's author.
    3. Price:, a space, and then the current instance's price.

The following starter code is provided:

from abc import ABCMeta, abstractmethod
class Book(object, metaclass=ABCMeta):
    def __init__(self,title,author):
        self.title=title
        self.author=author

    @abstractmethod
    def display(): pass

#Write MyBook class

title=input()
author=input()
price=int(input())
new_novel=MyBook(title,author,price)
new_novel.display()
Enter fullscreen mode Exit fullscreen mode

The first thing I do is check out the starter code to get a feel for what it's doing. We can see the first line of code imports tools from Python's abc module to create abstract base classes. Abstract base classes serve as blueprints for other classes, enforcing the implementation of specific methods in all subclasses that inherit from them.

The next line defines Book as an abstract base class using ABCMeta. The object indicates that Book is a new-style class inheriting from the base object class in Python.

The line def __init__(self, title, author) is the constructor method for the class. It is automatically called when a new instance of Book is created, initializing the title and author attributes of the instance.

Finally, @abstractmethod indicates that the display method is an abstract method. This means that any subclass of Book must provide its own implementation of the display method. The pass keyword is used as a placeholder indicating where code will eventually go. If a subclass does not implement this method, it cannot be instantiated (you can't create objects of that subclass).

You can read more on abstract methods and the abc module at https://docs.python.org/3/library/abc.html.

The code below where we will write the MyBook class sets the variables for title, author, and price to whatever input is provided by the user, with price being cast from a string to an integer. It instantiates an instance of MyBook called new_novel and calls the display() method.

So our first task is to create the MyBook class to inherit from the Book class. To do this, we just need to define the class and add the parent class as a parameter and add the __init__() function, which will override the parent class's __init__() function (more on this a bit):

def MyBook(Book):
    def __init__(self, title, author):
Enter fullscreen mode Exit fullscreen mode

Since we want our MyBook class to have all of the properties and methods that are in the Book class we'll use the super() function. Then we'll add in the price property, which will be specific only to our subclass. Don't forget to add it to the __init__() function as a parameter as well:

def MyBook(Book):
    def __init__(self, title, author, price):
        super().__init__(title, author):
        self.price = price
Enter fullscreen mode Exit fullscreen mode

The next step is to implement the Book class' abstract display() method. The challenge gives us the following output format:

Title: $title
Author: $author
Price: $price
Enter fullscreen mode Exit fullscreen mode

Noting that the $ is prepended to variable names to indicate they are placeholders for variables.

I write the method as follows, using f-strings to produce the required output:

def display(title, author, price):
    print(f"Title: {title}")
    print(f"Author: {author}")
    print(f"Price: {price}")
Enter fullscreen mode Exit fullscreen mode

Here I'm thinking I'm all set, so I run the code and get the following error:

- Traceback (most recent call last):

-   File "/tmp/submission/20231220/03/29/hackerrank-ff98319665ac0ee953b1fb5664e87cb3/code/Solution.py", line 27, in <module>
-     new_novel.display()
- TypeError: MyBook.display() missing 2 required positional arguments: 'author' and 'price'
Enter fullscreen mode Exit fullscreen mode

Personally, I like to debug and step through code to see where I went wrong so I'm going to paste the code into my Thonny IDE. I like Thonny for small code challenges like this because it doesn't require setting up a whole project just to run and step through code.

After stepping through the code, I can see exactly where and what the issue is:

Debugging Error In Thonny

I realize that I could also get this information from the error message itself, but in my experience, just stepping through and seeing what everything is doing at a granular level helps me figure out the problem more easily.

The message says that I'm missing two required positional arguments. Time to do some digging at this point since I'm not sure what that means. I checked out w3schools Python tutorial on inheritance. (P.S. I LOVE W3Schools).

After checking out the section for Adding Methods, I see where I went wrong adding in the variables as parameters instead of the self keyword, which I now remember is what we do in Python for implementing methods in subclasses.

Success!

Corrected Code

After running my code in the challenge code editor, I get the green success message. Challenge complete! 🎉

Challenge Success Message

I hope you enjoyed this first post. I am new to blogging and one of my goals is to get better at it so if you have any questions or feedback, please feel free to leave a comment, or connect with me:

Twitter: @sarah_schlueter
Discord: sarahmarie73

Thanks for reading and happy coding!

Here's the final code for the challenge:

from abc import ABCMeta, abstractmethod
class Book(object, metaclass=ABCMeta):
    def __init__(self,title,author):
        self.title=title
        self.author=author   
    @abstractmethod
    def display(): pass

#Write MyBook class
class MyBook(Book):
    def __init__(self, title, author, price):
        super().__init__(title, author)
        self.price = price

    def display(self):
        print(f"Title: {title}")
        print(f"Author: {author}")
        print(f"Price: {price}")


title=input()
author=input()
price=int(input())
new_novel=MyBook(title,author,price)
new_novel.display()
Enter fullscreen mode Exit fullscreen mode

Top comments (4)

Collapse
 
ranjancse profile image
Ranjan Dailata

Nicely written blog post. Congrats :)

Collapse
 
sarahs profile image
Sarah Schlueter

Thank you! That means a lot!

Collapse
 
nebulonix profile image
Nebulonix

Great ideia! This will help me advance on abstract classes and also help me with another way of studying. Congrats!

Collapse
 
sapiensanalytics profile image
Sapiens Analytics

Good stuff @sarahmarie73