Pre-class Assignment: object inheritance and composition#

Day 7#

CMSE 202#

(image from realpython.com)

✅ Put your name here

#

Goals for Today’s Pre-Class Assignment#

By the end of this assignment, you should be able to:

  • Understand the concept of object inheritance and composition

  • Practice using inheritance and composition using custom classes

Assignment instructions#

Watch the video (you will watch video in twice: first time for inheritance (from beginning till 8:30 minutes) and second time for composition - the from 8:30 till the end), read all included and linked content, and complete any assigned programming problems. Please get started early, and come to office hours if you have any questions and make use of Slack!

This assignment is due by 11:59 p.m. the day before class, and should be uploaded into the appropriate “Pre-class assignments” submission folder. Submission instructions can be found at the end of the notebook.

Download an additional file#

For this assignment, you’ll need the Animal.py file you worked with previously. If you don’t already have it handy, you may need to re-download the file and save it in the same folder as this Jupyter notebook. The file contains definition of the class you will use in the assignment. You can find the file here:

https://raw.githubusercontent.com/msu-cmse-courses/cmse202-supplemental-data/main/code_samples/Animal.py


1. Object inheritance#

Objects present a powerful programing paradigm (called Object Oriented Programming - OOP) by combining the attributes and methods for easy access and use. As mentioned before, objects are everywhere in Python.

Object inheritance is a programming technique that allow us to combine the objects in a way such that one object inherits properties from another object. This enables us to create a hierarchy of objects. But no worries, we will practice that later in the assignment!

Do this: To learn more about the idea behind using inheritance with Python objects, watch the video below (watch only first 8:30 minutes) and answer the questions below the video.

# Don't forget to watch the video in full-screen mode!
from IPython.display import YouTubeVideo  
YouTubeVideo("RiRrcCUyn4M",width=800,height=450,end=510)  # objects 

Quick questions#

After watching the video above, answer the following two questions to overview the most important facts about objects.

Question 1: What is the relationship between the Dog and Animal objects in the video?

Do This - Erase the contents of this cell and replace it with your answer to the above question! (double-click on this text to edit this cell, and hit shift+enter to save the text)

Question 2: In your own words, explain why would we might use object inheritance? In what ways might it make programming efforts easier?

Do This - Erase the contents of this cell and replace it with your answer to the above question! (double-click on this text to edit this cell, and hit shift+enter to save the text)


2. Using inheritance#

The main information we have to remember about inheritance is that objects have an “is a(n)” relationship: the Lion object is an Animal object, with a few attributes and methods tailored for a lion. When defining new object for lions, all Animal-specific attributes for lions are pre-defined in one place and there is no need to specify them explicitly when we want to use the Lion object.

2.1 Using inheritance to build our Animal kingdom#

Let’s now use the knowledge of the inheritance to simplify the creation of our Zoo. In the previous in-class assignment, we created the Zoo by:

  • creating an ‘Animal’ object for all animals in our Zoo

  • defining properties for every single animal object that we put in our Zoo

That was tedious task involving a lot of typing, as we had to define the requested area and the number of zookeepers for every animal individually. With the use of inheritance, that will be significantly easier and will require less typing, which usually means less possibilities for making mistakes. We will create an object (class) for each animal based on the already created object Animal - this way each animal will inherit properties from pre-construct Animal object.

To create a Zoo using multiple types of Animal objects, we would need to create the following classes:

  1. create a class for lions: Lion

  2. create a class for zebras: Zebra

  3. create a class for penguins: Penguin

Note: Before continuing, make sure you can access or have re-downloaded the “Animal.py” file and saved it in the same folder as this Jupyter notebook. If you don’t have the file next to the notebook, download it now. The file is required for the rest of the assignment.

Do this: Run the following cell to make sure the the “Animal” class can be imported from the Animal.py file.

