Object oriented programming: Fitting functionality into single objects

Object oriented programming is a programming paradigm that uses something called objects to fit lots of functionality and data into a single object.

class Student:
    def __init__(self, name, age):
        self.name = name
        self.age = age
        self.grades = {}

    def add_grade(self, subject, grade):
        self.grades[subject] = grade

    def calculate_gpa(self):
        if not self.grades:
            return 0  # No grades available

        total_grade_points = sum(self.grades.values())
        num_subjects = len(self.grades)
        return total_grade_points / num_subjects

    def display_grades(self):
        print(f"Grades for {self.name}:")
        for subject, grade in self.grades.items():
            print(f"{subject}: {grade}")

# Example usage:
student1 = Student("Alice", 18)
student1.add_grade("Math", 90)
student1.add_grade("English", 85)
student1.add_grade("History", 92)

student2 = Student("Bob", 19)
student2.add_grade("Math", 78)
student2.add_grade("English", 92)
student2.add_grade("History", 88)

# Display grades and calculate GPA
student1.display_grades()
print(f"{student1.name}'s GPA: {student1.calculate_gpa()}")

print("\n")

student2.display_grades()
print(f"{student2.name}'s GPA: {student2.calculate_gpa()}")
Grades for Alice:
Math: 90
English: 85
History: 92
Alice's GPA: 89.0


Grades for Bob:
Math: 78
English: 92
History: 88
Bob's GPA: 86.0

As you can see above, we can have a “self-sufficient” data-type that contains both data and functionality that they can use to manipulate themselves.

Object oriented programming mimics real life

To understand object oriented programming, it is best to think of it as a way to mimic how we think about things in real life.

Method

An object in real life is something that “contains” lots of functionalities by itself. For example, a car is an object that can drive, park, and honk.

If we try to model above car in Python, we can do it like so:

class Car:
    def drive(self):
        print("Driving")
        # Do something to drive the car
    
    def park(self):
        print("Parking")
        # Do something to park the car
    
    def honk(self):
        print("Honking")
        # Do something to honk the car

For the usage is as simple like we’re using a function:

car = Car()
car.drive()
car.park()
car.honk()

Attributes

In addition to having methods, objects also have attributes. Attributes are data that the object contains. For example, a car has a color, a model, and a year.

class Car:
    def __init__(self, color, model, year):
        self.color = color
        self.model = model
        self.year = year

To access the attributes, we can do it like so:

car = Car("red", "Toyota", 2019)
print(car.color)
print(car.model)
print(car.year)

Term: Class and object

For now let’s take a step back and talk about some terminology.

Class

Class is a blueprint, it will define what kind of data and functionality an object will have.

class Car:
    def __init__(self, manufacturer, model, year):
        self.manufacturer = manufacturer
        self.model = model
        self.year = year
        self.speed = 0

    def accelerate(self):
        self.speed += 5
        print(f"{self.manufacturer} {self.model} is accelerating. Current speed: {self.speed} mph")

    def brake(self):
        if self.speed > 0:
            self.speed -= 5
            print(f"{self.manufacturer} {self.model} is braking. Current speed: {self.speed} mph")
        else:
            print(f"{self.manufacturer} {self.model} is already stationary.")

As you can see above, we have a class called Car. It has 3 data attributes (which is defined in __init__ method): manufacturer, model, and year. It also has 2 “functionalities” (which more commonly called methods): accelerate and brake.

Object

Object is a derived instance of a class, basically a class is a blueprint and an object is the actual thing that is built from the blueprint.

# Creating an object from `Car` class
car1 = Car("Toyota", "Camry", 2022)
car2 = Car("Ford", "Mustang", 2023)

# Using the objects
car1.accelerate()
car2.accelerate()
car1.brake()
car2.brake()

init method

__init__ method is a special method that is called when an object is created. It is usually used to initialize the data attributes of the object.

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
        self.level = "Beginner"
    
person = Person("Alice", 18)
print(person.name)
print(person.age)
print(person.level)
Alice
18
Beginner

You can see on above code that we are assigning three data attributes to the object: name, age, and level. name and age are assigned from the arguments that we passed when creating the object, while level is assigned with a default value of "Beginner".

self is a special keyword, that we’ll learn in just a bit.

Using instance methods

Instance methods are methods that are defined inside a class, and can be used by the object of that class.

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
        self.level = "Beginner"

    def greet(self):
        print(f"Hello, my name is {self.name}!")
    
person = Person("Alice", 18)
person.greet()
Hello, my name is Alice!

Mutating instance attributes

Instance attributes can be mutated by two ways

Directly accessing the attribute on the object

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
        self.level = "Beginner"

person = Person("Alice", 18)
print(person.age)
person.age = 19
print(person.age)
18
19

Mutating the attribute using a method

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
        self.level = "Beginner"
    
    def set_age(self, age):
        self.age = age

person = Person("Alice", 18)
print(person.age)
person.set_age(19)
print(person.age)
18
19

self keyword

We’ve mentioned self keyword a couple of times now, but what is it? Basically self is a reference to the object itself. It is a special keyword that is used to access the “current” object’s attributes and methods.

Two objects created from the same class are independent

Two objects created from the same class are independent from each other. Mutating one object’s attribute will not affect the other object’s attribute.

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
        self.level = "Beginner"
    
    def set_age(self, age):
        self.age = age

person = Person("Alice", 18)
person2 = Person("Bob", 19)

print(person.age)
print(person2.age)

person.set_age(19)
person2.set_age(20)

print(person.age)
print(person2.age)

Exercise

!pip install rggrader
# @title #### Student Identity
student_id = "your student id" # @param {type:"string"}
name = "your name" # @param {type:"string"}
# @title #### 04. Automobile Dealership
from rggrader import submit

# In this assignment, you will implement classes in Python. 

# Here's the details of the task:
# 1. Create a class named 'Car' having attributes 'manufacturer' and 'model'.
# 2. The 'Car' class should have the following methods:
#     a. `display_info`: This should return a string "This car is a {manufacturer} {model}". The placeholders correspond to the 'manufacturer' and 'model' respectively.
#     b. `honk`: This should return a string "{manufacturer} says honk honk!". The placeholder corresponds to the 'manufacturer'.
#     c. `set_car_info`: This should be a method to set a new 'manufacturer' and 'model' for the car.
# 
# The initial creation of a Car object should take the 'manufacturer' and 'model' as arguments.
# Here is an example of what your code should emulate:

my_car = Car("Toyota", "Corolla")
answer = []
answer.append(my_car.display_info()) # This should add "This car is a Toyota Corolla" to the 'answer' list
answer.append(my_car.honk()) # This should add "Toyota says honk honk!" to the 'answer' list
my_car.set_car_info("Ford", "Mustang")
answer.append(my_car.display_info()) # This should add "This car is a Ford Mustang" to the 'answer' list
answer.append(my_car.honk()) # This should add "Ford says honk honk!" to the 'answer' list
# Finally submit your answer
assignment_id = "04-classes"
question_id = "04_automobile_dealership"
submit(student_id, name, assignment_id, str(answer), question_id)
Back to top