0% found this document useful (0 votes)
3 views18 pages

Oop Using Python Module 2

Uploaded by

Chisale Mwale
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views18 pages

Oop Using Python Module 2

Uploaded by

Chisale Mwale
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Python Programming Fundamentals

Training Module

Trainer: George Mugala


Department of Electrical/Electronics
Copperbelt University

Course Code: CS111-Python


Duration: 45 Hours (Now Includes OOP)
Credit Hours: 3

December 16, 2025


Python Programming Fundamentals George Mugala - Copperbelt University

Contents

Course Overview 2

1 Object-Oriented Programming (OOP) in Python 3


1.1 Introduction to OOP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1.1 Key OOP Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2 Classes and Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.3 Class Methods and Static Methods . . . . . . . . . . . . . . . . . . . . . 4
1.4 Encapsulation and Properties . . . . . . . . . . . . . . . . . . . . . . . . 5
1.5 Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.6 Multiple Inheritance and Mixins . . . . . . . . . . . . . . . . . . . . . . . 7
1.7 Polymorphism . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.8 Special Methods (Magic Methods) . . . . . . . . . . . . . . . . . . . . . . 10
1.9 Abstract Base Classes (ABC) . . . . . . . . . . . . . . . . . . . . . . . . 11
1.10 Composition vs Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . 12

2 OOP Design Principles 13


2.1 SOLID Principles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.2 OOP Project: University Management System . . . . . . . . . . . . . . . 14

3 Updated Practical Exercises 16


3.1 Exercise 3: OOP Implementation . . . . . . . . . . . . . . . . . . . . . . 16
3.2 Exercise 4: Banking System . . . . . . . . . . . . . . . . . . . . . . . . . 16

4 Updated Assessment 17
4.1 Continuous Assessment (40%) . . . . . . . . . . . . . . . . . . . . . . . . 17
4.2 Final Examination (60%) . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

OOP Best Practices Summary 17

1
Python Programming Fundamentals George Mugala - Copperbelt University

Course Overview
This module introduces students to the fundamentals of Python programming language
with comprehensive coverage of Object-Oriented Programming (OOP). Python is a ver-
satile, high-level programming language known for its simplicity and readability. This
course covers basic syntax, data structures, control flow, functions, file handling, and
comprehensive OOP concepts.

Updated Learning Outcomes


Upon completion of this module, students will be able to:

ˆ Understand Python syntax and semantics

ˆ Write Python programs using fundamental programming constructs

ˆ Implement data structures (lists, tuples, dictionaries, sets)

ˆ Create and use functions and modules

ˆ Handle files and exceptions

ˆ Understand and apply Object-Oriented Programming principles

ˆ Design and implement classes with inheritance and polymorphism

ˆ Use special methods and operator overloading

ˆ Solve complex problems using OOP approach

Prerequisites
ˆ Basic computer literacy

ˆ Understanding of mathematical concepts

ˆ No prior programming experience required

2
Python Programming Fundamentals George Mugala - Copperbelt University

1 Object-Oriented Programming (OOP) in Python


1.1 Introduction to OOP
Object-Oriented Programming is a programming paradigm based on the concept of ”ob-
jects” which can contain data and code. OOP focuses on creating reusable patterns of
code, in contrast to procedural programming which focuses on explicit sequenced instruc-
tions.

1.1.1 Key OOP Concepts


ˆ Class: Blueprint for creating objects

ˆ Object: Instance of a class

ˆ Encapsulation: Bundling data and methods

ˆ Inheritance: Creating new classes from existing ones

ˆ Polymorphism: Using a single interface for different types

ˆ Abstraction: Hiding complex implementation details

1.2 Classes and Objects

1 class Student :
2 " " " A class representing a CBU student " " "
3
4 # Class attribute ( shared by all instances )
5 university = " Copperbelt University "
6
7 # Constructor ( initializer )
8 def __init__ ( self , name , student_id , course ) :
9 " " " Initialize student attributes " " "
10 self . name = name # Instance attribute
11 self . student_id = student_id
12 self . course = course
13 self . grades = [] # Empty list for grades
14
15 # Instance method
16 def display_info ( self ) :
17 " " " Display student information " " "
18 print ( f " Student Name : { self . name } " )
19 print ( f " Student ID : { self . student_id } " )
20 print ( f " Course : { self . course } " )
21 print ( f " University : { self . university } " )
22 print ( f " Grades : { self . grades } " )
23
24 def add_grade ( self , grade ) :
25 " " " Add a grade to student ’s record " " "
26 if 0 <= grade <= 100:
27 self . grades . append ( grade )
28 return True
29 return False
30
31 def ca lculat e_aver age ( self ) :

