Abstract Classes in Python
Tags: python, tutorial, coding, programming
Published: 2023-12-20 05:55:27

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:
```python
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()
```

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):

```python
def MyBook(Book):
	def __init__(self, title, author):
```

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:

```python
def MyBook(Book):
	def __init__(self, title, author, price):
		super().__init__(title, author):
		self.price = price
```

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
```
Noting that the `$` is prepended to variable names to indicate they are placeholders for variables.

I write the method as follows, using [f-strings](https://docs.python.org/3/tutorial/inputoutput.html) to produce the required output:

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

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'
```

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](https://thonny.org/) 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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/av7kj4uywd8r9kbjd5bp.png)

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](https://www.w3schools.com/python/python_inheritance.asp) 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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5m4lrh5e2rn0cbh3s73o.png)

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

![Challenge Success Message](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ts6d0aaesw6ndg0z66qz.png)

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](https://twitter.com/sarah_schlueter)
Discord: [sarahmarie73](discordapp.com/users/529736403530285076)

Thanks for reading and happy coding!

Here's the final code for the challenge:
```python
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()
```