CMP 4266
Computer Programming
Lecture – 7
(Based on Gaddis, T., Starting out with Python 3e, Pearson Education)
CMP 4266, School of CS & DT, Birmingham City University.
Python coding challenge
The challenge starts on Wednesday 13 November at 12 pm noon until 15
November Friday at 12 pm noon.
The challenge is worth 15% and consists of 3 tasks.
You have 48 hours to complete it, or typical penalties for late submissions will
be applied.
To do well, you need to complete labs 1-6 as the questions are based on
these labs.
Use the provided test cases to test your code before you submit it on Moodle.
After the release of the coding challenge, no tutor will give you any help
or support in relation to the challenge.
CMP 4266, School of CS & DT, Birmingham City University.
Outline
More About Python Classes
– Writing a class step by step
Inheritance
Relationships between objects
CMP 4266, School of CS & DT, Birmingham City University.
Writing a Class, Step by Step
A Rectangle object will have the following fields:
– height. The length field will hold the rectangle’s height.
– width. The width field will hold the rectangle’s width.
CMP 4266, School of CS & DT, Birmingham City University.
Writing a Class, Step by Step
The Rectangle class will also have the following
methods:
– get_perim. This method will calculate the distance
around the outside of shapes.
– is_square. This check if the rectangle is a square
shaped or not.
– get_area. This method will return the area of the
rectangle, which is the result of the object’s height
multiplied by its width.
– get_width. This method will return the value in an
object’s width field.
– get_height. This method will return the value in an
object’s height field.
CMP 4266, School of CS & DT, Birmingham City University.
UML Diagram
Unified Modeling Language (UML) provides a set of standard
diagrams for graphically depicting object-oriented systems.
Class name goes here
Fields are listed here
Methods are listed here
CMP 4266, School of CS & DT, Birmingham City University.
UML Diagram for
Rectangle class
Rectangle
height: float
width: float
get_perim():float
is_square():boolean
get_width():float
get_length():float
get_area():float
CMP 4266, School of CS & DT, Birmingham City University.
Writing the Code for the Class Fields
class Rectangle:
def __init__(self, h, w):
self.__height = h
self.__width = w
CMP 4266, School of CS & DT, Birmingham City University.
instantiation function - A
Creates a new instance of the class and assigns this object to
the local variable
object local variables being
The self parameter refers to
assigned at the time of creating
the instance of the object
the instance
def __init__(self, h, w):
CMP 4266, School of CS & DT, Birmingham City University.
instantiation function - B
Classes can have special methods called __init__
function.
__init__ is a method that is automatically called when
an object is created.
__init__ are used to perform operations at the time an
object is created.
__init__ typically initialize instance fields and perform
other object initialization tasks.
6-10
CMP 4266, School of CS & DT, Birmingham City University.
Writing and Demonstrating the get_width()
get_height Methods
class Rectangle:
def __init__(self, h, w):
self.__height = h
self.__width = w
def get_width(self):
return self.__width
def get_height(self):
return self.__height
CMP 4266, School of CS & DT, Birmingham City University.
Writing more methods for Rectangle class
class Rectangle:
def __init__(self, h, w):
self.__height = h
self.__width = w
def perim(self):
return (2 * self.__height) + (2 * self.__width)
def area(self):
return self.__height * self.__width
def isSquare(self):
return (self.__height == self.__width)
def get_width(self):
return self.__width
def get_height(self):
return self.__height
CMP 4266, School of CS & DT, Birmingham City University.
Creating a Rectangle object
box = Rectangle(3,5)
A Rectangle object
The box
variable holds height: 3
the address of address
the Rectangle width: 5
object.
CMP 4266, School of CS & DT, Birmingham City University.
Accessor and Mutator Methods
Because of the concept of data hiding, fields in a
class are private.
The methods that retrieve the data of fields are called
accessors.
The methods that modify the data of fields are called
mutators.
Each field that the programmer wishes to be viewed
by other classes needs an accessor.
Each field that the programmer wishes to be modified
by other classes needs a mutator.
CMP 4266, School of CS & DT, Birmingham City University.
Writing mutator methods for Rectangle class
class Rectangle:
def __init__(self, h, w):
self.__height = h
self.__width = w
def perim(self):
return (2 * self.__height) + (2 * self.__width)
def area(self):
return self.__height * self.__width
def isSquare(self):
return (self.__height == self.__width)
def get_width(self):
return self.__width
def get_height(self): mutator methods
return self.__height
def set_width(self, w):
self.__width = w
def set_height(self, h):
self.__height = y
CMP 4266, School of CS & DT, Birmingham City University.
Calling the setLength Method
box.set_height(10.0)
The box A Rectangle object
variable holds
the address of height: 10.0
the address
Rectangle width: 0.0
object.
This is the state of the box object after
the set_height method executes.
CMP 4266, School of CS & DT, Birmingham City University.
Accessors and Mutators
For the Rectangle example, the accessors and
mutators are:
def get_width(self):
return self.__width
def get_height(self):
return self.__height
def set_width(self, w):
self.__width = w
def set_height(self, h):
self.__height = y
Other names for these methods are getters and
setters.
CMP 4266, School of CS & DT, Birmingham City University.
Converting the UML Diagram to Code
Once the class structure has been tested,
the method bodies can be written and
tested. class Rectangle:
def __init__(self, h, w):
self.__height = h
Rectangle self.__width = w
def perim(self):
return (2 * self.__height) + (2 * self.__width)
Height:float def area(self):
Width:float return self.__height * self.__width
def isSquare(self):
__init__(height:float, width:float) return (self.__height == self.__width)
perim():float def get_width(self):
return self.__width
area():float def get_height(self):
isSquare():boolean return self.__height
get_width():float def set_width(self, w):
get_height():float self.__width = w
def set_height(self, h):
set_width(width):void
self.__height = y
set_height(height):void
Stale Data
Rather than use an area variable in a Rectangle
class:
def area(self):
return self.__height * self.__width
This dynamically calculates the value of the
rectangle’s area when the method is called.
Now, any change to the height or width variables
will not leave the area of the rectangle stale.
6-19
CMP 4266, School of CS & DT, Birmingham City University.
Class Layout Conventions
The layout of a source code file can vary by employer or
instructor. class Rectangle:
def __init__(self, h, w):
A common layout is: self.__height = h
– Fields listed first self.__width = w
def perim(self):
– Methods listed second return (2 * self.__height) + (2 * self.__widt
- Accessors and mutators def area(self):
return self.__height * self.__width
are typically grouped.
def isSquare(self):
return (self.__height == self.__width)
def get_width(self):
return self.__width
def get_height(self):
return self.__height
def set_width(self, w):
self.__width = w
def set_height(self, h):
self.__height = y
CMP 4266, School of CS & DT, Birmingham City University.
Running/Testing the Rectangle Class
box = Rectangle(3,5)
print ("Perimitar value is %.2f" %box.perim())
print ("Rectangle total area is %.2f" %box.area())
print (box.is_square())
print ("Rectangle height %.2f and width %.2f" %(box.get_height(),
box.get_width()))
box.set_height(9)
Using mutator methods to change
box.set_width(9)
print ("Perimitar value is %.2f" %box.perim())
the instance variables (height and
print ("Rectangle total area is %.2f" %box.area())
width)
print ("is it a Square? : ", box.is_square())
print ("Rectangle height %.2f and width %.2f"
%(box.get_height(), box.get_width()))
CMP 4266, School of CS & DT, Birmingham City University.
Employee class– 7.1 Exercise:
(15 minutes)
In-class
You are required to develop an employee class Exercise
using the following scenario:
The software should store employees’ name, address, age, worked
hours per week and pay rate.
Based on the employee worked hours per week and his/her pay rate, the
system can calculate the full weekly salary before tax deduction.
The income tax to be detected from the weekly salary is 20%. However, if
the age of employee is 50 years or over, the employee income tax is
reduced to only 5%.
The class should contain a method to print the Employee personal details
and the weekly salary after tax.
Write a class Employee that contains all the necessary attributes and
methods. Then, create a Test class to create multiple employee
instances/objects and print their relevant data.
CMP4266 , School of CS & DT, Birmingham City University.
Relationships between objects
Association – Weak relationship
– Is a weakest form of relationship between classes. If we have two classes A
and B, B is completely independent from A, but only needs some attributes
from A to run its methods.
– A and B can live independently from each other.
Aggregation – Medium relationship
– Is a medium form of relationship. Normally, if Class A needs Class B to perform
some functions, then B object will be created and passed to A.
– If we delete the container object A, then the contents object B can live without
container object.
Composition – Strong relationship
– In composition when Class A is composed of one or more instance of other
class B. In other words one class is container and other class is content.
Hence, if you delete the container object A then its content object B will also
deleted.
CMP 4266, School of CS & DT, Birmingham City University.
Association
class Salary:
• Salary Class is
def __init__(self, hrs, rate): independent
self.monthly_worked_hours = hrs
self.pay_rate = rate • Employee Class is
independent, but needs
def get_annual_salary(self): Salary when calculating
return (self.monthly_worked_hours * self.pay_rate * 12) employee salary with bonus
class Employee:
def __init__(self, na, add, bon):
self.name = na
self.address = add
self.bonus = bon
def annual_salary_with_bonus(self, annual_salary):
return "Total: " + str(annual_salary + self.bonus)
obj_sal = Salary(40, 10.50) # 40 hours per month, and the pay rate is £10.50
obj_emp=Employee("Thomas", "50 Curzon St.", 2500)
print (obj_emp.annual_salary_with_bonus(obj_sal.get_annual_salary()))
CMP 4266, School of CS & DT, Birmingham City University.
Aggregation
class Salary:
def __init__(self, hrs, rate): • Salary Class is
independent
self.monthly_worked_hours = hrs
self.pay_rate = rate
• Employee needs Salary to
exist as its part of its
def get_annual_salary(self): __init__ parameters.
return (self.monthly_worked_hours * self.pay_rate * 12)
class Employee:
def __init__(self,na, add, bon, salary):
self.name = na
self.address = add
self.bonus = bon
self.obj_salary = salary
def annual_salary_with_bonus(self):
return "Total: " + str(self.obj_salary.get_annual_salary() + self.bonus)
obj_sal = Salary(40, 10.50) # 40 hours per month, and the pay rate is £10.50
obj_emp = Employee("Thomas", "50 Curzon St.", 2500, obj_sal)
print (obj_emp.annual_salary_with_bonus())
CMP 4266, School of CS & DT, Birmingham City University.
Composition
Salary Class is not independent,
as it is being created inside
Employee class. Hence, if
class Salary: Employee object gets deleted,
the inner Salary object will be
def __init__(self, hrs, rate):
deleted too.
self.monthly_worked_hours = hrs
self.pay_rate = rate
Employee needs Salary input
parameters to exist, and to create
def get_annual_salary(self): the Salary objects as part of its
return (self.monthly_worked_hours * self.pay_rate * 12) __init__ function
class Employee:
def __init__(self, na, add, bon, hrs, rate):
self.name=na
self.address = add
self.bonus=bon
self.obj_salary = Salary(hrs, rate)
def annual_salary_with_bonus(self):
return "Total: " + str(self.obj_salary.get_annual_salary() + self.bonus)
obj_emp=Employee("Thomas", "50 Curzon St.", 2000, 40, 10.50)
print (obj_emp.annual_salary_with_bonus())
CMP 4266, School of CS & DT, Birmingham City University.
Class relationships in UML class diagram
CMP 4266, School of CS & DT, Birmingham City University.
Inheritance
In the real world, many objects are a specialized version of more general
objects
– Example: grasshoppers and bees are specialized types of insect
- In addition to the general insect characteristics, they have unique
characteristics:
- Grasshoppers can jump
- Bees can sting, make honey, and build hives
We can specify this feature by using a relationship between the objects
which is known as “Is a” relationship.
“Is a” relationship: exists when one object is a specialized version of
another object
– Specialized object has all the characteristics of the general object plus
unique characteristics
– Example: Rectangle is a shape
Daisy is a flower
CMP 4266, School of CS & DT, Birmingham City University.
Inheritance
In OOP inheritance is the concept that is applied to create an “is a”
relationship between classes. Inheritance in OOP is based on the concepts
of superclass and subclass.
Superclass (base class): a general class
Subclass (derived class): a specialized class
– An extended version of the superclass
- Inherits attributes and methods of the superclass
- New attributes and methods can be added
CMP 4266, School of CS & DT, Birmingham City University.
Inheritance (Example)
For example, need to create classes for cars and pickup trucks
All are automobiles
– Have a make, year model, and price
– This can be the attributes for the base class
In addition:
– Car has a number of doors
– Pickup truck has a drive type
CMP 4266, School of CS & DT, Birmingham City University.
Inheritance in UML Diagrams
In UML diagram, inheritance is shown by drawing a line with an
open arrowhead from subclass to superclass
CMP 4266, School of CS & DT, Birmingham City University.
Inheritance in Python
In a class definition for a subclass:
– To indicate inheritance, the superclass name is placed in parentheses
after subclass name
- Example: class Sub_Class_Name(Super_Class_Name):
– The initializer method of a subclass calls the initializer method of the
superclass and then initializes the unique data attributes
– Add method definitions for unique methods
CMP 4266, School of CS & DT, Birmingham City University.
Inheritance in Python (Super class example)
CMP 4266, School of CS & DT, Birmingham City University.
Inheritance in Python (sub classes example)
CMP 4266, School of CS & DT, Birmingham City University.
Testing Inheritance
Output
CMP 4266, School of CS & DT, Birmingham City University.
Super– 7.2 Exercise: Superclass / Supclass
(15 minutes)
In-class
Exercise
Use the Employee class developed from Exercise 6.1:
Create a superclass Person that should include the appropriate attributes
and methods of the class Employee.
Make the class Employee a subclass of the class person
Test the Employee class by creating two or more employee instances and
print their relevant data. To test the inheritance relationship, you need to
use the employee instance to call methods from both the subclass and
superclass.
Superclass Subclass
Person Employee
???
???
CMP4266 , School of CS & DT, Birmingham City University.
Class Variables and Instance Variables
Class variable
– declared inside a class but outside of any method
– also known as static variable
– can be accessed without creating an instance of the class
– shared by all instances of the class
Instance variable
– declared within a method preceded by the self keyword
– each instance of the class can have unique value for the instance variable
CMP 4266, School of CS & DT, Birmingham City University.
Class Variables and Instance Variables (Example)
CMP 4266, School of CS & DT, Birmingham City University.