3
Python Programming Fundamentals George Mugala - Copperbelt University

32 " " " Calculate average grade " " "


33 if not self . grades :
34 return 0
35 return sum ( self . grades ) / len ( self . grades )
36
37 # Creating objects ( instances )
38 student1 = Student ( " John Banda " , " CBU2023001 " , " Computer Science " )
39 student2 = Student ( " Mary Phiri " , " CBU2023002 " , " Information Technology "
)
40
41 # Using objects
42 student1 . display_info ()
43 student1 . add_grade (85)
44 student1 . add_grade (92)
45 print ( f " Average Grade : { student1 . ca lculat e_aver age () :.2 f } " )
46
47 # Accessing attributes
48 print ( f " \ n { student1 . name } studies at { Student . university } " )

Listing 1: Basic Class and Object

1.3 Class Methods and Static Methods

1 class UniversityCourse :
2 " " " Class demonstrating class and static methods " " "
3
4 total_courses = 0
5
6 def __init__ ( self , code , name , credits ) :
7 self . code = code
8 self . name = name
9 self . credits = credits
10 UniversityCourse . total_courses += 1
11
12 @classmethod
13 def c re at e_ fr om _s tr in g ( cls , course_string ) :
14 " " " Class method to create course from string " " "
15 code , name , credits = course_string . split ( " ," )
16 return cls ( code . strip () , name . strip () , int ( credits ) )
17
18 @staticmethod
19 def is_valid_credits ( credits ) :
20 " " " Static method to validate credits " " "
21 return 1 <= credits <= 6
22
23 @classmethod
24 def ge t_tota l_cour ses ( cls ) :
25 " " " Get total number of courses created " " "
26 return cls . total_courses
27
28 # Using class method
29 course_str = " CS101 , Introduction to Programming , 3 "
30 course1 = UniversityCourse . cre at e_ fr om _s tr in g ( course_str )
31 print ( f " Course : { course1 . name } ({ course1 . code }) " )
32
33 # Using static method
34 print ( f " Are 5 credits valid ? { UniversityCourse . is_valid_credits (5) } " )

4
Python Programming Fundamentals George Mugala - Copperbelt University

35

36 # Using class method


37 print ( f " Total courses : { UniversityCourse . ge t_tota l_cour ses () } " )

Listing 2: Class and Static Methods

1.4 Encapsulation and Properties

1 class BankAccount :
2 " " " Bank account class demonstrating encapsulation " " "
3
4 def __init__ ( self , account_holder , initial_balance =0) :
5 self . account_holder = account_holder
6 self . __balance = initial_balance # Private attribute
7 self . _ _ t r a n s a c t i o n _ h i s t o r y = []
8
9 @property
10 def balance ( self ) :
11 " " " Getter for balance " " "
12 return self . __balance
13
14 @balance . setter
15 def balance ( self , amount ) :
16 " " " Setter for balance with validation " " "
17 if amount < 0:
18 print ( " Error : Balance cannot be negative " )
19 else :
20 self . __balance = amount
21
22 def deposit ( self , amount ) :
23 " " " Deposit money into account " " "
24 if amount > 0:
25 self . __balance += amount
26 self . _ _ t r a n s a c t i o n _ h i s t o r y . append ( f " Deposited : ZMW { amount } "
)
27 return True
28 return False
29
30 def withdraw ( self , amount ) :
31 " " " Withdraw money from account " " "
32 if 0 < amount <= self . __balance :
33 self . __balance -= amount
34 self . _ _ t r a n s a c t i o n _ h i s t o r y . append ( f " Withdrew : ZMW { amount } " )
35 return True
36 print ( " Insufficient funds or invalid amount " )
37 return False
38
39 def g e t _ t r a n s a c t i o n _ h i s t o r y ( self ) :
40 " " " Get transaction history ( read - only ) " " "
41 return self . _ _ t r a n s a c t i o n _ h i s t o r y . copy () # Return copy for
encapsulation
42
43 # Using encapsulated class
44 account = BankAccount ( " John Banda " , 1000)
45 print ( f " Initial Balance : ZMW { account . balance } " )
46
47 account . deposit (500)

