🧱 Section 2: Create the Base Class Shell (Animal)

📝 Summary (What you will do)

In this section, you will create the Animal base class. This class will be the “blueprint” for all animals in the game (Dog, Cat, Bird, etc.).

Right now, this class won’t do everything yet. It’s a shell (starter structure) that:

  • Stores animal data (name, hunger, happiness, cleanliness, level, XP)
  • Uses an abstract method to require that every animal type has a special_action() later

This section is the first big step into Object-Oriented Programming.


✅ Checklist (You must complete these)

  • Find the comment in pet_manager.py that says where future code will go
  • Add the Animal class below Section 1
  • Make sure Animal inherits from ABC
  • Write the __init__ method with the correct instance variables
  • Add the @abstractmethod special_action() method exactly as shown
  • Keep the “future code” comment at the bottom of the section

No new constants/settings are added in this section, so you do not need to edit the top-of-file constants.


🎓 Core Concepts (New learning for this section)

1) What is a “base class”?

A base class is a general class that other classes will build from.

Example:

  • Animal is the base class (general rules for all animals)
  • Later we’ll create classes like Dog(Animal) and Cat(Animal)
  • Those are subclasses (more specific versions)

Why do this?

  • You avoid repeating the same code in every animal type.
  • You build shared features once, then reuse them.

2) What is an abstract class (ABC)?

An abstract class is a special kind of base class that is not meant to be used directly.

In this project:

  • We do NOT want someone creating a plain Animal() in the game.
  • We want them to create a Dog(), Cat(), Bird(), etc.

So we make Animal an abstract base class using:

  • ABC
  • @abstractmethod

3) What does @abstractmethod do?

@abstractmethod forces subclasses to include a required method.

That means:

  • If you create class Dog(Animal):
  • Dog MUST define a special_action() method

If you forget, Python will not let you create a Dog object.

This is helpful because it keeps your program organized and consistent.

4) Encapsulation and _private-ish variables

You’ll notice variables like:

  • self._hunger
  • self._happiness

The underscore _ is a Python convention that means:

“This should be treated like private data. Don’t change it directly from outside the class.”

Later, we’ll use properties to safely access these values.

5) Why random starting stats?

We use random.randint() so each animal begins slightly differently.
That makes the program more interesting and more “real” without adding complexity.


💻 Code to Write (Type this by hand in pet_manager.py)

Directions:

  1. Open pet_manager.py
  2. Find the line near the bottom that says:
    # (Future code will go below: Animal class, species, Player, UI, main loop)
  3. Below Section 1, type the following code by hand:

Code image: s02-code


🧠 Code Review & Key Concepts (What important lines do)

Inheritance from ABC

class Animal(ABC):

This means:

  • Animal is an abstract base class
  • You’re creating a general “Animal” blueprint
  • You are not meant to create plain Animal() directly later

Constructor (__init__)

def __init__(self, name: str):

This runs automatically when an animal is created.

Example (later):

dog = Dog("Buddy")

This will call the Animal constructor first, setting up the stats.

Instance variables

self._hunger = random.randint(20, 50)

These are instance variables, meaning each animal object gets its own copy.

So one Dog might start with hunger 25, another might start with hunger 45.

Abstract method

@abstractmethod
def special_action(self) -> str:

This forces every subclass (Dog/Cat/Bird) to create its own version of:

  • special_action()

The raise NotImplementedError is a safety reminder:

“If this gets called, something is wrong—because subclasses should replace it.”


🧪 Test File: s2_test.py

✅ Create this file

Create a new file in the same folder called:

s2_test.py

💻 Code to write in s2_test.py

Code image: s02-test

🧠 What this test is doing (and how it works)

  • It tries to create an Animal("Testy")
  • Because Animal contains an @abstractmethod, Python should block this
  • When Python blocks it, it raises a TypeError
  • The test catches that error and prints PASS

✅ Run the test:

python s2_test.py

If you see PASS, your base class shell is correctly set up and ready for the next section.