Professional Documents
Culture Documents
MODULE 4
Object oriented Programming
Q1. What is Object Oriented Programming what are its advantages? Explain
some key concepts of Object oriented programming ?
Object-Oriented Programming (OOP) is a programming
model that is based on the concept of classes and objects.
As opposed to procedural programming where the focus
is on writing procedures or functions that perform
operations on the data, in object-oriented programming
the focus is on the creations of objects which contain
both data and functions together.
Q2. What is a class? How class can be instantiated and show how class
members are accessed in python?
Class
A class is a blueprint for the object. We can think of class as an sketch of a parrot
with labels. It contains all the details about the name, colors, size etc. Based on
these descriptions, we can study about the parrot. Here, parrot is an object.
Here, we use class keyword to define an empty class Parrot. From class, we
construct instances. An instance is a specific object created from a particular
class.
In the above program, we create a class with name Parrot. Then, we define
attributes. The attributes are a characteristic of an object. Then, we create
instances of the Parrot class. You can create multiple different objects that are of
the same class (have the same variables and functions defined). However, each
object contains independent copies of the variables defined in the class. Here, blu
and woo are references (value) to our new objects. Then, we access the class
attribute using __class __.species. Class attributes are same for all instances of a
class. Similarly, we access the instance attributes using blu.name and blu.age.
However, instance attributes are different for every instance of a class.
Methods/ Instances: Methods are functions defined inside the body of a class.
They are used to define the behaviors of an object. Once there are attributes that
“belong” to the class, you can define functions that will access the class attribute.
These functions are called methods.
Class Attributes: We can see in the following interactive Python session that the
class attribute "a" is the same for all instances, in our example "x" and "y". Besides
this, we see that we can access a class attribute via an instance or via the class
name:
>>> class A:
... a = "I am a class attribute!"
>>> x = A()
>>> y = A()
>>> x.a
'I am a class attribute!'
>>> y.a
'I am a class attribute!'
>>> A.a
'I am a class attribute!'
But be careful, if you want to change a class attribute, you have to do it with the
notation ClassName. AttributeName. Otherwise, you will create a new instance
variable. We demonstrate this in the following example:
class A:
a = "I am a class attribute!"
x = A()
y = A()
x.a = "This creates a new instance attribute for x!"
y.a # Output: 'I am a class attribute!'
A.a # Output : 'I am a class attribute!'
A.a = "This is changing the class attribute 'a'!"
A.a # Output: "This is changing the class attribute 'a'!"
y.a # Output: "This is changing the class attribute 'a'!"
# but x.a is still the previously created instance variable:
x.a # Output: 'This creates a new instance attribute for x!'
Sometimes it is obvious what the attributes of an object should be, but other times
you have to make decisions. For example, imagine you are designing a class to
represent rectangles. What attributes would you use to specify the location and
size of a rectangle? You can ignore angle; to keep things simple, assume that the
rectangle is either vertical or horizontal.
There are at least two possibilities:
• You could specify one corner of the rectangle (or the center), the width, and the
height.
• You could specify two opposing corners.
At this point it is hard to say whether either is better than the other, so we’ll
implement the first one, just as an example.
Here is the class definition:
class Rectangle:
"""Represents a rectangle.
attributes: width, height, corner.
"""
The docstring lists the attributes: width and height are numbers; corner is a Point
object that specifies the lower-left corner. To represent a rectangle, you have to
instantiate a Rectangle object and assign values to the attributes:
box = Rectangle()
box.width = 100.0
box.height = 200.0
box.corner = Point()
box.corner.x = 0.0
box.corner.y = 0.0
The expression box.corner.x means, “Go to the object box refers to and select the
attribute named corner; then go to that object and select the attribute named x.”
What does the key word self in python mean? Explain with example?
Show using python code how __init__ method is invoked when an object is
initiated. Explain its working.
The self-keyword: The self is used to represent the instance of the class. With
this keyword, you can access the attributes and methods of the class in python. It
binds the attributes with the given arguments. When you define methods, you will
need to always provide the first argument to the method with a self keyword.
For example, you can define a class Parrot, which has two attributes name & age
and two methods sing & dance. The methods do a certain task on the supplied
arguments and the along with the keyword self.
The __init__ method:"__init__" is a reseved method in python classes. It is known
as a constructor in object oriented concepts. This method called when an object is
created from the class and it allow the class to initialize the attributes of a class.
You can also provide the values for the attributes at runtime or time of creation.
This is done by defining the attributes inside the init method The following
example illustrates this
Creating Methods/ Instances in Python:
class Parrot:
# instance attributes
def __init__(self, name, age):
self.name = name
self.age = age
# instance method
def sing(self, song):
return "{} sings {}".format(self.name, song)
def dance(self):
return "{} is now dancing".format(self.name)
def change_name(self, new_name):
self.name = new_name
Class variables are shared across all objects while instance variables are
for data unique to each instance.
Instance variable overrides the Class variables having same name which
can accidentally introduce bugs or surprising behavior in our code.
class Shark:
# Class variables
animal_type = "fish"
location = "ocean"
def main():
# First object, set up instance variables of constructor method
sammy = Shark("Sammy", 5)
# Print out instance variable name
print(sammy.name)
# Print out class variable location
print(sammy.location)
# Second object
stevie = Shark("Stevie", 8)
# Print out instance variable name
print(stevie.name)
# Use set_followers method and pass followers instance variable
stevie.set_followers(77)
# Print out class variable animal_type
print(stevie.animal_type)
if __name__ == "__main__":
main()
Output
Sammy
ocean
Stevie
This user has 77 followers
fish
def find_center(rect):
p = Point ()
p.x = rect.corner.x + rect.width/2
p.y = rect.corner.y + rect.height/2
return p
Here is an example that passes box as an argument and assigns the resulting
Point to center:
center = find_center(box)
print_point(center)
(50, 100)
Objects are mutable: You can change the state of an object by making an
assignment to one of its attributes. For example, to change the size of a rectangle
without changing its position, you can modify the values of width and height:
box.width = box.width + 50
box.height = box.height + 100
You can also write functions that modify objects. For example, grow_rectangle
takes a Rectangle object and two numbers, dwidth and dheight, and adds the
numbers to the width and height of the rectangle:
def grow_rectangle(rect, dwidth, dheight):
rect.width += dwidth
rect.height += dheight
Here is an example that demonstrates the effect:
box.width, box.height
(150.0, 300.0)
grow_rectangle(box, 50, 100)
box.width, box.height
(200.0, 400.0)
Inside the function, rect is an alias for box, so when the function modifies rect,
box changes. As an exercise, write a function named move_rectangle that takes a
Rectangle and two numbers named dx and dy. It should change the location of the
rectangle by adding dx to the x coordinate of corner and adding dy to the y
coordinate of corner.
Copying: Aliasing can make a program difficult to read because changes in one
place might have unexpected effects in another place. It is hard to keep track of
all the variables that might refer to a given object.
Copying an object is often an alternative to aliasing. The copy module contains a
function called copy that can duplicate any object:
p1 = Point()
p1.x = 3.0
p1.y = 4.0
import copy
p2 = copy.copy(p1)
p1 and p2 contain the same data, but they are not the same Point.
>>> print_point(p1)
(3, 4)
>>> print_point(p2)
(3, 4)
>>> p1 is p2
False
Debugging: When you start working with objects, you are likely to encounter some
new exceptions. If you try to access an attribute that doesn’t exist, you get an
AttributeError:
>>> p = Point()
>>> print p.z
AttributeError: Point instance has no attribute 'z'
If you are not sure what type an object is, you can ask:
>>> type(p)
<type '__main__.Point'>
If you are not sure whether an object has a particular attribute, you can use the
built-in function hasattr:
>>> hasattr(p, 'x')
True
>>> hasattr(p, 'z')
False
The first argument can be any object; the second argument is a string that
contains the name of the attribute.
Define “Life cycle of an object”. Explain constructing and destructing the
objects with example program?
Typically, an object goes through the following phases during it’s lifetime:
1. Allocating memory space
2. Binding or associating methods
3. Initialization
4. Destruction
Step1: Definition: Python defines its classes with keywowd ‘class’ which is
defined in Python interpretor.
Step2: Initialization: When an instance of the class is created, __init__ method
defined in the class is called. It initializes the attributes for newly created class
instance. A namespace is also allocated for object’s instance variables. __new__
method is also called where the instance gets created.
Step3: Access and Manipulation: Methods defined in a class can be used for
accessing or modifying the state of an object. These are accessors and
manipulators respectively. A class instance is used to call these methods.
Step4: Destrcution: Every object that gets created, needs to be destroyed. This
is done with Python garbage collection (that is reference counting).
class Person:
name = ""
age = 0
def __init__(self, personName, personAge):
self.name = personName
self.age = personAge
p = Person('Pankaj', 34)
print(p.__str__()) # Output: <__main__.Person object at 0x10ff22470>
print(p.__repr__()) # Output <__main__.Person object at 0x10ff22470>
bearObj = Bear()
dogObj = Dog()
class Pdf(Document):
def show(self):
return 'Show pdf contents!'
class Word(Document):
def show(self):
return 'Show word contents!'
documents = [Pdf('Document1'),
Pdf('Document2'),
Word('Document3')]
for document in documents:
print document.name + ': ' + document.show()
Output:
Document1: Show pdf contents!
Document2: Show pdf contents!
Document3: Show word contents!
class Point:
def __init__(self,a=0,b=0):
self.x=a
self.y=b
def __add__(self, p2):
p3=Point()
p3.x=self.x+p2.x
p3.y=self.y+p2.y
return p3
def __str__(self):
return "(%d,%d)"%(self.x, self.y)
p1=Point(10,20)
p2=Point(4,5)
print("P1 is:",p1)
print("P2 is:",p2)
p4=p1+p2 #call for __add__() method
print("Sum is:",p4)
# The output would be –
P1 is: (10,20)
P2 is: (4,5)
Sum is: (14,25)
In the above program, when the statement p4 = p1+p2 is used, it invokes a special
method __add__() written inside the class. Because, internal meaning of this
statement is p4 = p1.__add__(p4) Here, p1 is the object invoking the method.
Hence, self inside __add__() is the reference (alias) of p1. And, p4 is passed as
argument explicitly.
In the definition of __add__(), we are creating an object p3 with the statement –
p3=Point() The object p3 is created without initialization. Whenever we need to
create an object with and without initialization in the same program, we must set
arguments of __init__() for some default values. Hence, in the above program
arguments a and b of __ init__() are made as default rguments with values as zero.
Thus, x and y attributes of p3 will be now zero. In the __add__() method, we are
adding respective attributes of self and p2 and storing in p3.x and p3.y. Then the
object p3 is returned. This returned object is received as p4 and is printed.
We read the URL into a string and then pass that into urllib to retrieve the data from the web.
The urllib library uses the socket library to make the actual network connection to retrieve
the data. We take the string that urllib returns and hand it to BeautifulSoup for parsing.
BeautifulSoup makes use of the object html.parser1 and returns an object. We call the tags()
method on the returned object that returns a dictionary of tag objects. We loop through the
tags and call the get() method for each tag to print out the href attribute.
name attributes with a double underscore prefix, and those attributes then are not be directly
visible to outsiders.
def count(self):
self.__secretCount += 1
print (self.__secretCount)
counter = JustCounter()
counter.count()
counter.count()
# print (counter.__secretCount) error, yes it can't be accessed outside
print (counter._JustCounter__secretCount) # works
Programming Excises:
P1. Demonstrate polymorphism with function to find histogram to count the number of
times each letter appears in a word and in sentence?
def count(str1):
dict = {}
for n in str1:
keys = dict.keys()
if n in keys:
dict[n] += 1
else:
dict[n] = 1
return dict
To count words:
def word_count(sentence):
word_counter = {}
wordlist = sentence.lower().split()
for word in wordlist:
word = re.sub('[.,:*! ]', '', word)
if word in word_counter:
word_counter[word] += 1
else:
word_counter[word] = 1
return word_counter
P2. Write a program that has a class person, inherit a class Student from person which
also has a class MarksAtttendence. Assume the attributes for the person class as:
USN, Name, DOB, Gender. Attributes for Student class as: Class, Branch, Year, M, A.
Attributes for Marks Attendence: Marks, Attendance. Create a student S= Student
(“ 1AB116CS005”, “XYZ”, “18-1-90”, “M”, 85, 98) and display the details of the student.
def show_Details(self):
Person. show_Details(self)
print(self.Class, self.Branch, self.Year, self.Marks, self.Attnd)
#Prints the value of student class definition
P3. Create a student class and initialize it with name and roll number. Design methods
to: a) Display: to display all information of the student b) Set_Age: to assign age to
the student c) Set_marks: to assign marks to the student
class Student():
# Constructor
def __init__(self,name,rollno):
self.name = name
self.rollno = rollno
self.age = 0
self.marks = 0
# To set name
def set_age(self, age):
self.age=age
# To set Marks
def set_marks(self, marks):
self.marks=marks
# To print info
def info(self):
print("Name={},RollNo={},Age={},Marks={}".format(self.name,
self.rollno, self.age, self.marks))
# Driver code
S1 = Student("Geek",53) # An Object of student
S1.set_age(22)
S1.set_marks(90)
S1.info()
P4. Write Python code to create a function named move_rectangle that takes an
object Rectangle and two numbers named dx and dy. It should chance the location of
the Rectangle by adding dx to the x coordinate of corner and adding dy to the y
coordinate of corner.
class Rectangle(object):
"""Represents a rectangle."""
def __init__(self, w, h, p=Point(0,0)):
assert isinstance(p, Point)
self.width = w
self.height = h
self.corner = p
r1 = Rectangle(500,500)
move_rectangle(r1,15,15)
P5. Write a python program to express instances as return values to define a class
REECTANGLE with member’s width, height, corner_x, corner_y, and member function:
to find centre, area and perimeter of a rectangle.
class Rectangle():
def __init__(self, l, w,corner_x=0, corner_y=0):
self.length = l
self.width = w
self.corner_x= corner_x
self.corner_y=corner_y
def rectangle_area(self):
return self.length*self.width
def rectangle_perimeter(self):
return (2 * (self.width + self.height))
def rectangle_center(self):
return (self.corner_x + self.width/2),( self.corner_y + self.height/2)
P6. Write a program that has a class Point with attribute as X and Y co-ordinates.
Create two objects of this class and find the midpoint of both the points. Add a
method reflex_x to class point. Which returns a new point. Which is the reflection of
the point about the x-axis.? Ex: pont(5,10)=> reflex_x returns point(5,-10).
class Point:
""" Create a new Point, at coordinates x, y """
def __init__(self, x=0, y=0):
""" Create a new point at x, y """
self.x = x
self.y = y
def reflex_x(self):
""" Compute my distance from the origin """
return (self.x, -1*self.y )
def show(self):
" Display the co=ordenates"
print(self.x,self.y)
p = Point(3, 4)
q = Point(5, 12)
a = ADD_point(p, q)
a.show()
print(p.reflex_x())
P7. Write a python program to find duration of event if start and end time is given by
defining class TIME.
P8. Using datetime module write a program that gets the current date and prints the
day of the week.
import datetime
now = datetime.datetime.now()
def findDay(date):
day, month, year = (int(i) for i in date.split(' '))
born = datetime.date(year, month, day)
return born.strftime("%A")
def printdate(date):
print ("Current date: ")
print (now.strftime("%d %m %Y"))
print ("Current time: ")
print (now.strftime("%H %M %S"))
# Driver program
printdate(now)
print(findDay(now.strftime("%d %m %Y")))
P9. Write a Python program that uses datetime module with in a class that takes a
birthday as input and prints the age and the number of days, hours, minutes,and
seconds until the next birthday.
# 1. Use the datetime module to write a program that gets the current
date and prints the day of the week.
# 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.
class Time(object):
now = datetime.datetime.now()
def day_of_week(self):
def birthday_stats(birthday):
age = today.year - birthday.year
if (birthday.month == today.month) and (birthday.day <= today.day):
pass
elif birthday.month < today.month:
pass
else:
age -= 1
if len(till_birthday) > 1:
days = int(till_birthday[0])
time = till_birthday[2].split(":")
else:
days = 365
time = till_birthday[0].split(":")
hours = time[0]
mins = time[1]
secs = time[2][:2]
print ("2) You are %s years old; %sd:%sh:%sm:%ss until your next birthday."
% (age, days, hours, mins, secs))
# Driver code
today = Time().now
birthday = Time(1974, 9, 24).date
print ("1) Its a :{}".format(day_of_week(today)))
birthday_stats(birthday)
P10. Consider a user defined class called Time that records the time of the day. Create
a new Time object and assign attributes for hours, minutes and seconds. Write a
function called print_time that takes a Time object and prints it in the form hour:
minutes: second. Write a Boolean function called is_after that takes two time objects,
t1 and t2 and returns True if t1 follows t2 chronologically and False otherwise. Write
a function called increment which adds a give number of seconds to a Time object.
class Time(object):
"""Represents the time of day.
attributes: hour, minute, second"""
def print_time(t):
print ('%.2d:%.2d:%.2d' % (t.hour, t.minute, t.second))
def int_to_time(seconds):
"""Makes a new Time object.
seconds: int seconds since midnight. """
time = Time()
minutes, time.second = divmod(seconds, 60)
time.hour, time.minute = divmod(minutes, 60)
return time
def time_to_int(time):
"""Computes the number of seconds since midnight.
time: Time object. """
minutes = time.hour * 60 + time.minute
seconds = minutes * 60 + time.second
return seconds
def valid_time(time):
"""Checks whether a Time object satisfies the invariants."""
if time.hour < 0 or time.minute < 0 or time.second < 0:
return False
if time.minute >= 60 or time.second >= 60:
return False
return True
def main():
# if a movie starts at noon...
noon_time = Time()
noon_time.hour = 12
noon_time.minute = 0
noon_time.second = 0
print ('Starts at', print_time(noon_time))
if __name__ == '__main__':
main()
class Time(object):
"""Attributes: hours, minutes, seconds"""
def __init__(self,hours,minutes,seconds):
self.hours =hours
self.minutes=minutes
self.seconds=seconds
def print_time(self):
"""prints time object as a string"""
print "%.2d:%.2d:%.2d" % (self.hours, self.minutes, self.seconds)
def _str_(self):
"""returns time object as a string"""
return "%.2d:%.2d:%.2d" % (self.hours, self.minutes, self.seconds)
def name(self,name):
"""names an instance"""
self.name=name
return self.name
def after(t1,t2):
"""checks to see which of two time objects is later"""
if t1.convert_to_seconds()<t2.convert_to_seconds():
return "%s is later" %(t2.name)
elif t1.convert_to_seconds>t2.convert_to_seconds:
return "%s is later" %(t1.name)
else:
return "these events occur simultaneously"
def convert_to_seconds(self):
"""converts Time object to an integer(# of seconds)"""
minutes=self.hours*60+self.minutes
seconds=minutes*60+self.seconds
return seconds
def make_time(self,seconds):
"""converts from an integer to a Time object"""
self.hours=seconds/3600
seconds=seconds-self.hours*3600
self.minutes=seconds/60
seconds=seconds-self.minutes*60
self.seconds=seconds