"

12 Object-Oriented Programming and Pedestrian Crossings

Learning Objectives

In this module, you will:

  • Learn the basics of Object-Oriented Programming
  • Practice creating classes and using inheritance
  • Connect Object-Oriented Programming with modelling real-world systems like pedestrian crossings

Objects & Classes

Object-Oriented Programming (OOP) is a programming approach that allows users to organize data and methods into objects. Objects allow programmers to simplify code and perform actions that interact with other objects. For this module, we will be using traffic lights to explore some concepts of OOP.

Objects are created using classes. Classes define the variables and methods that each instance of an object will contain. They are often likened to blueprints since they define what objects can do, but every object created from a class is considered its own instance. Take pedestrian lights, for example, all pedestrian lights have the same three states (Stop, Caution, and Go) and have the same systematic approach to how they change. However, they differ in the length of time they remain in the “go” state and where they’re placed. They’re all pedestrian lights and work the same, even if they differ in certain areas.

Creating a Class

Before we add any data or methods, we must start by defining the class. That is done with  class ClassName: .  Everything in the indented space underneath the class header is part of the class body. For example, defining a class called PedestrianLight would look like this:

class PedestrianLight:

# Class body

Variables

The variables of a class are stored in variables similar to how they’ve been done throughout the rest of CSC108. There are three types of variables that we’ll use in this module: class variables, instance variables, and private variables.

Class Variables

Class variables are variables that are shared across all instances of a class. Meaning, the value of the variable will be the same for every object made from the same class. For example, to store the possible states of a pedestrian light in a list, we would store it in a class variable. Note that declaring a class variable looks the same as how a variable is normally declared in a Python program.

class PedestrianLight:

possible_states = ["stop", "caution", "go"]

Instance variables

Instance variables are variables that are unique to each instance of a class. For example, our PedestrianLight class would have an instance variable called current_state since the state of each pedestrian light varies. One way of declaring an instance variable in a class is done by writing   variable_name: variableType .

class PedestrianLight:

#Class variables

possible_states = ["stop", "caution", "go"]

 

#Instance variables

current_state: str

Private variables

Private variables are variables that are protected from code outside of the class and that cannot be accessed outside of the class. These variables are often used to keep information that shouldn’t be easily changed, like the location of a pedestrian light. Technically, it is possible to access them outside of the class, but it serves as a style convention to denote how the variable should be treated.

class PedestrianLight:

#Class variables

possible_states = ["stop", "caution", "go"]

 

#Instance variables

current_state: str

_location: str

Creating an instance

Constructors

To create instances of a class, a __init__ or constructor method needs to be defined. This method is what creates an object and decides what happens when an object is initialized. The first parameter of the __init__ method is always the self parameter. Often, the __init__ function is used to assign initial values to variables and anything necessary to set up the object.

class PedestrianLight:

# Class variables

possible_states = ["stop", "caution", "go"]

# Instance variables

current_state: str

countdown_duration: int

remaining_duration: int

_location: str

def __init__(self, countdown_duration: int, location: str):

    self.countdown_duration = countdown_duration

    self._location = location

Note that to assign values to an object, you must add the self keyword before the variable name. Otherwise, everything that is done within the __init__ method remains within the scope of the __init__ method.

Initializing and using an instance

To initialize an instance of a class, in the program you intend to use the class in, use the __init__ method to pass in any variables needed. While the first parameter of the __init__ method is self, you can ignore it and pass in the value of all the other variables.

p = PedestrianLight(30, "St George St & Harbord St")

Now that there are values associated with the variables in the PedestrianLight class and an instance of it, variables can be accessed both inside and outside the class. To access variables inside the class, add the self keyword before the variable name. To access variables outside of the class, add the instance which you want to access the variable of in front of the variable name.

# Accessing variables within the class 

print(self.current_state)

# Accessing variables outside the class

p = PedestrianLight(30, "St George St & Harbord St")

print (p.current_state)

You may have noticed that in certain areas of Toronto, there are pedestrian lights that have longer crossing times than others for the same distance of crossing. This is due to changes proposed by the Vision Zero Road Safety Plan, which suggested longer crossing times to ensure that elder citizens would be able to finish crossing the road (City of Toronto, 2016).

For this activity, initialize a pedestrian light that has a crossing time of 40 seconds rather than the 30 seconds like the example.

Methods

Methods in classes are written very similarly to how they are regularly written. Almost all methods of classes will always have the self parameter. An exception is class methods, but these will not be discussed in the module.

Using methods within the class is done very similarly to how variables are accessed. Inside the class, add the self keyword before the method. Outside the class, add the instance of the method before the method. For this example, assume there is a function called countdown.

# Accessing methods within the class 

self.countdown()

# Accessing methods outside the class

p = PedestrianLight(30, "St George St & Harbord St")

p.countdown()

Inheritance

Inheritance is a way to create a class that inherits all the methods and variables of another class. This allows programmers to create variants of classes without having to reuse code. The class that is being inherited from is called the parent class, while the class that is inheriting from the parent class is known as the child class.

To create a child class, instead of writing  class ClassName , the class is defined using   class ChildClass(ParentClass): . Since this is a child class, the attributes and methods, including the __init__ method, will be the same as the parent class, even if they aren’t explicitly stated in the child class. In the child class, you can add more variables or any methods that do not already exist within the parent class as needed. For this example, we will be creating a child class of PedestrianLight that will represent Accessible Pedestrian Signals (APS). This class will have a new attribute that stores what direction the crossing is facing by using an integer. 0 will represent the north/south direction and 1 will represent the east/west direction.

class AccessibleLight(PedestrianLight):

direction: int

Polymorphism

Polymorphism refers to methods that have the same name but may do different things depending on what class the object is an instance of. In other words, a child class can have methods that have the same name as a method in the parent class. When the method is called on an instance of the child class, the version of the method will call the child class’s version because the method has been overridden. Otherwise, it will call the parent class’s function. Furthermore, you can call methods from the child class by using super() or referencing the parent class.

class AccessibleLight(PedestrianLight):

sound: int

def __init__(countdown_duration: int, location: str, direction: int):

    super().__init__(countdown_duration, location)

    # PedestrianLight.__init__(countdown_duration, location)

      would also do the same thing

When a regular pedestrian light changes to the “go” state, the display changes but doesn’t make a clear sound. To accommodate visually impaired folks, APS will emit a cuckoo sound or a melody called the “Canadian Melody” depending on the direction the pedestrian can cross (City of Toronto, 2025). The APS will emit a cuckoo sound when the pedestrian can cross in the north/south direction and the “Canadian Melody” if they can cross in the east/west direction.

References

City of Toronto. (2016). Road Safety Plan (RSP) 2017-2021 [Report]. https://www.toronto.ca/wp-content/uploads/2017/12/8b9f-VisionZero-RoadSafetyPlan-StaffReport-10-Jun-2016.pdf

City of Toronto. (2025). Accessible pedestrian signals. Accessible Pedestrian Signals. https://www.toronto.ca/services-payments/streets-parking-transportation/traffic-management/traffic-signals-street-signs/types-of-traffic-signals/accessible-pedestrian-signals/

License

Icon for the Creative Commons Attribution-NonCommercial 4.0 International License

Introducing Critical Algorithmic Literacies in Computer Programming Copyright © by Rutwa Engineer; Moeez Omair; Alisha Hasan; Adelina Patlatii; Lanz Angeles; Sana Sarin; Madhav Ajayamohan; and Izabelle Marianne is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License, except where otherwise noted.