# The magic command below tells Jupyter Notebook to automatically load classes and methods from external files 
# in case they have changed from last load time;
# This is needed when you change the Animal.py file
%reload_ext autoreload
%autoreload 2

# import animal object that will be used to create other objects
# note how the Animal class is imported!
from Animal import Animal

2.2 Creating object for lions#

According to the “plan” above, we have to create objects for each animal we want to have in the Zoo.

Do this: Check the code bellow, read carefully all comments and fill-in the missing pieces - enter 2 values. Then use the cell below to test if new object is working correctly.

# here is the class for lions; read all comments and add missing 
class Lion(Animal):
    """
        This is a Lion class, used to store information about lions.
    """
    def __init__(self, name):
        """ Initialize Lion class. All we need now is the animal nick name. """
        
        # this class is only for lions, so we can define animal 'kind' as lion
        kind = "lion"
        
        # this calls initialization of Animal class and sets the animal to given 'name'      
        super().__init__(kind,name)     
        
        #--- in lines below we define attribute values for lions--#
        
        # default required area: 
        # ENTER VALUE (arbitrary one or one you used in the previous 
        # in-class assignment)
        self.required_area = 
        
        # set default number of Zoo keepers needed for lions: 
        # ENTER VALUE (arbitrary one or one you used in the previous 
        # in-class assignment)
        self.required_staff = 
        
    
# use this cell to test the 'Lion' class
alex = Lion("Alex")
alex.set_arrive_to_zoo("2019-01-01")

# printing animal's names
print("{0} is a {1}, arrived to Zoo on {4} and requires {2} m^2 of space and {3} keepers to be happy.".format(
    alex.get_name(), alex.get_kind(), alex.get_required_area(), alex.get_number_keepers(), alex.get_arrive_to_zoo()))

Note: If running the cell above does not return an error, you are good to move forward.

Question 3: The Lion class does not have the methods set_arrive_to_zoo() and get_required_area() defined within it and yet, the code above works when you print the information about alex, how can this be? Hint: something to do with inheritance!

Do This - Erase the contents of this cell and replace it with your answer to the above question! (double-click on this text to edit this cell, and hit shift+enter to save the text)

2.3 Creating objects for zebras and penguins#

The next steps in our plan are creating objects for zebras and penguins.

Do this: Using the code above (for creating the object for a lion), create objects for zebras and penguins. As before, run the cell below to test of your objects are correct.

# Here is a starting point for the Zebra class;
# use the Lion class as a guide to complete this class
class Zebra(Animal):
    """
        This is a Zebra class, used to store information about zebras.
    """
    def __init__(self, name):
        """
        Initialize Zebra class. All we need now is the animal nickname.
        """
        # ---- fill in missing code----#
        
    
class Penguin(Animal):
    pass     # delete this line and fill in missing pieces for Penguin class; use class definitions above as a guide

2.4 Test your code!#

Do this: Now use the code in the cell below to test your new classes. The code creates two objects with animal names from Madagascar movie and prints their names with some additional information. The output should be something like this (depending on what you used for your animal attributes):

Marty is a zebra and requires 100 m^2 of space and 1 keepers to be happy.
Skipper is a penguin and requires 300 m^2 of space and 0.5 keepers to be happy.

If that is the case, you are good to move on!

# use this cell to test the 'Lion' class
marty = Zebra("Marty")
skipper = Penguin("Skipper")
# printing animal's names
print("{0} is a {1} and requires {2} m^2 of space and {3} keepers to be happy.".format(marty.get_name(), marty.get_kind(), marty.get_required_area(), marty.get_number_keepers()))
print("{0} is a {1} and requires {2} m^2 of space and {3} keepers to be happy.".format(skipper.get_name(), skipper.get_kind(), skipper.get_required_area(), skipper.get_number_keepers()))

Part 3. Object composition#

The main idea behind object composition is to combine properties (attributes and methods) from different objects into single one. You’re going to watch the second part of the previous video to learn a bit about the idea behind object composition through the provided example.

