Classes allow you to define how to package data with functions to create objects. An object is an instance of a class, which contains its own data, and its own copy of functions that can operate on that data.
You use classes to define objects that represent the concepts and things that your program will work with. For example, if your program managed exam results of students, then you may create one class that represents an Exam, and another that represents a Student.
class Exam:
def __init__(self, max_score=100):
self._max_score = max_score
self._actual_score = 0
def percent(self):
return 100.0 * self._actual_score / self._max_score
def setResult(self, score):
if (score < 0):
self._actual_score = 0
elif (score > self._max_score):
self._actual_score = self._max_score
else:
self._actual_score = score
def grade(self):
if (self._actual_score == 0):
return "U"
elif (self.percent() > 90.0):
return "A"
elif (self.percent() > 80.0):
return "B"
elif (self.percent() > 70.0):
return "C"
else:
return "F"
class Student:
def __init__(self):
self._exams = {}
def addExam(self, name, exam):
self._exams[name] = exam
def addResult(self, name, score):
self._exams[name].setResult(score)
def result(self, exam):
return self._exams[exam].percent()
def grade(self, exam):
return self._exams[exam].grade()
def grades(self):
g = {}
for exam in self._exams.keys():
g[exam] = self.grade(exam)
return g
We can now create a student, and give them a set of exams that they need to complete.
s = Student()
s.addExam( "maths", Exam(20) )
s.addExam( "chemistry", Exam(75) )
At this point, the student has not completed any exams, so the grades are all 'U'
s.grades()
However, we can now add the results...
s.addResult("maths", 15)
s.addResult("chemistry", 62)
s.grades()
Programming with classes makes the code easier to read, as the code more closely represents the concepts that make up the program. For example, here we have a class that represents a full school of students.
class School:
def __init__(self):
self._students = {}
self._exams = []
def addStudent(self, name):
self._students[name] = Student()
def addExam(self, exam, max_score):
self._exams.append(exam)
for key in self._students.keys():
self._students[key].addExam(exam, Exam(max_score))
def addResult(self, name, exam, score):
self._students[name].addResult(exam, score)
def grades(self):
g = {}
for name in self._students.keys():
g[name] = self._students[name].grades()
return g
We can now create a whole school of students and manage the exams and results for all of them with some reasonably readable code :-)
school = School()
school.addStudent("Charlie")
school.addStudent("Matt")
school.addStudent("James")
school.addExam( "maths", 20 )
school.addExam( "physics", 50 )
school.addExam( "english literature", 30 )
school.grades()
We can now add in the results of the exams, which have been returned to us by the exam markers...
englit_results = { "Charlie" : 10, "Matt" : 25, "James" : 3 }
phys_results = { "Matt" : 48, "James" : 3 }
maths_results = { "James" : 20, "Matt" : 18, "Charlie" : 4 }
Indeed, we will do this by using a function...
def add_results(school, exam, results):
for student in results.keys():
school.addResult(student, exam, results[student])
add_results(school, "english literature", englit_results)
add_results(school, "physics", phys_results)
add_results(school, "maths", maths_results)
school.grades()