5
Python Programming Fundamentals George Mugala - Copperbelt University

48 account . withdraw (200)


49 print ( f " Current Balance : ZMW { account . balance } " )
50
51 # Cannot access private attribute directly
52 # print ( account . __balance ) # This will cause AttributeError
53
54 # Access through property
55 print ( f " Balance via property : ZMW { account . balance } " )
56
57 # View transaction history
58 print ( " \ nTransaction History : " )
59 for transaction in account . g e t _ t r a n s a c t i o n _ h i s t o r y () :
60 print ( f " - { transaction } " )

Listing 3: Encapsulation with Properties

1.5 Inheritance

1 class Person :
2 " " " Base class for all persons " " "
3
4 def __init__ ( self , name , age , gender ) :
5 self . name = name
6 self . age = age
7 self . gender = gender
8
9 def introduce ( self ) :
10 return f " Hello , I ’m { self . name } , { self . age } years old . "
11
12 def display_info ( self ) :
13 print ( f " Name : { self . name } " )
14 print ( f " Age : { self . age } " )
15 print ( f " Gender : { self . gender } " )
16
17 class Student ( Person ) :
18 " " " Student class inheriting from Person " " "
19
20 def __init__ ( self , name , age , gender , student_id , course ) :
21 # Call parent class constructor
22 super () . __init__ ( name , age , gender )
23 self . student_id = student_id
24 self . course = course
25 self . enrolled_courses = []
26
27 # Method overriding
28 def display_info ( self ) :
29 super () . display_info ()
30 print ( f " Student ID : { self . student_id } " )
31 print ( f " Course : { self . course } " )
32
33 def enroll_course ( self , course ) :
34 " " " Enroll in a course " " "
35 if course not in self . enrolled_courses :
36 self . enrolled_courses . append ( course )
37 return True
38 return False
39

6
Python Programming Fundamentals George Mugala - Copperbelt University

40 class Lecturer ( Person ) :