Composition is a programming technique that allow us to combine the objects in a way that one object is built from other objects. Objects from which new object is built, can be completely non-related and are usually combined because each object brings a piece of puzzle to the newly combined object.

Do this: Watch the video below (from 8:30 min on) how composition can be used in Python. Answer the questions below the video.

# Don't forget to watch the video in full-screen mode!
from IPython.display import YouTubeVideo  
YouTubeVideo("RiRrcCUyn4M",width=800,height=450,start=515)  # objects

Quick question#

After watching the video above, answer the following question to review the motivation behind object composition.

Question 4: When might you use object composition? In what ways might it make our programming efforts easier?

Do This - Erase the contents of this cell and replace it with your answer to the above question! (double-click on this text to edit this cell, and hit shift+enter to save the text)

3.1 Few important things before combining objects#

Object composition is combining different objects into new one, where each object brings part of properties to the newly created class. Objects do not inherit or share anything and the only common thing could be the fact that they are combined into one object. Another way to think about composition is that it represents a “has a” relationship. That is, an object/class has a component that might be another class/object.

3.2 Defining a Zoo object#

We can use object composition to create a new object, Zoo, which will be a place where we can store Animal objects. In the previous in-class assignment, we were creating our “Zoo” by storing animals in a list. We can extend that idea by creating a class Zoo that will hold all animals in the Zoo and also offer methods to manipulate attributes of Zoo class.

First we should define what properties (attributes and methods) we have to implement in our Zoo class:

  • our Zoo class should have at least the following attributes:

    • list of animals in the Zoo, these should be Animal objects

    • list of zookeepers (we will create the class later)

  • and at least the following methods:

    • add new animal

    • add new zookeeper (we will create the method later)

    • get total Zoo area

    • get total number of Zookeepers

You might remember from the previous in-class assignment that we created most of the required attributes and methods during that class. All we have to do now is to combine them into a single class.

3.3 Adding missing code in methods get_animal_names() and total_area()#

Most of the before mentioned methods are already in the Zoo class. Two methods, get_animal_names() and total_area(), are in the class but have no content - most of the method’s body is missing.

Do this: Your task is to add the missing code into methods get_animal_names() and total_area() (last two methods in the cell) so they will perform their designed functionality. Last part of the previous in-class assignment was similar to this task - printing animal names and computing the Zoo’s total area. Use ideas/steps from that assignment, but pay attention how animal objects are stored.

Hint: here we use dictionary to store animal objects, before we were using lists. Adding and retrieving items is slightly different.

# Here is a skeleton of Zoo class with few methods defined, but with some missing.
class Zoo:
    """
        Class for Zoo.
    """
    def __init__(self, name):
        """ Initialize the Zoo object
        Input:
        name : a name for the Zoo
        """
        # name of the Zoo
        self.name = name
        # we are using dictionaries for animals and personnel
        self.animals = {}
        self.zookeepers = {}

    def add_animal(self, animal):
        """ Adds an animal to the zoo. """
        # we use animal's name as a key in the dictionary
        name = animal.get_name()
        self.animals[name] = animal
        return len(self.animals)

    def add(self, animal):
        """ Shorter name of function to add animals to the Zoo. """
        return self.add_animal(animal)
    
    def get_animals(self):
        """ Return all animals in the zoo."""
        return self.animals

    def number_animals(self):
        """ Return number of animals in the zoo."""
        return len(self.animals)

    def remove(self, name):
        """
        Remove animal from the Zoo for given name.
        If the name does not exist, error is printed.
        """
        if name in self.animals:
            # yes, animal with given name is in the Zoo
            del self.animals[name]
        else:
            print("Animal with given name is not in", self.name, "Zoo.")

    
    def number_zookeepers(self):
        """ Return number of zookeepers in the zoo."""
        return len(self.zookeepers)

    def get_animal_names(self, sort=False):
        """
        Return animal names in the Zoo.
        Return sorted names if parameters sorted==True
        """
        names = []
        
        #
        # add the content of this method; the method should return names of all animals in the Zoo
        #
        
        if sort == True:
            # we have to return sorted names; so sort the names
            names = sorted(names)
    
        return names
        
    def total_area(self):
        """
        Return the total Zoo area to host all animals defined in the object.
        """
        area = 0
        
        #
        # add the content of this method; the method should return total area required by animals
        # use the code from the previous in-class assignment - code for computing required area
        #
        
        return area
        

