Lab Session 35 (python)
Lab Session 35 (python)
using Python 3
Object Oriented Programming
Prepared By:
Mr. Muhammad Ahsan Naeem
YouTube Playlist
https://youtube.com/playlist?list=PLWF9TXck7O_zuU2_BVUTrmGMCXYSYzjku
Student.py:
class MechaStudent:
department='Mechatronics'
offSubjects=['Mech','LA','ES','CP2','MOM','Isl/Pak','Proj']
allStudents=[]
def __init__(self,fName,lName,reg):
self.fName=fName
self.lName=lName
self.reg=reg
self.email=f'{reg.lower()}@uet.edu.pk'
self.courses=['Proj']
MechaStudent.allStudents.append(self)
@property
def fullName(self):
return f'{self.fName} {self.lName}'
def regCourse(self,*sub):
for i in sub:
if i in MechaStudent.offSubjects:
if i not in self.courses:
self.courses.append(i)
1|Page
else:
raise ValueError(f'{i} is not Offered!')
self.courses.sort()
def __repr__(self):
return f'{self.fullName}-{self.reg}'
Note that as convention, we should use keyword other to refer to the second object as we use self to
refer to the actual object on which the method is being applied/called.
With above addition in the original class program, let's run the following Main program
from Student import MechaStudent
std1=MechaStudent('Anwar','Ali','MCT-UET-01')
std2=MechaStudent('Akbar','Khan','MCT-UET-02')
std3=MechaStudent('Asad','Shabir','MCT-UET-03')
std4=MechaStudent('Faisal','Iqbal','MCT-UET-04')
print(std1.groupMember) # Will print None
std1.setGroupMember(std2)
print(std1.groupMember) # Will print Akbar Khan-MCT-UET-02
print(std2.groupMember) # Will print None
If you try to print and see groupMember attribute of std2, it will still be None because the method
setGroupMember sets this attribute for self only. We will have to apply this method on std2 and
2|Page
provide std1 to set groupMember for it. But the good approach is to handle it within the method
setGroupMember such that other becomes the groupMember of self and self becomes the
groupMember of other. Not only that, we must also check that the groupMember attribute of both
self and other is set to None before setting them groupMember of each other to avoid setting a
student as groupMember who is already groupMember of some other student. In such case we must
generate an exception. Secondly, there must be a way to cancel out two group members. See the following
code where these features are implemented:
def setGroupMember(self, other):
if(self.groupMember==None and other.groupMember==None):
self.groupMember=other
other.groupMember=self
else:
raise ValueError(
'Both students should have no group member set earlier'
)
def dropGroupMember(self,other):
if(self.groupMember==other.groupMember==None):
return
if(self.groupMember==other):
self.groupMember=None
other.groupMember=None
else:
raise ValueError('They are not group Members!')
With these methods added in class, run and see the output of following Main code:
from Student import MechaStudent
std1=MechaStudent('Anwar','Ali','MCT-UET-01')
std2=MechaStudent('Akbar','Khan','MCT-UET-02')
std3=MechaStudent('Asad','Shabir','MCT-UET-03')
std4=MechaStudent('Faisal','Iqbal','MCT-UET-04')
std1.setGroupMember(std2)
print(std1.groupMember) # Will print Akbar Khan-MCT-UET-02
print(std2.groupMember) # Will print Anwar Ali-MCT-UET-01
std1.dropGroupMember(std2)
print(std1.groupMember) # Will print None
print(std2.groupMember) # Will print None
std1.setGroupMember(std2)
print(std1.groupMember) # Will print Akbar Khan-MCT-UET-02
print(std2.groupMember) # Will print Anwar Ali-MCT-UET-01
# std1.setGroupMember(std3) # Will generate Error (ValueError: Both
students should have no group member set earlier)
3|Page
Tasks:
[1] In main program create two lists of same number of students (at least 4). Then you have to make
the students of both lists on corresponding indices as group members of each other. Verify the
results by printing group members of first list.
@classmethod
def withoutGroupMember(cls):
return list(filter(lambda s: s.groupMember==None,cls.allStudents))
The method is tested in main program as:
std1.setGroupMember(std2)
a=Student.withoutGroupMember()
print(a) #Will print [Asad Shabir-MCT-UET-03, Faisal Iqbal-MCT-UET-
04]
Static Method:
Unlike instance and class methods which are bound to instance and class respectively, the static methods
are bound neither to instance nor the class. These methods do not need an instance or the class as first
4|Page
input argument. This means that these methods are not meant for accessing and processing instance or
class attributes. Then what is the use of such methods?
These methods in general are not meant to be called outside the class though we can. These methods
usually serve as helping or utility function to simplify a complex logic e.g., some calculation or checking
the validity parameter for which we do not need any instance or class attribute. Let's see this with an
example but first note that a method will become a static method by the decorator @staticmethod
used on it.
We will create meaningful static methods later but here just for understanding purpose, let’s create a
sample static method. We will name it as test. It will not have the instance or class as first input argument
and can have some other input arguments. Let’s say, it will have a number as input argument and will
return the square of the that number. This is how we will define it inside the class:
@staticmethod
def test(a):
return a**2
We can use this method inside the class (usually in some other method) or outside the class. An example
use outside the class is here:
print(MechaStudent.test(5))
Tasks:
[2] We want to find the list of subjects in which no student is registered. Create a method in class with
name notRegSub (Decide whether it should be instance method, a class method or static
method). In main program, create a few students, register few subjects for those students and the
call the method notRegSub to find and display the list of subjects in which no student is
registered.
References:
[1] https://youtu.be/WZbgr14jyTk
[2] https://youtu.be/ml7pl2a-wK0
5|Page