41 " " " Lecturer class inheriting from Person " " "
42
43 def __init__ ( self , name , age , gender , employee_id , department ) :
44 super () . __init__ ( name , age , gender )
45 self . employee_id = employee_id
46 self . department = department
47 self . courses_teaching = []
48
49 def display_info ( self ) :
50 super () . display_info ()
51 print ( f " Employee ID : { self . employee_id } " )
52 print ( f " Department : { self . department } " )
53
54 def assign_course ( self , course ) :
55 " " " Assign course to lecturer " " "
56 self . courses_teaching . append ( course )
57
58 # Using inheritance
59 student = Student ( " Alice Zulu " , 21 , " Female " , " CBU2023003 " , " Computer
Science " )
60 lecturer = Lecturer ( " Dr . George Mugala " , 45 , " Male " , " CBU001 " , "
Computer Science " )
61
62 print ( " === Student Information === " )
63 student . display_info ()
64 student . enroll_course ( " CS101 - Python Programming " )
65
66 print ( " \ n === Lecturer Information === " )
67 lecturer . display_info ()
68 lecturer . assign_course ( " CS101 - Python Programming " )
69
70 # Check inheritance
71 print ( f " \ nIs student a Person ? { isinstance ( student , Person ) } " )
72 print ( f " Is student a Student ? { isinstance ( student , Student ) } " )
73 print ( f " Is lecturer a Person ? { isinstance ( lecturer , Person ) } " )

Listing 4: Inheritance Example

1.6 Multiple Inheritance and Mixins

1 class Researcher :
2 " " " Mixin class for research capabilities " " "
3
4 def conduct_research ( self , topic ) :
5 return f " Conducting research on { topic } "
6
7 def publish_paper ( self , title , journal ) :
8 return f " Published ’{ title } ’ in { journal } "
9
10 class Teacher :
11 " " " Mixin class for teaching capabilities " " "
12
13 def prepare_lecture ( self , topic ) :
14 return f " Preparing lecture on { topic } "
15
16 def grade_assignment ( self , student , marks ) :

7
Python Programming Fundamentals George Mugala - Copperbelt University

17 return f " Graded { student } ’ s assignment : { marks }/100 "


18
19 class U ni v e rs i t yP r o fe s s or ( Lecturer , Researcher , Teacher ) :
20 " " " Professor with multiple capabilities " " "
21
22 def __init__ ( self , name , age , gender , employee_id , department ,
title ) :
23 Lecturer . __init__ ( self , name , age , gender , employee_id ,
department )
24 self . title = title
25 self . research_areas = []
26
27 def ad d_rese arch_a rea ( self , area ) :
28 self . research_areas . append ( area )
29
30 def d i s p l a y _ c a p a b i l i t i e s ( self ) :
31 print ( f " { self . name } ’ s Capabilities : " )
32 print ( f " - { self . conduct_research ( ’ AI in Education ’) } " )
33 print ( f " - { self . prepare_lecture ( ’ Advanced Python ’) } " )
34 print ( f " - { self . publish_paper ( ’ OOP Best Practices ’, ’ Journal of
CS Education ’) } " )
35
36 # Using multiple inheritance
37 professor = U ni v e rs i t yP r o fe s s or (
38 " Prof . Sarah Mwansa " ,
39 50 ,
40 " Female " ,
41 " CBU002 " ,
42 " Computer Science " ,
43 " Professor "
44 )
45
46 professor . d i s p l a y _ c a p a b i l i t i e s ()
47 print ( f " \ nTitle : { professor . title } " )

Listing 5: Multiple Inheritance

1.7 Polymorphism

1 from math import pi


2
3 class Shape :
4 " " " Base class for all shapes " " "
5
6 def area ( self ) :
7 raise No t I m pl e m en t e dE r r or ( " Subclass must implement area () " )
8
9 def perimeter ( self ) :
10 raise N ot I m pl e m en t e dE r r or ( " Subclass must implement perimeter () "
)
11
12 def display_info ( self ) :
13 print ( f " Shape : { self . __class__ . __name__ } " )
14 print ( f " Area : { self . area () :.2 f } " )
15 print ( f " Perimeter : { self . perimeter () :.2 f } " )
16
17 class Rectangle ( Shape ) :

8
Python Programming Fundamentals George Mugala - Copperbelt University

18 " " " Rectangle class " " "


19
20 def __init__ ( self , length , width ) :
21 self . length = length
22 self . width = width
23
24 def area ( self ) :
25 return self . length * self . width
26
27 def perimeter ( self ) :
28 return 2 * ( self . length + self . width )
29
30 class Circle ( Shape ) :
31 " " " Circle class " " "
32
33 def __init__ ( self , radius ) :
34 self . radius = radius
35
36 def area ( self ) :
37 return pi * self . radius ** 2
38
39 def perimeter ( self ) :
40 return 2 * pi * self . radius
41
42 class Triangle ( Shape ) :
43 " " " Triangle class " " "
44
45 def __init__ ( self , base , height , side1 , side2 , side3 ) :
46 self . base = base
47 self . height = height
48 self . side1 = side1
49 self . side2 = side2
50 self . side3 = side3
51
52 def area ( self ) :
53 return 0.5 * self . base * self . height
54

55 def perimeter ( self ) :


56 return self . side1 + self . side2 + self . side3
57
58 # Polymorphism in action
59 shapes = [
60 Rectangle (10 , 5) ,
61 Circle (7) ,
62 Triangle (6 , 4 , 3 , 4 , 5)
63 ]
64
65 print ( " === Shape Information === " )
66 for shape in shapes :
67 shape . display_info ()
68 print () # Empty line
69
70 # Common interface
71 total_area = sum ( shape . area () for shape in shapes )
72 print ( f " Total area of all shapes : { total_area :.2 f } " )

Listing 6: Polymorphism Example

9
Python Programming Fundamentals George Mugala - Copperbelt University

1.8 Special Methods (Magic Methods)

1 class Vector :
2 " " " Vector class demonstrating special methods " " "
3
4 def __init__ ( self , x , y ) :
5 self . x = x
6 self . y = y
7
8 # String representation
9 def __str__ ( self ) :
10 return f " Vector ({ self . x } , { self . y }) "
11
12 def __repr__ ( self ) :
13 return f " Vector ( x ={ self . x } , y ={ self . y }) "
14

15 # Arithmetic operations
16 def __add__ ( self , other ) :
17 return Vector ( self . x + other .x , self . y + other . y )
18
19 def __sub__ ( self , other ) :
20 return Vector ( self . x - other .x , self . y - other . y )
21
22 def __mul__ ( self , scalar ) :
23 return Vector ( self . x * scalar , self . y * scalar )
24
25 # Comparison operators
26 def __eq__ ( self , other ) :
27 return self . x == other . x and self . y == other . y
28
29 def __lt__ ( self , other ) :
30 # Compare magnitudes
31 return ( self . x **2 + self . y **2) < ( other . x **2 + other . y **2)
32

33 # Length / magnitude
34 def __len__ ( self ) :
35 return 2 # Always 2 D vectors
36
37 def magnitude ( self ) :
38 return ( self . x **2 + self . y **2) ** 0.5
39
40 # Container emulation
41 def __getitem__ ( self , index ) :
42 if index == 0:
43 return self . x
44 elif index == 1:
45 return self . y
46 else :
47 raise IndexError ( " Vector index out of range " )
48
49 def __setitem__ ( self , index , value ) :
50 if index == 0:
51 self . x = value
52 elif index == 1:
53 self . y = value
54 else :
55 raise IndexError ( " Vector index out of range " )
56

10
Python Programming Fundamentals George Mugala - Copperbelt University

57 # Using special methods


58 v1 = Vector (3 , 4)
59 v2 = Vector (1 , 2)
60
61 print ( f " v1 : { v1 } " )
62 print ( f " v2 : { v2 } " )
63 print ( f " v1 + v2 : { v1 + v2 } " )
64 print ( f " v1 * 2: { v1 * 2} " )
65 print ( f " v1 == v2 : { v1 == v2 } " )
66 print ( f " Magnitude of v1 : { v1 . magnitude () :.2 f } " )
67 print ( f " v1 [0]: { v1 [0]} , v1 [1]: { v1 [1]} " )

Listing 7: Special Methods

1.9 Abstract Base Classes (ABC)

1 from abc import ABC , abstractmethod


2

3 class UniversityMember ( ABC ) :


4 " " " Abstract base class for all university members " " "
5
6 def __init__ ( self , name , id_number ) :
7 self . name = name
8 self . id_number = id_number
9
10 @abstractmethod
11 def get_role ( self ) :
12 " " " Return the role of the member " " "
13 pass
14

15 @abstractmethod
16 def get_details ( self ) :
17 " " " Return detailed information " " "
18 pass
19
20 def common_method ( self ) :
21 " " " Common method for all university members " " "
22 return f " { self . name } ( ID : { self . id_number }) is a { self . get_role
() } "
23
24 class ConcreteStudent ( UniversityMember ) :
25 " " " Concrete implementation of Student " " "
26
27 def __init__ ( self , name , id_number , course ) :
28 super () . __init__ ( name , id_number )
29 self . course = course
30
31 def get_role ( self ) :
32 return " Student "
33
34 def get_details ( self ) :
35 return f " Student : { self . name } , Course : { self . course } "
36
37 class ConcreteLecturer ( UniversityMember ) :
38 " " " Concrete implementation of Lecturer " " "
39
40 def __init__ ( self , name , id_number , department ) :