3.4 Test your code!#

Do this: Now use the code in the cell below to test your class. The code creates few objects with animal names from Madagascar movies, adds them into the ‘NYC ZOO’ and prints out their names and the total Zoo area.

# create object for defining few characters from The Madagascar
# the code may look long, but will produce only 5 lines of output. 
# You are encouraged to go through the code to get familiar with the usage of the Zoo class.
# creating all classes
alex = Lion('Alex')
marty = Zebra('Marty')
skipper = Penguin('Skipper')
kowalski = Penguin('Kowalski')

# create a Zoo and adding Alex and Skipper
zoo = Zoo('NYC ZOO')
zoo.add(alex)
zoo.add_animal(skipper)

# get animal names and print them
names = zoo.get_animal_names(True)
print("\nAlex and Skipper?", names)

# add few more names
zoo.add(marty)
zoo.add_animal(kowalski)

# get animal names and print them
names = zoo.get_animal_names()
print("\nAlex, Skipper, Marty, and Kowalski?", names)

#
# remove Alex
zoo.remove('Alex')
# get animal names and print them
names = zoo.get_animal_names()
print("\nAll, but Alex?", names)

#
# Add him back
zoo.add(alex)

# get animal names and print them
names = zoo.get_animal_names()
print("\nAlex, Skipper, Marty, and Kowalski?", names)

print("\nTotal Zoo area is:", zoo.total_area(), "m^2.")

Does it work?#

If the output above looks like this (the total area depends on your numbers and will probably be different than 1300):

Alex and Skipper? ['Alex', 'Skipper']

Alex, Skipper, Marty, and Kowalski? ['Alex', 'Skipper', 'Marty', 'Kowalski']

All, but Alex? ['Skipper', 'Marty', 'Kowalski']

Alex, Skipper, Marty, and Kowalski? ['Skipper', 'Marty', 'Kowalski', 'Alex']

Total Zoo area is: 1300 m^2.

then you succeeded and you are almost done!


4. Additional reading (not mandatory)#

Additional reading in this pre-class assignment is might come across very technical and it extends beyond the scope of this class. However, if you are interested in learning more on the topics, read on:

Important: The web pages above include comprehensive information about classes and you are NOT expected to read (or even remember) everything presented!


Follow-up Questions#

Copy and paste the following questions into the appropriate box in the assignment survey include below and answer them there. (Note: You’ll have to fill out the assignment number and go to the “NEXT” section of the survey to paste in these questions.)

  1. Inheritance: what is the relationship of an object that inherits properties from another object? (Remember the relation of object Dog to object Animal)

  2. Composition: in your own words, explain the main difference between inheritance and composition.

  3. When might you use inheritance and when might you use composition?


Assignment wrap-up#

Please fill out the form that appears when you run the code below. You must completely fill this out in order to receive credit for the assignment!

from IPython.display import HTML
HTML(
"""
<iframe 
	src="https://cmse.msu.edu/cmse202-pc-survey" 
	width="800" 
	height="800px" 
	frameborder="0" 
	marginheight="0" 
	marginwidth="0">
	Loading...
</iframe>
"""
)

Congratulations, you’re done!#

Submit this assignment by uploading it to the course Desire2Learn web page. Go to the “Pre-class assignments” folder, find the appropriate dropbox link, and upload it there.

See you in class!

© Copyright 2024, Department of Computational Mathematics, Science and Engineering at Michigan State University