Ppds Unit 2 Notes
Ppds Unit 2 Notes
Benefits of OOP
Encapsulation allows you to bundle data (attributes) and behaviors (methods) within
a class to create a cohesive unit. By defining methods to control access to attributes
and its modification, encapsulation helps maintain data integrity and promotes
modular, secure code.
It reduces complexity.
It avoids delicacy.
Eases the burden of maintenance
Increase security and confidentially.
Polymorphism allows you to treat objects of different types as instances of the same
base type, as long as they implement a common interface or behavior. Python’s duck
typing make it especially suited for polymorphism, as it allows you to access attributes
and methods on objects without needing to worry about their actual class.
Python Class
A class is a collection of objects. Classes are blueprints for creating objects. A class
defines a set of attributes and methods that the created objects (instances) can have.
Some points on Python class:
Classes are created by keyword class.
Attributes are the variables that belong to a class.
Attributes are always public and can be accessed using the dot (.) operator.
Example: Myclass.Myattribute
Syntax
class ClassName:
<statement-1>
.
.
<statement-N>
Example
Python Objects
An Object is an instance of a Class. It represents a specific implementation of the
class and holds its own data.
An object consists of:
State: It is represented by the attributes and reflects the properties of an object.
Behavior: It is represented by the methods of an object and reflects the response
of an object to other objects.
Identity: It gives a unique name to an object and enables one object to interact
with other objects.
Example
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
p1 = Person("John", 36) // p1 is a object
print(p1.name)
print(p1.age)
Methods
Instance methods are associated with an instance of a class and can modify the
data stored within the instance.
Class methods are associated with the class rather than an instance and can access
and modify class-level data.
Static methods are similar to functions outside of the class and cannot access any
instance or class data.
Predefined Methods
append():
Adds an element to the end of the list.
Syntax: list_name.append(element)
copy():
Returns a shallow copy of the list.
Syntax: list_name.copy()
clear():
Removes all elements from the list.
Syntax: list_name.clear()
count():
Returns the number of times a specified element appears in the list.
Syntax: list_name.count(element)
extend():
Adds elements from another list to the end of the current list.
Syntax: list_name.extend(iterable)
index():
Returns the index of the first occurrence of a specified element.
Syntax: list_name.index(element)
insert():
Inserts an element at a specified position.
Syntax: list_name.insert(index, element)
pop():
Removes and returns the element at the specified position (or the last element if
no index is specified).
Syntax: list_name.pop(index)
remove():
Removes the first occurrence of a specified element.
Syntax: list_name.remove(element)
reverse():
Reverses the order of the elements in the list.
Syntax: list_name.reverse()
sort():
Sorts the list in ascending order (by default).
Syntax: list_name.sort(key=None, reverse=False)
Constructor
A constructor is a special method that is called automatically when an object is
created from a class. Its main role is to initialize the object by setting up its
attributes or state.
New method
The method new is the constructor that creates a new instance of the class while
init is the initializer that sets up the instance’s attributes after creation
Responsible for creating a new instance of the class.
Rarely overridden but useful for customizing object creation and especially in
singleton or immutable objects.
Example
class ClassName:
def __new__(cls, parameters):
instance = super(ClassName, cls).__new__(cls)
return instance
Init method
This method initializes the newly created instance and is commonly used as a
constructor in Python. It is called immediately after the object is created by new
method and is responsible for initializing attributes of the instance.
Types of Constructors
Constructors can be of two types.
1. Default Constructor
A default constructor does not take any parameters other than self. It initializes the
object with default attribute values.
class Car:
def __init__(self):
#Initialize the Car with default attributes
self.make = "Toyota"
self.model = "Corolla"
self.year = 2020
# Creating an instance using the default constructor
car = Car()
print(car.make)
print(car.model)
print(car.year)
Parameterized Constructor
A parameterized constructor accepts arguments to initialize the object’s attributes
with specific values.
class Car:
self.make = make
self.model = model
self.year = year
print(car.make)
print(car.model)
print(car.year)
Inheritance in Python
1. Parent Class:
This is the base class from which other classes inherit.
It contains attributes and methods that the child class can reuse.
2. Child Class:
This is the derived class that inherits from the parent class.
The syntax for inheritance is class ChildClass(ParentClass).
The child class automatically gets all attributes and methods of the parent
class unless overridden.
Types of Inheritance
1. Single Inheritance: Employee inherits from Person, adding a salary attribute.
2. Multiple Inheritance: EmployeePersonJob inherits from both Employee and
Job, allowing access to both name and salary.
3. Multilevel Inheritance: Manager inherits from EmployeePersonJob, which
already includes Employee and Job.
4. Hierarchical Inheritance: AssistantManager also inherits from
EmployeePersonJob, demonstrating multiple child classes inheriting from the
same parent.
5. Hybrid Inheritance: SeniorManager inherits from both Manager (multilevel)
and AssistantManager (hierarchical), combining two inheritance types.
Single Inheritance : One Base One Sub Class
Syntax
class Animal:
def speak(self):
print("Animal Speaking")
#child class Dog inherits the base class Animal
class Dog(Animal):
def bark(self):
print("dog barking")
d = Dog()
d.bark()
d.speak()
Multi-Level inheritance
Syntax
class class1:
<class-suite>
class class2(class1):
<class suite>
class class3(class2):
<class suite>
Example
class Animal:
def speak(self):
print("Animal Speaking")
#The child class Dog inherits the base class Animal
class Dog(Animal):
def bark(self):
print("dog barking")
#The child class Dogchild inherits another child class Dog
class DogChild(Dog):
def eat(self):
print("Eating bread...")
d = DogChild()
d.bark()
d.speak()
d.eat()
Multiple inheritance
Python provides us the flexibility to inherit multiple base classes in the child class.
Syntax
class Base1:
<class-suite>
class Base2:
<class-suite>
class BaseN:
<class-suite>
class Derived(Base1, Base2, ...... BaseN):
<class-suite>
Example
class Calculation1:
def Summation(self,a,b):
return a+b;
class Calculation2:
def Multiplication(self,a,b):
return a*b;
class Derived(Calculation1,Calculation2):
def Divide(self,a,b):
return a/b;
d = Derived()
print(d.Summation(10,20))
print(d.Multiplication(10,20))
print(d.Divide(10,20))
Hierarchical Inheritance
Hierarchical Inheritance is a type of inheritance in which a single base class is inherited by
multiple derived classes. In this scenario, each derived class shares common attributes and
methods from the same base class, forming a hierarchy of classes.
Syntax :
class BaseClass:
# Base class attributes and methods
class DerivedClass1(BaseClass):
# Additional attributes and methods specific to DerivedClass1
class DerivedClass2(BaseClass):
# Additional attributes and methods specific to DerivedClass2
Example
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
pass
class Dog(Animal):
def speak(self):
return f"{self.name} says Woof!"
class Cat(Animal):
def speak(self):
return f"{self.name} says Meow!"
dog = Dog("Buddy")
cat = Cat("Whiskers")
print(dog.speak())
print(cat.speak())
Example
class Calculation1:
def Summation(self,a,b):
return a+b;
class Calculation2:
def Multiplication(self,a,b):
return a*b;
class Derived(Calculation1,Calculation2):
def Divide(self,a,b):
return a/b;
d = Derived()
print(issubclass(Derived,Calculation2))
print(issubclass(Calculation1,Calculation2))
True
False
The isinstance (obj, class) method
The isinstance() method is used to check the relationship between the objects and
classes. It returns true if the first parameter, i.e., obj is the instance of the second
parameter, i.e., class.
class Calculation1:
def Summation(self,a,b):
return a+b;
class Calculation2:
def Multiplication(self,a,b):
return a*b;
class Derived(Calculation1,Calculation2):
def Divide(self,a,b):
return a/b;
d = Derived()
print(isinstance(d,Derived))
True
Method Overriding
Provide some specific implementation of the parent class method in our child class.
When the parent class method is defined in the child class with some specific
implementation, then the concept is called method overriding. We may need to
perform method overriding in the scenario where the different definition of a parent
class method is needed in the child class.
class Bank:
def getroi(self):
return 10;
class SBI(Bank):
def getroi(self):
return 7;
class ICICI(Bank):
def getroi(self):
return 8;
b1 = Bank()
b2 = SBI()
b3 = ICICI()
print("Bank Rate of interest:",b1.getroi());
print("SBI Rate of interest:",b2.getroi());
print("ICICI Rate of interest:",b3.getroi());
Output:
Python does not support method overloading by default, but you can achieve similar
behavior by using default parameters or variable-length arguments.
class Addition:
# first sum for 2 params
def my_sum(self, a, b):
return a + b
# second overloaded sum for 3 params
def my_sum(self, a, b, c):
return a + b + c.
Calling Function
obj.my_sum(value1, value2) # for first func
print(obj.my_sum(3, 4))
print(obj.my_sum(3, 4, 5))
Class Method
The class method in Python is a method, which is bound to the class but not the object
of that class. The static methods are also same but there are some basic differences.
A class method takes cls as the first parameter while a static method needs
no specific parameters.
A class method can access or modify the class state while a static method
can’t access or modify it.
In general, static methods know nothing about the class state. They are
utility-type methods that take some parameters and work upon those
parameters. On the other hand class methods must have class as a
parameter.
We use @classmethod decorator in python to create a class method and we
use @staticmethod decorator to create a static method in python.
Syntax for Class Method.
class my_class:
@classmethod
deffunction_name(cls, arguments):
#Function Body
return value
class my_class:
@staticmethod
deffunction_name(arguments):
#Function Body
return value
The class method takes cls (class) as first The static method does not take any specific
argument. parameter.
Class method can access and modify the Static Method cannot access or modify the
class state. class state.
The class method takes the class as Static methods do not know about class state.
parameter to know about the state of that These methods are used to do some utility tasks
class. by taking some parameters.
Python, there are several built-in Python exceptions that can be raised when an error
occurs during the execution of a program. Here are some of the most common types
of exceptions in Python:
SyntaxError: This exception is raised when the interpreter encounters a syntax
error in the code, such as a misspelled keyword, a missing colon, or an
unbalanced parenthesis.
TypeError: This exception is raised when an operation or function is applied to
an object of the wrong type, such as adding a string to an integer.
NameError: This exception is raised when a variable or function name is not
found in the current scope.
IndexError: This exception is raised when an index is out of range for a list,
tuple, or other sequence types.
KeyError: This exception is raised when a key is not found in a dictionary.
ValueError: This exception is raised when a function or method is called with
an invalid argument or input, such as trying to convert a string to an integer
when the string does not represent a valid integer.
AttributeError: This exception is raised when an attribute or method is not
found on an object, such as trying to access a non-existent attribute of a class
instance.
IOError: This exception is raised when an I/O operation, such as reading or
writing a file, fails due to an input/output error.
ZeroDivisionError: This exception is raised when an attempt is made to divide
a number by zero.
ImportError: This exception is raised when an import statement fails to find or
load a module.
Syntax Error: As the name suggests this error is caused by the wrong syntax
in the code. It leads to the termination of the program.
Example:
There is a syntax error in the code . The ‘if' statement should be followed by
a colon (:), and the ‘print' statement should be indented to be inside
the ‘if' block.
Exceptions: Exceptions are raised when the program is syntactically correct, but
the code results in an error. This error does not stop the execution of the program,
however, it changes the normal flow of the program.
Example:
Here in this code as we are dividing the ‘marks’ by zero so a error will occur
known as ‘ZeroDivisionError’. ‘ZeroDivisionError’ occurs when we try to divide
any number by 0.
Exception Handling Blocks
The try block lets you test a block of code for errors.
The except block lets you handle the error.
The else block lets you execute code when there is no error.
The finally block lets you execute code, regardless of the result of the try-
and except blocks.
Try and Except Statement – Catching Exceptions
Try and except statements are used to catch and handle exceptions in Python.
Statements that can raise exceptions are wrapped inside the try block and the
statements that handle the exception are written inside except block.
Example
a = [1, 2, 3]
try:
print ("Second element = %d" %(a[1]))
print ("Fourth element = %d" %(a[3]))
except:
print ("An error occurred")
Example
def fun(a):
if a < 4:
b = a/(a-3)
print("Value of b = ", b)
try:
fun(3)
fun(5)
except ZeroDivisionError:
print("ZeroDivisionError Occurred and Handled")
except NameError:
print("NameError Occurred and Handled")
The finally block, if specified, will be executed regardless if the try block raises an
error or not.
try:
print(x)
except:
print("Something went wrong")
finally:
print("The 'try except' is finished")
File Handling
File handling is an important part of any web application.
Python has several functions for creating, reading, updating, and deleting files.
The key function for working with files in Python is the open() function.
The open() function takes two parameters; filename, and mode.
"r" - Read - Default value. Opens a file for reading, error if the file does not exist
"a" - Append - Opens a file for appending, creates the file if it does not exist
"w" - Write - Opens a file for writing, creates the file if it does not exist
"x" - Create - Creates the specified file, returns an error if the file exists
f = open("demofile.txt")
f = open("demofile.txt", "rt")
Open File
The open() function returns a file object, which has a read() method for reading the
content of the file:
f = open("demofile.txt", "r")
print(f.read())
f = open("D:\\myfiles\welcome.txt", "r")
print(f.read())
Read Only Parts of the File
By default the read() method returns the whole text, but you can also specify how
many characters you want to return:
f = open("demofile.txt", "r")
print(f.read(5))
Read Lines
f = open("demofile.txt", "r")
print(f.readline())
To write to an existing file, you must add a parameter to the open() function:
f = open("demofile2.txt", "a")
f.write("Now the file has more content!")
f.close()
f = open("demofile3.txt", "w")
f.write("Woops! I have deleted the content!")
f.close()
To create a new file in Python, use the open() method, with one of the following
parameters:
"x" - Create - will create a file, returns an error if the file exists
"a" - Append - will create a file if the specified file does not exists
"w" - Write - will create a file if the specified file does not exists
Example
f = open("myfile.txt", "x")
Example
f = open("myfile.txt", "w")
Delete a File
To delete a file, you must import the OS module, and run its os.remove() function:
import os
os.remove("demofile.txt")
To avoid getting an error, you might want to check if the file exists before you try to
delete it:
Example
import os
if os.path.exists("demofile.txt"):
os.remove("demofile.txt")
else:
print("The file does not exist")
Delete Folder
import os
os.rmdir("myfolder")