11
Python Programming Fundamentals George Mugala - Copperbelt University

41 super () . __init__ ( name , id_number )


42 self . department = department
43
44 def get_role ( self ) :
45 return " Lecturer "
46
47 def get_details ( self ) :
48 return f " Lecturer : { self . name } , Department : { self . department } "
49
50 # Using abstract base class
51 student = ConcreteStudent ( " John Banda " , " CBU2023001 " , " Computer Science
")
52 lecturer = ConcreteLecturer ( " George Mugala " , " CBU001 " , " Computer
Science " )
53
54 print ( student . common_method () )
55 print ( lecturer . common_method () )
56
57 # Cannot instantiate abstract class
58 # member = UniversityMember (" Test " , "001") # This will raise TypeError

Listing 8: Abstract Base Classes

1.10 Composition vs Inheritance

1 class Engine :
2 " " " Engine class for composition example " " "
3
4 def __init__ ( self , horsepower ) :
5 self . horsepower = horsepower
6
7 def start ( self ) :
8 return " Engine started "
9
10 def stop ( self ) :
11 return " Engine stopped "
12
13 class Wheels :
14 " " " Wheels class for composition example " " "
15
16 def __init__ ( self , count ) :
17 self . count = count
18
19 def rotate ( self ) :
20 return f " { self . count } wheels rotating "
21
22 class Car :
23 " " " Car using composition ( has - a relationship ) " " "
24
25 def __init__ ( self , model , engine_hp , wheel_count =4) :
26 self . model = model
27 self . engine = Engine ( engine_hp ) # Composition
28 self . wheels = Wheels ( wheel_count ) # Composition
29

30 def drive ( self ) :


31 return f " { self . model } is driving with { self . engine . horsepower }
HP "

12
Python Programming Fundamentals George Mugala - Copperbelt University

32

33 def start_car ( self ) :


34 return f " { self . model }: { self . engine . start () } "
35
36 def stop_car ( self ) :
37 return f " { self . model }: { self . engine . stop () } "
38

39 def display_info ( self ) :


40 info = [
41 f " Car Model : { self . model } " ,
42 f " Engine : { self . engine . horsepower } HP " ,
43 self . start_car () ,
44 self . wheels . rotate () ,
45 self . drive ()
46 ]
47 return " \ n " . join ( info )
48
49 # Using composition
50 my_car = Car ( " Toyota Hilux " , 150)
51 print ( my_car . display_info () )

Listing 9: Composition Example

2 OOP Design Principles


2.1 SOLID Principles
S - Single Responsibility Principle Each class should have only one reason to change.
1 # Good Example
2 class StudentData :
3 def __init__ ( self , name , id ) :
4 self . name = name
5 self . id = id
6
7 class StudentDisplay :
8 def show_student ( self , student ) :
9 print ( f " Name : { student . name } , ID : { student . id } " )
10
11 class StudentStorage :
12 def save_to_file ( self , student , filename ) :
13 with open ( filename , ’w ’) as f :
14 f . write ( f " { student . name } ,{ student . id } " )

O - Open/Closed Principle Classes should be open for extension but closed for mod-
ification.
1 class Discount :
2 def calculate ( self , amount ) :
3 pass
4
5 class StudentDiscount ( Discount ) :
6 def calculate ( self , amount ) :
7 return amount * 0.8 # 20% discount
8
9 class StaffDiscount ( Discount ) :

13
Python Programming Fundamentals George Mugala - Copperbelt University

10 def calculate ( self , amount ) :


11 return amount * 0.9 # 10% discount

L - Liskov Substitution Principle Subclasses should be substitutable for their base


classes.

I - Interface Segregation Principle Clients shouldn’t depend on interfaces they don’t


use.

D - Dependency Inversion Principle Depend on abstractions, not concretions.

2.2 OOP Project: University Management System

1 """
2 University Management System
3 Comprehensive OOP example for CBU
4 """
5
6 class Person :
7 def __init__ ( self , name , email , phone ) :
8 self . name = name
9 self . email = email
10 self . phone = phone
11
12 def contact_info ( self ) :
13 return f " Email : { self . email } , Phone : { self . phone } "
14
15 class Student ( Person ) :
16 def __init__ ( self , name , email , phone , student_id , year ) :
17 super () . __init__ ( name , email , phone )
18 self . student_id = student_id
19 self . year = year
20 self . courses = []
21
22 def enroll_course ( self , course ) :
23 self . courses . append ( course )
24
25 def get_transcript ( self ) :
26 return f " Transcript for { self . name } ({ self . student_id }) "
27
28 class Lecturer ( Person ) :
29 def __init__ ( self , name , email , phone , employee_id , department ) :
30 super () . __init__ ( name , email , phone )
31 self . employee_id = employee_id
32 self . department = department
33
34 def assign_grade ( self , student , course , grade ) :
35 return f " Assigned grade { grade } to { student . name } for { course } "
36
37 class Course :
38 def __init__ ( self , code , name , credits ) :
39 self . code = code
40 self . name = name
41 self . credits = credits
42 self . students = []
43 self . lecturer = None

14
Python Programming Fundamentals George Mugala - Copperbelt University

44

45 def add_student ( self , student ) :


46 self . students . append ( student )
47 student . enroll_course ( self )
48
49 def assign_lecturer ( self , lecturer ) :
50 self . lecturer = lecturer
51
52 def get_info ( self ) :
53 return f " { self . code }: { self . name } ({ self . credits } credits ) "
54
55 class University :
56 def __init__ ( self , name ) :
57 self . name = name
58 self . students = []
59 self . lecturers = []
60 self . courses = []
61
62 def add_student ( self , student ) :
63 self . students . append ( student )
64
65 def add_lecturer ( self , lecturer ) :
66 self . lecturers . append ( lecturer )
67
68 def add_course ( self , course ) :
69 self . courses . append ( course )
70
71 def get_statistics ( self ) :
72 return {
73 " university " : self . name ,
74 " students " : len ( self . students ) ,
75 " lecturers " : len ( self . lecturers ) ,
76 " courses " : len ( self . courses )
77 }
78
79 # Main program
80 def main () :
81 # Create university
82 cbu = University ( " Copperbelt University " )
83
84 # Create students
85 student1 = Student ( " John Banda " , " john@cbu . ac . zm " , " 0971234567 " , "
CBU2023001 " , 2)
86 student2 = Student ( " Mary Phiri " , " mary@cbu . ac . zm " , " 0977654321 " , "
CBU2023002 " , 3)
87
88 # Create lecturer
89 lecturer1 = Lecturer ( " George Mugala " , " george . mugala@cbu . ac . zm " ,
90 " 0971122334 " , " CBU001 " , " Computer Science " )
91
92 # Create courses
93 python_course = Course ( " CS101 " , " Python Programming " , 3)
94 oop_course = Course ( " CS201 " , " Object - Oriented Programming " , 3)
95
96 # Build relationships
97 python_course . assign_lecturer ( lecturer1 )
98 python_course . add_student ( student1 )
99 python_course . add_student ( student2 )

15
Python Programming Fundamentals George Mugala - Copperbelt University

100

101 # Add to university


102 cbu . add_student ( student1 )
103 cbu . add_student ( student2 )
104 cbu . add_lecturer ( lecturer1 )
105 cbu . add_course ( python_course )
106 cbu . add_course ( oop_course )
107
108 # Display information
109 print ( f " Welcome to { cbu . name } " )
110 print ( " \ n === Statistics === " )
111 stats = cbu . get_statistics ()
112 for key , value in stats . items () :
113 print ( f " { key . title () }: { value } " )
114
115 print ( " \ n === Course Information === " )
116 print ( python_course . get_info () )
117 print ( f " Lecturer : { python_course . lecturer . name } " )
118 print ( f " Students enrolled : { len ( python_course . students ) } " )
119
120 if __name__ == " __main__ " :
121 main ()

Listing 10: Complete OOP Project

3 Updated Practical Exercises


3.1 Exercise 3: OOP Implementation
Create a complete library management system using OOP principles:

1. Design classes for Book, Member, Librarian, and Transaction

2. Implement inheritance where appropriate

3. Use encapsulation with properties

4. Implement polymorphism for different types of publications

5. Add error handling and validation

3.2 Exercise 4: Banking System


Design a banking system with:

ˆ Account base class with savings and checking account subclasses

ˆ Transaction history with composition

ˆ calculation using polymorphism

ˆ Customer class with multiple accounts

ˆ Bank class managing all accounts and customers

16
Python Programming Fundamentals George Mugala - Copperbelt University

4 Updated Assessment
4.1 Continuous Assessment (40%)
ˆ Weekly quizzes (10%)

ˆ Programming assignments (15%)

ˆ OOP design project (15%)

4.2 Final Examination (60%)


ˆ Theory questions (20%) including OOP concepts

ˆ Practical programming test with OOP implementation (40%)

OOP Best Practices Summary


1. Plan before coding: Design your class hierarchy

2. Keep classes focused: Single Responsibility Principle

3. Use inheritance wisely: ”Is-a” relationships only

4. Prefer composition over inheritance: For ”has-a” relationships

5. Encapsulate data: Use private attributes with getters/setters

6. Document your classes: Use docstrings for each class and method

7. Follow naming conventions: CamelCase for classes, snake case for methods

8. Test your classes: Write unit tests for each class

17

You might also like