Mod 5 Solutions
Mod 5 Solutions
MODULE -5
1. Explain the methods init__ and __str__ with suitable code example to each.
(8M)(IMP)
__init__
The init method (short for “initialization”) is a special method that gets invoked when an
object is instantiated. Its full name 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
>>> time = Time()
>>> time.print_time()
00:00:00
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.
__str__
__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:
2. Define the terms with example: (i) class (ii) objects (iii) instance variables. (6 M)
(i) Class: A class is a blueprint or a template for creating objects that defines a set of attributes and
methods that the objects will have. In Python, you can define a class using the class keyword
followed by the name of the class. Here's an example
class Dog:
self.name = name
def bark(self):
my_dog = Dog("Buddy")
(ii) An object is an instance of a class. It is created from the blueprint or template provided by the
class and has its own set of attributes and methods. In Python, you can create an object by calling
the class as if it were a function. Here's an example:
my_dog = Dog("Buddy") my_dog is the object.
(iii)Instance variables: Instance variables are variables that belong to a specific instance of a class,
as opposed to class variables, which are shared among all instances of a class. In Python, you can
define instance variables by assigning values to them within the __init__ () method of the
class. Here's an example:
self.name In this program, self.name is an instance variable that holds the name of the dog.
3. Explain the following with syntax and suitable code snippet : i) Class definition ii)
instantiation iii) passing an instance (or objects) as an argument iv) instances as return values
(8M)
i) Class definition:
In Python, a class can be defined using the class keyword followed by the class name and a
colon. Inside the class definition, you can define methods, attributes, and other properties of
the class
ii) Instantiation:
Instantiation is the process of creating an instance of a class, which can be done using the class
name followed by parentheses.
iii) Passing an instance (or objects) as an argument: In Python, you can pass an instance (or
object) of a class as an argument to a function or method. This allows you to manipulate the
instance data in the function or method
iv) Instances as return values: In Python, you can return instances of a class from a function
or method. This allows you to create and return new instances of a class based on some input.
4. Define pure function and modifier. Explain the role of pure functions and modifiers in
application development with suitable python programs (8M)
Definition of Pure Function and Modifier:
1. Pure Function:
A pure function is a function that does not modify any of the objects passed to it as
arguments. It only performs operations and returns a result without causing side effects.
Pure functions are deterministic and always return the same output for the same input.
2. Modifier:
A modifier is a function that modifies the objects it gets as parameters. The changes made
by a modifier are visible to the caller, and they may cause side effects by altering the state
of the passed object.
1. Pure Functions:
Pure functions are easier to test and debug because they don’t rely on or change
the state of external variables or objects.
They are reusable and predictable, which makes them an essential part of
functional programming.
Example: Adding time values without modifying the original objects.
2. Modifiers:
Modifiers are useful when you need to update the state of an object directly.
They are convenient for in-place updates but can make debugging harder if side
effects are not well-understood.
Example: Incrementing time by a certain number of seconds.
the copy module provides a method named deepcopy that copies not only the object but
also the objects it refers to, and the objects they refer to.
Ex:
>>> box3 = copy.deepcopy(box)
>>> box3 is box
False
>>> box3.corner is box.corner
False
box3 and box are completely separate objects.
6. Briefly Explain the printing of objects with an example
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)
09:45:00
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
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
print_time is the name of the method (again), and start is the object the method is invoked on,
which is called the subject..The first parameter of a method is called self, so it would be more
common to write print_time like this:
class Time:
def print_time(self):
print ('%.2d:%.2d:%.2d' % (self.hour, self.minute, self.second))
7. Demonstrate polymorphism with function to find histogram to count the numbers of times
each letter appears in a word and in sentence
Type-based dispatch is useful when it is necessary, but (fortunately) it is not always necessary.
Often you can avoid it by writing functions that work correctly for arguments with different
types
For example,
we used histogram to count the number of times each letter appears in a word.
def histogram(s):
d = dict()
for c in s:
if c not in d:
d[c] = 1
else:
d[c] = d[c]+1
return d
This function also works for lists, tuples, and even dictionaries, as long as the elements of
s are hashable, so they can be used as keys in d.
>>> t = ['spam', 'egg', 'spam', 'spam', 'bacon', 'spam']
>>> histogram(t)
{'bacon': 1, 'egg': 1, 'spam': 4}
Functions that work with several types are called polymorphic. Polymorphism can facilitate
code reuse.
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
In general, if all of the operations inside a function work with a given type, the function
works with that type. The best kind of polymorphism is the unintentional kind, where you discover
that a function you already wrote can be applied to a type you never planned for.
8. Explain the program development concept ‘prototype and patch’ with suitable example
The use of functions demonstrates an application development plan called "prototype and patch."
To illustrate, we will define a class called Time that records the time of day:
class Time:
An alternative is designed development, in which high-level insight into the problem can
make the programming much easier.
When we wrote add-time and increment, we were effectively doing addition in base 60,
which is why we had to carry from one column to the next.
def time_to_int(time):
min = time.hour * 60 + time.min
sec = min * 60 + time.sec
return sec
def int_to_time(sec):
time = Time()
Once the function is found correct, we can use them to rewrite add-time:
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.
# inside class Time:
def __add__(self, other):
seconds = self.time_to_int() + other.time_to_int()
return int_to_time(seconds)
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__. Changing the behaviour of an operator so that it works with
programmer-defined types is called operator overloading.
Type based dispatch
When the + operator is used with a Time object and another type, this logic ensures the correct
method is called:
The implementation of __radd__ ensures the addition is commutative when the Time object
appears on the right side: