An introductory course to the Python 3 programming language, with a curriculum aligned to the Certified Associate in Python Programming (PCAP) examination syllabus (PCAP-31-02).
https://knowledgebase.hyperlearning.ai/courses/introduction-to-python
In this module we will introduce the object oriented programming (OOP) paradigm - a means to model the world and our software applications as objects that interact with each other. Supported by hands-on examples in Python, we will explore the fundamental concepts in object oriented programming, including:
# Write a program using imperative programming to calculate the sum of a given list of numbers
sum = 0
my_numbers = [1, 2, 3, 4, 5]
for number in my_numbers:
sum += number
print(f'The sum of the numbers in {my_numbers} is: {sum}')
from functools import reduce
# Write a program using functional programming to calculate the sum of a given list of numbers
def add(x, y):
return x + y
sum = reduce(add, my_numbers)
print(sum)
# Write a program using functional programming and a lambda function to calculate the sum of a given list of numbers
sum = reduce(lambda x, y: x + y, my_numbers)
print(sum)
# Update sys.path so that it can find our example module
import sys
sys.path.append('examples/formulapy')
# Import our example module containing our Car class definition
from example import Car
# Try to create a new car object without the required arguments
my_car = Car()
# Create a new car object
mercedes_f1 = Car(number_doors = 0,
registration_number = 'MERC 123',
make = 'Mercedes',
model = 'AMG F1 W10 EQ Power+',
year_manufactured = 2019,
maximum_speed = 200,
acceleration_rate = 20,
deceleration_rate = 50)
# Print the type of object that this is i.e. the class that was used to instantiate this object
print(type(mercedes_f1))
# Print a string representation of the car object
print(mercedes_f1)
# Create another new car object
ferrari_f1 = Car(number_doors = 0,
registration_number = 'MON 888',
make = 'Ferrari',
model = 'SF1000',
year_manufactured = 2020,
maximum_speed = 200,
acceleration_rate = 15,
deceleration_rate = 60)
# Print a string representation of the car object
print(ferrari_f1)
# Access and display the maximum speed of the Mercedes car object
print(mercedes_f1.maximum_speed)
# Access and display the registration number of the Ferrari car object
print(ferrari_f1.registration_number)
# Modify the maximum speed of the Mercedes car object
mercedes_f1.maximum_speed = 220
print(mercedes_f1)
# Modify the registration number of the Ferrari car object
ferrari_f1.registration_number = 'SCUD 888'
print(ferrari_f1)
# Delete the number of doors attribute belonging to the Mercedes car object
print(mercedes_f1)
print(mercedes_f1.number_doors)
del mercedes_f1.number_doors
print(mercedes_f1)
print(mercedes_f1.number_doors)
# Create a new car object
redbull_f1 = Car(number_doors = 0,
registration_number = 'RB 999',
make = 'Red Bull',
model = 'RB9',
year_manufactured = 2013,
maximum_speed = 210,
acceleration_rate = 18,
deceleration_rate = 60)
# Print a string representation of the car object
print(redbull_f1)
# Delete the previously created car object
del redbull_f1
# Try to print a string representation of the deleted car object
print(redbull_f1)
# Access an object's attribute references
print(mercedes_f1.__dict__)
# Access a class's name
print(Car.__name__)
# Access an object's class name (or type name) from which it was instantiated
print(mercedes_f1.__class__)
print(mercedes_f1.__class__.__name__)
# Access the name of the module that a class was defined in
print(Car.__module__)
print(mercedes_f1.__class__.__module__)
# Access a class's base classes
print(Car.__bases__)
print(mercedes_f1.__class__.__bases__)
# Add a completely new attribute to one of our car objects that was not defined in the Car class definition
print(mercedes_f1)
setattr(mercedes_f1, 'height_mm', 950)
setattr(mercedes_f1, 'width_mm', 2000)
setattr(mercedes_f1, 'weight_kg', 743)
setattr(mercedes_f1, 'power_kw', 750)
print(mercedes_f1)
# Invoke the Car.accelerate() method on an existing car object
ferrari_f1.accelerate()
# Update sys.path so that it can find our formulapy module
import sys
sys.path.append('examples/formulapy')
# Import our new vehicle domain data model module
from model import Aircraft, Car, RoadVehicle, Vehicle
# Create a new car object
mclaren_p1 = Car(number_engines = 1,
engine_horsepower_kw = 673,
chassis_height_mm = 1188,
chassis_width_mm = 1946,
chassis_depth_mm = 4588,
make = 'McLaren',
model = 'P1',
year_manufactured = 2013,
maximum_speed_mph = 217,
acceleration_rate_mps = 20,
deceleration_rate_mps = 50,
registration_number = 'MCL P1')
# Print a string representation of the car object
print(mclaren_p1)
# Access an attribute that is set in the Vehicle superclass
print(mclaren_p1.maximum_speed_mph)
# Access an attribute that is set in the RoadVehicle superclass
print(mclaren_p1.last_mot_date)
# Access an attribute that is set in the Car subclass
print(mclaren_p1.number_wheels)
# Invoke a method that is defined in the Vehicle superclass
print(mclaren_p1.accelerate())
# Invoke a method that is defined in the Car class that itself invokes methods defined in the Vehicle superclass
print(mclaren_p1.avoid_collision())
# Create a new aircraft object
airbus_a380 = Aircraft(number_engines = 4,
engine_horsepower_kw = 670,
chassis_height_mm = 24100,
chassis_width_mm = 79800,
chassis_depth_mm = 72700,
make = 'Airbus',
model = 'A380',
year_manufactured = 2005,
maximum_speed_mph = 736,
acceleration_rate_mps = 30,
deceleration_rate_mps = 30,
minimum_speed_mph = 150)
# Print a string representation of the aircraft object
print(airbus_a380)
# Invoke a method that is defined in the Vehicle superclass
print(airbus_a380.accelerate())
# Invoke a method that is defined in the Aircraft class that overrides a method defined in the Vehicle superclass
print(airbus_a380.brake())
# Define a simple superclass
class ClassA:
var1 = 'A'
def __init__(self, a1, a2, a3):
self.attr1 = a1
self.attr2 = a2
self.attr3 = a3
def method1(self):
return self.attr1 + self.attr2
# Define a simple class derived from ClassA
class ClassB(ClassA):
var1 = 'B'
def __init__(self, b1, b2, b3):
super().__init__(b1, b2, b3)
self.attr4 = b2 * b3
def method1(self):
return self.attr1 * self.attr2
# Define another simple class derived from ClassA
class ClassC(ClassA):
def __init__(self, c1, c2, c3):
super().__init__(c1, c2, c3)
self.attr4 = c2 - c3
def method1(self):
return self.attr1 - self.attr2
# Define a class that is derived from both ClassB and ClassC
class ClassD(ClassB, ClassC):
pass
# Create and test an instance of ClassB
class_b_object = ClassB(1, 2, 3)
print(f'ClassB attr1: {class_b_object.attr1}')
print(f'ClassB attr2: {class_b_object.attr2}')
print(f'ClassB attr3: {class_b_object.attr3}')
print(f'ClassB attr4: {class_b_object.attr4}')
print(f'ClassB var1: {class_b_object.var1}')
print(f'ClassB method1(): {class_b_object.method1()}')
# Create and test an instance of ClassC
class_c_object = ClassC(1, 2, 3)
print(f'ClassC attr1: {class_c_object.attr1}')
print(f'ClassC attr2: {class_c_object.attr2}')
print(f'ClassC attr3: {class_c_object.attr3}')
print(f'ClassC attr4: {class_c_object.attr4}')
print(f'ClassC var1: {class_c_object.var1}')
print(f'ClassC method1(): {class_c_object.method1()}')
# Create and test an instance of ClassD
class_d_object = ClassD(1, 2, 3)
print(f'ClassD attr1: {class_d_object.attr1}')
print(f'ClassD attr2: {class_d_object.attr2}')
print(f'ClassD attr3: {class_d_object.attr3}')
print(f'ClassD attr4: {class_d_object.attr4}')
print(f'ClassD var1: {class_d_object.var1}')
print(f'ClassD method1(): {class_d_object.method1()}')
# Access the resolved MRO for each class
print(f'ClassA MRO:\n{ClassA.__mro__}\n')
print(f'ClassB MRO:\n{ClassB.__mro__}\n')
print(f'ClassC MRO:\n{ClassC.__mro__}\n')
print(f'ClassD MRO:\n{ClassD.__mro__}\n')
# List the names of all the subclasses directly derived from the Vehicle class
print([cls.__name__ for cls in Vehicle.__subclasses__()])
# List all the subclasses directly derived from the Vehicle class
print(Vehicle.__subclasses__())
# Create a function to list all direct and indirect subclasses of a given class
def find_all_subclasses(cls):
return set(cls.__subclasses__()).union(
[subclass for c in cls.__subclasses__() for subclass in find_all_subclasses(c)])
# List all the subclasses that are both directly and indirectly derived from the Vehicle class
print(find_all_subclasses(Vehicle))
# Define a class with a non-parameterized constructor
class ClassX:
def __init__(self):
print(f'Creating an instance of {type(self).__name__}...')
def sum(self, a, b):
return a + b
# Create a new instance of ClassX
class_x_object = ClassX()
# Invoke a method on the new object of type ClassX
print(class_x_object.sum(100, 38))
# Define a class without an explicit constructor
class ClassY:
def product(self, a, b):
return a * b
# Create a new instance of ClassY
class_y_object = ClassY()
# Invoke a method on the new object of type ClassY
print(class_y_object.product(13, 20))
# Define a class with a constructor that explicitly invokes the constructor of another class
class ClassZ:
def __init__(self):
ClassX.__init__(self)
def modulus(self, a, b):
return a % b
# Create a new instance of ClassZ
class_z_object = ClassZ()
# Invoke a method on the new object of type ClassZ
print(class_z_object.modulus(103, 4))
# Define a class that contains 'private' variables
class User:
def __init__(self, fname, lname, email, dob, postal_address):
self.fname = fname
self.lname = lname
self.email = email
self.__dob = dob
self.__postal_address = postal_address
def display_dob(self):
print(self.__dob)
def display_postal_address(self):
print(self.__postal_address)
# Create a new user
barack_obama_user = User('Barack', 'Obama', '[email protected]', '04/08/1961', '1600 Pennsylvania Avenue')
# Display the user's private dob using the display_dob() method
barack_obama_user.display_dob()
# Display the user's private dob by directly accessing the dob attribute using dot notation
print(barack_obama_user.dob)
# Display the user's private dob indirectly by accessing the mangled dob attribute
print(barack_obama_user._User__dob)
# Create a new aircraft object
airbus_a380 = Aircraft(number_engines = 4,
engine_horsepower_kw = 670,
chassis_height_mm = 24100,
chassis_width_mm = 79800,
chassis_depth_mm = 72700,
make = 'Airbus',
model = 'A380',
year_manufactured = 2005,
maximum_speed_mph = 736,
acceleration_rate_mps = 30,
deceleration_rate_mps = 30,
minimum_speed_mph = 150)
# hasattr()
print( hasattr(airbus_a380, 'engine_horsepower_kw') )
print( hasattr(airbus_a380, 'last_mot_date') )
print()
# type()
print( type(airbus_a380) )
print( type([1, 2, 3]) )
print( type(('a', 'b', 'c')) )
print( type({1: 'a', 2: 'b', 3: 'c'}) )
print( type(Vehicle) )
print( type(str) )
print( type(int) )
print( type(str) )
print( type('Hello World!') )
print( type(38) )
print( type(0.5) )
print( type(True) )
print( type(False) )
print( type(47 & 55) )
print( type(None) )
print()
# issubclass()
print( issubclass(type(airbus_a380), Vehicle) )
print( issubclass(Aircraft, Vehicle) )
print( issubclass(Vehicle, Aircraft) )
print( issubclass(Vehicle, Vehicle) )
print( issubclass(Vehicle, object) )
print( issubclass(str, object) )
print( issubclass(list, object) )
print( issubclass(tuple, object) )
print( issubclass(dict, object) )
print( issubclass(type(ClassD(1, 2, 3)), ClassA) )
print( issubclass(type(None), ClassA) )
print( issubclass(type(None), object) )
print()
# isinstance()
print( isinstance(airbus_a380, Aircraft) )
print( isinstance(airbus_a380, Vehicle) )
print( isinstance(airbus_a380, object) )
print( isinstance(airbus_a380, Car) )
print( isinstance(None, object) )