Module – 5
Classes and objects: Programmer-defined types, Attributes,
Rectangles, Instances as return values, Objects are mutable,
Copying
Classes and functions: Time, Pure functions, Modifiers
Classes and methods: Object-oriented features, Printing
objects, Another example, A more complicated example, The init
method, The str method, Operator overloading, Type-based
dispatch, Polymorphism, Interface and implementation
Classes and objects
What are classes and objects in
Python?
• Python is an object-oriented programming language.
• Class is an abstract data type which can be defined as a
template or blueprint that describes the behavior /
state that the object of its type support.
• An object is an instance of class . Objects have states
and behaviors. Example: A dog has states - color, name,
breed as well as behaviors – wagging the tail, barking,
eating
• Object is simply a collection of data (variables) and
methods (functions) that act on those data.
• The process of creating this object is called
instantiation
Exercise:
1. Write a definition for a class named Circle with
attributes center and radius, where center is a Point
object and radius is a number.
2. Write a function called draw_rect that takes a Turtle
object and a Rectangle and uses the Turtle to draw the
Rectangle
Classes and Functions
Time
• Define a class called Time that records the time of day. The class
definition looks like this:
class Time :
“""Represents the time of day. attributes: hour, minute, second """
• Create a new Time object and assign attributes for hours, minutes,
and seconds:
time = Time()
time.hour = 11
time.minute = 59
time.second = 30
• User defined Function to display the attribute of object say ob.
def printTime(ob)
print(“Hours :” Ob.hour , ”minute:” Ob.minute, “seconds:” ob.second)
Two Kinds of Functions
1. Pure Functions
2. Modifiers
def add_time(t1, t2):
sum = Time()
sum.hour = t1.hour + t2.hour
sum.minute = t1.minute + t2.minute
sum.second = t1.second + t2.second
return sum
Pure Function
• The function creates a new Time object ,
initializes its attributes and returns a reference
to the new object is called a pure function.
• It is called pure function because it does not
modify any of the objects passed to it as
arguments of the objects passed to it as
arguments and it has no side effects, such as
displaying value or getting user input.
Usage of add_time(t1,t2)
>>> start = Time() >>> duration = Time()
>>> start.hour = 9 >>> duration.hour = 1
>>> start.minute = 45 >>> duration.minute = 35
>>> start.second = 0 >>> duration.second = 0
>>> done = add_time(start, duration)
>>> print_time(done) 10:80:00
• Create two Time objects: start contains the start
time of a movie, like “Avatar”, and duration contains
the run time of the movie, which is one hour 35
minutes.
Example
def add_time(t1, t2): >>> done = add_time(start, duration)
sum = Time() >>>print_time(done)
sum.hour = t1.hour + t2.hour 10:80:00
sum.minute = t1.minute + t2.minute
sum.second = t1.second + t2.second
if sum.second >= 60:
sum.second -= 60
>>> done = add_time(start, duration)
sum.minute += 1
>>>print_time(done)
if sum.minute >= 60: 11:20:00
sum.minute -= 60
sum.hour += 1
return sum
Modifiers
• The functions which are used to modify one or more of
the objects it gets as arguments are called modifiers.
Most modifiers are fruitful.
def increment(time, seconds):
time.second += seconds
if time.second >= 60:
time.second -= 60
time.minute += 1
if time.minute >= 60:
time.minute -= 60
time.hour += 1
Modifiers
• Is this function correct? What happens if seconds is much
greater than sixty?
• In that case, it is not enough to carry once; we have to
keep doing it until time.second is less than sixty. One
solution is to replace the if statements with while
statements. That would make the function correct, but not
very efficient.
• Anything that can be done with modifiers can also be
done with pure functions. In fact, some programming
languages only allow pure functions. There is some
evidence that programs that use pure functions are faster
to develop and less error-prone than programs that use
modifiers. But modifiers are convenient at times, and
functional programs tend to be less efficient.
Prototype and Planned
Development
• Prototype Development
• Planned Development
Prototype Development
• Prototype involves
– Writing a Rough draft of programs ( or prototype)
– Performing a basic calculation
– Testing on a few cases , correcting flaws as we
found them.
• Prototype development leads code
complicated
Planned Development
• High level insight into the problem can make
the programming much easier
• Example : A time object is really a three digit
number in base 60. The second component is
the “Ones Column” the minute component is
the “sixties column” and the hour component
is the thirty six hundred column.
Example
add_time and increment, were effectively doing addition in
base 60, so had to carry from one column to the next.
Other approach - convert Time objects to integers and take
advantage of the fact that the computer knows how to do
integer arithmetic. Here is a function that converts Times to
integers:
def time_to_int(time):
minutes = time.hour * 60 + time.minute
seconds = minutes * 60 + time.second
return seconds
And here is a function that converts an integer to a Time (recall
that divmod divides the first argument by the second and
returns the quotient and remainder as a tuple).
Example 2
def int_to_time(seconds):
time = Time()
minutes, time.second = divmod(seconds, 60)
time.hour, time.minute = divmod(minutes, 60)
return time
rewrite add_time
def add_time(t1, t2):
seconds = time_to_int(t1) + time_to_int(t2)
return int_to_time(seconds)
EXERCISE
1. Write a function called mul_time that takes a Time object and a number and
returns a new Time object that contains the product of the original Time and
the number.
2. Write a program that takes a birthday as input and prints the user’s age and the
number of days, hours, minutes and seconds until their next birthday.
3. For two people born on different days, there is a day when one is twice as old as
the other. That’s their Double Day. Write a program that takes two birth dates
and computes their Double Day.
4. For a little more challenge, write the more general version that computes the day
when one person is n times older than the other.
Classes and Methods
Object Oriented Features
• Python is an object-oriented programming
language, which means that it provides features
that support object-oriented programming, which
has these defining characteristics:
– Programs include class and method definitions.
– Most of the computation is expressed in
terms of operations on objects.
– Objects often represent things in the real world,
and methods often correspond to the ways
things in the real world interact
Printing objects
class Time:
"""Represents the time of day."""
def print_time(time):
print('%.2d:%.2d:%.2d' % (time.hour, time.minute,
time.second))
To call this function, you have to pass a Time object as an
argument:
>> start = Time()
>>> start.hour = 9
>>> start.minute = 45
>>> start.second = 00
>>> print_time(start)
Printing objects
To make print_time a method, all we have to do is move the
function definition inside the class definition. Notice the
change in indentation.
class Time:
def print_time(time):
print('%.2d:%.2d:%.2d' % (time.hour,
time.minute, time.second))
Now there are two ways to call print_time. The first (and
less common) way is to use function syntax:
>>> Time.print_time(start)
09:45:00
Printing objects
In this use of dot notation, Time is the name of the
class, and print_time is the name of the method. start is
passed as a parameter.
The second (and more concise) way is to use method
syntax:
>>> start.print_time()
09:45:00
Methods versus Functions
• Methods are just like functions with two
differences :
– Methods are defined inside a class definition in
order to make the relationship between the class
and the method explicit
– The syntax for invoking a method is different from
the syntax for calling a function.
The init method
• The initialization method is a special method that is
invoked when an object is created or instantiated.
• The name of this method is : _ _ init _ _(two
underscore characters followed by init and then two
more underscores)
• # inside class Time:
def init (self, hour=0, minute=0, second=0):
self.hour = hour
self.minute=minute
self.second = second
The init method
• It is common for the parameters of __init__ to have
the same names as the attributes. The statement
self.hour = hour
stores the value of the parameter hour as an attribute of
self.
• The parameters are optional, so if you call Time with
no arguments, you get the default values.
>>> time = Time()
>>> time.print_time()
00:00:00
The init method
• If you provide one argument, it overrides hour:
>>> time = Time (9)
>>> time.print_time()
09:00:00
• If you provide two arguments, they override hour and
minute.
>>> time = Time(9, 45)
>>> time.print_time()
09:45:00
• And if you provide three arguments, they override all
three default values.
The _ _str_ _ method
• __str__ is a special method, like __init__, that is supposed
to return a string representation of an object. For
example, here is a str method for Time objects:
• # inside class Time:
def __str__(self):
return '%.2d:%.2d:%.2d' % (self.hour, self.minute,
self.second)
• When you print an object, Python invokes the str method:
>>> time = Time(9, 45)
>>> print(time)
09:45:00
• When I write a new class, I almost always start by writing
__init__, which makes it easier to instantiate objects, and
__str__, which is useful for debugging.
Operator Overloading
• By defining other special methods, you can specify the
behavior of operators on programmer-defined types.
• For example, if you define a method named __add__ for
the Time class, you can use the + operator on Time
objects. Here is what the definition might look like:
# inside class Time:
def __add__(self, other):
seconds = self.time_to_int() + other.time_to_int()
return int_to_time(seconds)
Operator Overloading
• And here is how you could use it:
>>> start = Time(9, 45)
>>> duration = Time(1, 35)
>>> print(start + duration)
11:20:00
• When you apply the + operator to Time objects, Python
invokes __add__. When you print the result, Python
invokes __str__.
Type-based dispatch
• The following is a version of __add__ that checks the
type of other and invokes either add_time or increment:
# inside class Time:
def __add__(self, other):
if isinstance(other, Time):
return self.add_time(other)
else:
return self.increment(other)
def add_time(self, other):
seconds = self.time_to_int() + other.time_to_int()
return int_to_time(seconds)
def increment(self, seconds):
seconds += self.time_to_int()
return int_to_time(seconds)
Type-based dispatch
• The built-in function isinstance takes a value and a
class object, and returns True if the value is an
instance of the class.
• If other is a Time object, __add__ invokes
add_time. Otherwise it assumes that the parameter
is a number and invokes increment. This operation
is called a type-based dispatch because it
dispatches the computation to different methods
based on the type of the arguments.
Polymorphism
• Functions that work with several types are called
polymorphic. Polymorphism can facilitate code reuse.
For example, the built-in function sum, which adds the
elements of a sequence, works as long as the elements
of the sequence support addition.
• Since Time objects provide an add method, they work
with sum:
>>> t1 = Time(7, 43)
>>> t2 = Time(7, 41)
>>> t3 = Time(7, 37)
>>> total = sum([t1, t2, t3])
>>> print(total)
23:01:00
Interface and Implementation
• One of the goals of object-oriented design is to make
software more maintainable, which means that you can
keep the program working when other parts of the
system change and modify the program to meet new
requirements.
• A design principle that helps achieve that goal is to keep
interfaces separate from implementations. For objects,
that means that the methods a class provides should not
depend on how the attributes are represented.
• Design the interface carefully, you can change the
implementation without changing the interface, which
means that other parts of the program don’t have to
change