Download as pdf or txt
Download as pdf or txt
You are on page 1of 64

GOKARAJU RANGARAJU

INSTITUTE OF ENGINEERING AND TECHNOLOGY


Department of Computer Science and Engineering

PYTHON
PROGRAMMING
Course Code : GR20A2068
Object-oriented programming
Paradigms
Paradigm can also be termed as a method to solve some problems or
do some tasks. A programming paradigm is an approach to solving
the problem using some programming language or also we can say it
is a method to solve a problem using tools and techniques that are
available to us following some approach.

Procedural programming:
A step-by-step procedure is followed sequentially to solve a problem

Object-oriented programming (OOP)


Real World entities or concepts are modeled using objects
 Main concepts of Object-Oriented Programming (oops)

Class

Objects

Polymorphism

Encapsulation

Inheritance
Python is a multi-paradigm programming language. It supports different
programming approaches.

One of the popular approaches to solving a programming problem is by


creating objects. This is known as Object-Oriented Programming (OOP).

An object has two characteristics:


attributes
behavior

Let's take an example:


A parrot is an object, as it has the following properties:
name, age, color as attributes
singing, dancing as behavior
Class
A class is a collection of objects. A class contains the blueprints or the
prototype from which the objects are being created. It is a logical
entity that contains some attributes and methods.

We can think of a class as a sketch of a parrot with labels. It


contains all the details about the name, colors, size, etc. Based on
these descriptions, we can study the parrot. Here, a parrot is an
object.

An example of class of parrot can be :

Class parrot
pass
The class keyword is used to create an empty class called Parrot. We create instances from classes. A unique
object formed from a certain class is referred to as an instance.

Class Definition Syntax:

class ClassName:
#statement1

#statementN

Objects

The object is an entity that has a state and behavior associated with it. It may be any
real-world object like a mouse, keyboard, chair, table, pen, etc. Integers, strings,
floating-point numbers, even arrays, and dictionaries, are all objects.

An object (instance) is an instantiation of a class. When class is defined, only the


description for the object is defined. Therefore, no memory or storage is allocated.
An example of object of parrot class can be:
• An object consists of :

• State: It is represented by the attributes of an object. It


also reflects the properties of an object.

• Behavior: It is represented by the methods of an object. It


also 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
• class MyClass:
x = 5

• OBJECT
• p1 = MyClass()
print(p1.x)
• O/p: 5
Object declaration
• class MyClass:
mem = 5
• Obj=MyClass
• Print( obj.mem)
_init_ a built in function

• It is to declare and initialize the instance variables of a class


• Instance variable has a copy in the object.
• Init is always executed when a class is used
• class Person:
def __init__(self, name, age):
self.name = name
self.age = age
p1 = Person("John", 36)
print(p1.name)
print(p1.age)
• Cls is the default parameter that represent the class.
Object Methods- method in a class

class Person:
def __init__(self, name, age):
self.name = name
self.age = age

def myfunc(self):
print("Hello my name is " + self.name, +self.age)

p1 = Person("John", 36)
p1.myfunc()
Self parameter
The self parameter is a reference to the current instance of the class, and is used to access variables that belong to the
class.

It does not have to be named self , you can call it whatever you like, but it has to be the first parameter of any function
in the class:

class Person:
def __init__(mysillyobject, name, age):
mysillyobject.name = name
mysillyobject.age = age

def myfunc(abc):
print("Hello my name is " + abc.name)

p1 = Person("John", 36)
p1.myfunc()
DELETE

• You can delete properties on objects by using


the del keyword:
• del p1.age
Example 1: Creating Class and Object in Python
class Parrot:
species = "bird"
def __init__(self, name, age): # a special function
self.name = name
self. age = age
blu = Parrot("Blu", 10)
woo = Parrot("Woo", 15)
OUTPUT:
print("Blu is a”,blu.name, blu.age)
print("Woo is also a {}".format(woo.__class__.species)) Blu is a Blu 10
Woo is also a bird
print("{} is {} years old".format( blu.name, blu.age)) Blu is 10 years old
print("{} is {} years old".format( woo.name, woo.age)) Woo is 15 years old
What is a static method?
Static methods in Python are extremely like python class-level
methods, the difference being that a static method is bound to a class
rather than the objects for that class.
This means that a static method can be called without an object for
that class. This also means that static methods cannot modify the
state of an object as they are not bound to it.

The staticmethod() built-in function returns a static method for a given


function.

A static method is also a method that is bound to the class and not the
object of the class.
A static method can’t access or modify the class state.
It is present in a class because it makes sense for the method to be
present in class.
Example 1: Create a static method using staticmethod()
class Mathematics:

def addNumbers(x, y):


return x + y

# create addNumbers static method


Mathematics.addNumbers = staticmethod(Mathematics.addNumbers)

print('The sum is:', Mathematics.addNumbers(5, 10))

OUTPUT:

The sum is 15
Class Method
The class method decorator is a built-in function decorator that is an expression
that getsevaluated after your function is defined. The result of that evaluation
shadows your function definition.
A class method receives the class as an implicit first argument, just like an
instance method receives the instance

•A class method is a method that is bound to the class and not the object
of the class.
•They have the access to the state of the class as it takes a class
parameter that points to the class and not the object instance.
•It can modify a class state that would apply across all the instances of
the class. For example, it can modify a class variable that will apply to all
the instances.
def show(self):
print(self.name + "'s age is: " + str(self.age))

jessa = Student('Jessa', 20)


jessa.show()

# create new object using the factory method


joy = Student.calculate_age("Joy", 1995)
joy.show()

from datetime import date


OUTPUT:
class Student:
def __init__(self, name, age): Jessa's age is: 20
self.name = name John's age is: 26
self.age = age

@classmethod
def calculate_age(cls, name, birth_year):
# calculate age an set it as a age
# return new object
return cls(name, date.today().year - birth_year)
Class method vs Static Method
• 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.
Inheritance

Inheritance is the capability of one class to derive or inherit the properties from
another class. The class that derives properties is called the derived class or child
class and the class from which the properties are being derived is called the base
class or parent class. The benefits of inheritance are:

• It represents real-world relationships well.


• It provides the reusability of a code. We don’t have to write the same code
again and again. Also, it allows us to add more features to a class without
modifying it.
• It is transitive in nature, which means that if class B inherits from another class
A, then all the subclasses of B would automatically inherit from class A.
Methods
Methods are functions defined inside the body of a class. They are
used to define the behaviors of an object.
Example 2 : Creating Methods 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)
OUTPUT:
def dance(self):
return "{} is now dancing".format(self.name)
Blu sings 'Happy'
# instantiate the object Blu is now dancing
blu = Parrot("Blu", 10)

# call our instance methods


print(blu.sing("'Happy'"))
print(blu.dance())
Use of Inheritance in Python
def whoisThis(self):
# parent class print("Penguin")
class Bird: def run(self):
print("Run faster")
def __init__(self):

print("Bird is ready") peggy = Penguin()


peggy.whoisThis()
def whoisThis(self):
peggy.swim()
print("Bird") peggy.run()
def swim(self): `

print("Swim faster")

# child class
OUTPUT:
class Penguin(Bird):
Bird is ready
def __init__(self):
Penguin is ready
# call super() function Penguin
Swim faster
super().__init__() Run faster
print("Penguin is ready")
In the above program, we created two classes i.e. Bird
(parent class) and Penguin (child class). The child class
inherits the functions of a parent class. We can see this
from the swim() method.

Again, the child class modified the behavior of the parent


class. We can see this from the whoisThis() method.
Furthermore, we extend the functions of the parent
class, by creating a new run() method.

Additionally, we use the super() function inside the


__init__() method. This allows us to run the __init__()
method of the parent class inside the child class.
Encapsulation

Encapsulation is one of the fundamental concepts in object-


oriented programming (OOP). It describes the idea of
wrapping data and the methods that work on data within
one unit. This puts restrictions on accessing variables and
methods directly and can prevent the accidental
modification of data. To prevent accidental change, an
object’s variable can only be changed by an object’s
method
Data Encapsulation in Python

class Computer: # using setter function


c.setMaxPrice(1000)
c.sell()
def __init__(self):
self.__maxprice = 900

def sell(self):
print("Selling Price:
{}".format(self.__maxprice))

OUTPUT:
def setMaxPrice(self, price):
self.__maxprice = price Selling Price: 900
Selling Price: 900
Selling Price: 1000
c = Computer()
c.sell()
c.__maxprice = 1000
c.sell()
• Polymorphism
Polymorphism is an ability (in OOP) to use a common interface for
multiple forms (data types).
Polymorphism simply means having many forms.
Using Polymorphism in Python (Example)
class Parrot:

def fly(self):
print("Parrot can fly")

def swim(self):
print("Parrot can't swim")

class Penguin:

def fly(self):
print("Penguin can't fly")

def swim(self):
print("Penguin can swim")
# common interface
def flying_test(bird):
bird.fly()

#instantiate objects
blu = Parrot()
peggy = Penguin()

# passing the object


flying_test(blu)
flying_test(peggy)

OUTPUT:

Parrot can fly


Penguin can’t fly
Python Constructor
A constructor is a special type of method (function) that is used to initialize
the instance members of the class.

Constructors can be of two types.


1.Parameterized Constructor
2.Non-parameterized Constructor

Constructor definition is executed when we create the object


of this class. Constructors also verify that there are enough
resources for the object to perform any start-up task.
Constructors are generally used for instantiating an object. The task of
constructors is to initialize(assign values) to the data members of the
class when an object of the class is created. In Python the __init__()
method is called the constructor and is always called when an object is
created.
Syntax of constructor declaration :

def __init__(self):
# body of the constructor

Creating the constructor in python


In Python, the method the __init__() simulates the constructor of the class.
This method is called when the class is instantiated. It accepts the self-
keyword as a first argument which allows accessing the attributes or method
of the class.
We can pass any number of arguments at the time of creating the class
object, depending upon the __init__() definition. It is mostly used to
initialize the class attributes. Every class must have a constructor, even if it
simply relies on the default constructor.
Example:

class Employee:
def __init__(self, name, id):
self.id = id
self.name = name
def display(self):
print("ID: %d \nName: %s" % (self.id, self.name))
emp1 = Employee("John", 101)
emp2 = Employee("David", 102) OUTPUT:
# accessing display() method to print employee 1 information ID: 101
emp1.display() Name: John
ID: 102
# accessing display() method to print employee 2 information
Name: David
emp2.display()
Default constructor:
The default constructor is a simple constructor which doesn’t accept any arguments. Its
definition has only one argument which is a reference to the instance being
constructed.
When we do not include the constructor in the class or forget to declare it, then that
becomes the default constructor. It does not perform any task but initializes the objects.
Consider the following example.

Example
class Student:
roll_num = 101
OUTPUT:
name = "Joseph"
101 Joseph
def display(self):
print(self.roll_num,self.name)

st = Student()
st.display()
Python Non-Parameterized Constructor
The non-parameterized constructor uses when we do not want to manipulate the
value or the constructor that has only self as an argument. Consider the following
example.

Example
class Student:
# Constructor - non parameterized
def __init__(self):
print("This is non parametrized constructor")
def show(self,name):
print("Hello",name)
student = Student()
student.show("John")
Python Parameterized Constructor
The parameterized constructor has multiple parameters along with the self. Consider the following example.

Example
class Student:
# Constructor - parameterized
def __init__(self, name):
print("This is parametrized constructor")
self.name = name
def show(self):
print("Hello",self.name)
student = Student("John")
student.show()

Output:

This is parametrized constructor


Hello John
Example:

class Calculator:

def add_numbers(num1, num2):


return num1 + num2

# convert add_numbers() to static method


Calculator.add_numbers = staticmethod(Calculator.add_numbers)

sum = Calculator.add_numbers(5, 7)
print('Sum:', sum)

# Output: Sum: 12
Operator Overloading in Python
Operator Overloading means giving extended meaning beyond their predefined
operational meaning. For example, operator + is used to add two integers as well as join
two strings and merge two lists. It is achievable because ‘+’ operator is overloaded by int
class and str class. You might have noticed that the same built-in operator or function
shows different behavior for objects of different classes, this is called Operator
Overloading.

Example:
print (14 + 32)
# Now, we will concatenate the two strings OUTPUT:
print (“Gokaraju" + “Rangaraju")
46
# We will check the product of two numbers GokarajuRangaraju
print (23 * 14) 322
XYZXYZXYZ
# Here, we will try to repeat the String
print ("X Y Z " * 3)
How to Overload the Operators in Python?

Suppose the user has two objects which are the physical representation of a user-
defined data type class. The user has to add two objects using the "+" operator, and
it gives an error. This is because the compiler does not know how to add two
objects. So, the user has to define the function for using the operator, and that
process is known as "operator overloading". The user can overload all the existing
operators by they cannot create any new operator. Python provides some special
functions, or we can say magic functions for performing operator overloading, which
is automatically invoked when it is associated with that operator. Such as, when the
user uses the "+" operator, the magic function __add__ will automatically invoke in
the command where the "+" operator will be defined.
Program 2: defining Overloading operator in another object
Python program for defining the overloading operator inside another object.

Example:

class complex_1:
def __init__(self, X, Y):
self.X = X
self.Y = Y

# Now, we will add the two objects


def __add__(self, U):
return self.X + U.X, self.Y + U.Y

Object_1 = complex_1(23, 12) OUTPUT:


Object_2 = complex_1(21, 22)
(44,34)
Object_3 = Object_1 + Object_2
print (Object_3)
• Program 3: Overloading comparison operators in
Python
Example:
class example_1:
def __init__(self, X):
self.X = X
def __gt__(self, U):
if(self.X > U.X):
return True Output:
else: Case 1:
return False
object_1 = example_1(int( input( print ("Please enter the value: ")))) Please enter the value: 23
Please enter the value: 12
object_2 = example_1(int (input( print("Please enter the value: "))))
The object_1 is greater than object_2
if(object_1 > object_2):
print ("The object_1 is greater than object_2") Case 2:
else: Please enter the value: 20
Please enter the value: 31
print ("The object_2 is greater than object_1") The object_2 is greater than object_1
Inheritance and Composition in Python

What is Inheritance (Is-A Relation)?

It is a concept of Object-Oriented Programming. Inheritance is a


mechanism that allows us to inherit all the properties from
another class. The class from which the properties and
functionalities are utilized is called the parent class (also called
as Base Class). The class which uses the properties from
another class is called as Child Class (also known as Derived
class). Inheritance is also called an Is-A Relation.
Syntax :

# Parent class
class Parent :
# Constructor
# Variables of Parent class

# Methods
...

...

# Child class inheriting Parent class


class Child(Parent) :
Classes are depicted as boxes in the diagram above. An arrow
# constructor of child class
pointing from Derived Class (Child Class) to Base Class represents
# variables of child class
the inheritance connection (Parent Class). The term extends
# methods of child class
indicates that the Child Class is inherited or derived from the
Parent Class.
...

...
Example: # creating object of child class
obj = Child()
# parent class
class Parent: # calling parent class m1() method
obj.m1()
# parent class method
def m1(self): # calling child class m2() method
print('Parent Class Method obj.m2()
called...')

# child class inheriting parent class


class Child(Parent):

# child class constructor


def __init__(self):
OUTPUT:
print('Child Class object
created...')
Child Class object created...
Parent Class Method called...
# child class method
Child Class Method called...
def m2(self):
print('Child Class Method
called...')
What is Composition (Has-A Relation)?

It is one of the fundamental concepts of Object-Oriented Programming. In


this concept, we will describe a class that references to one or more
objects of other classes as an Instance variable. Here, by using the class
name or by creating the object we can access the members of one class
inside another class. It enables creating complex types by combining
objects of different classes. It means that a class Composite can contain
an object of another class Component. This type of relationship is known
as Has-A Relation.
Syntax:

class A :

# variables of class A
# methods of class A
...
...

class B :
# by using "obj" we can access member's of class A.
obj = A()

# variables of class B
In the above figure Classes are represented as boxes with the # methods of class B
class name Composite and Component representing Has-A
relation between both of them. ...
...
# composite class instance method
Example: def m2(self):

class Component: print('Composite class m2()


method executed...')
# composite class constructor
def __init__(self): # calling m1() method of
print('Component class object component class
created...') self.obj1.m1()
# composite class instance method
def m1(self):
print('Component class m1() method # creating object of composite class
executed...') obj2 = Composite()
class Composite:
# calling m2() method of composite class
# composite class constructor obj2.m2()
def __init__(self):
Output
# creating object of component class
Component class object created...
self.obj1 = Component()
Composite class object also created...
Composite class m2() method executed...
print('Composite class object also
Component class m1() method executed...
created...')
Method Overriding in Python

• Method overriding is an ability of


any object-oriented programming
language that allows a subclass or
child class to provide a specific
implementation of a method that is
already provided by one of its super-
classes or parent classes. When a
method in a subclass has the same
name, same parameters or signature
and same return type(or sub-type)
as a method in its super-class, then
the method in the subclass is said
to override the method in the super-
class.
Method overriding in Python is when you have two methods with
the same name that each perform different tasks. This is an
important feature of inheritance in Python.

There are two prerequisite conditions for Method overriding:


1.Inheritance should be present in the code, method overriding
cannot be performed in the same class, and overriding can only be
executed when a child class is derived through inheritance.
2.The child class should have the same name and the same number
of parameters as the parent class.
Example:

# Python program to demonstrate


# calling the parent's class method
# inside the overridden method

class Parent():

def show(self):
print("Inside Parent")

class Child(Parent):

def show(self):

# Calling the parent's class


# method
Parent.show(self) OUTPUT:
print("Inside Child")
Inside Parent
# Driver's code Inside Child
obj = Child()
obj.show()
Multiple Inheritance in Python

Inheritance is the mechanism to achieve the re-usability of


code as one class(child class) can derive the properties of
another class(parent class). It also provides transitivity ie. if
class C inherits from P then all the sub-classes of C would
also inherit from P.

Multiple Inheritance
When a class is derived from more than one base class it is
called multiple Inheritance. The derived class inherits all the
features of the base case.
Syntax:

Class Base1:
Body of the class

Class Base2:
Body of the class

Class Derived(Base1, Base2):


Body of the class
Example
class Base1:
pass

class Base2:
pass

class MultiDerived(Base1, Base2):


pass

Python Multilevel Inheritance


We can also inherit from a derived class. This is called multilevel
inheritance. It can be of any depth in Python.
In multilevel inheritance, features of the base class and the derived
class are inherited into the new derived class.
An example with corresponding visualization is given below.
Example:

class Base:
pass

class Derived1(Base):
pass

class Derived2(Derived1):
pass

Here, the Derived1 class is derived from the Base


class, and the Derived2 class is derived from the
Derived1 class.
Abstract Classes in Python

An abstract class can be considered as a blueprint for other classes.


It allows you to create a set of methods that must be created within
any child classes built from the abstract class. A class which contains
one or more abstract methods is called an abstract class. An abstract
method is a method that has a declaration but does not have an
implementation. While we are designing large functional units we
use an abstract class. When we want to provide a common interface
for different implementations of a component, we use an abstract
class
Why use Abstract Base Classes :

By defining an abstract base class, you can define a common


Application Program Interface(API) for a set of subclasses. This
capability is especially useful in situations where a third party is
going to provide implementations, such as with plugins, but can also
help you when working in a large team or with a large code-base
where keeping all classes in your mind is difficult or not possible.
How Abstract Base classes work :

By default, Python does not provide abstract classes. Python comes


with a module that provides the base for defining Abstract Base
classes(ABC) and that module name is ABC. ABC works by
decorating methods of the base class as abstract and then registering
concrete classes as implementations of the abstract base. A method
becomes abstract when decorated with the keyword
@abstractmethod.
Example: class Quadrilateral(Polygon):
from abc import ABC, abstractmethod
# overriding abstract method
class Polygon(ABC): def noofsides(self):
print("I have 4 sides")
@abstractmethod
def noofsides(self): # Driver code
pass R = Triangle()
R.noofsides()
class Triangle(Polygon):
K = Quadrilateral()
# overriding abstract method K.noofsides()
def noofsides(self):
print("I have 3 sides") R = Pentagon()
R.noofsides()
class Pentagon(Polygon):
K = Hexagon()
# overriding abstract method K.noofsides()
def noofsides(self):
print("I have 5 sides")
OUTPUT:
class Hexagon(Polygon):
I have 3 sides
# overriding abstract method I have 4 sides
def noofsides(self): I have 5 sides
print("I have 6 sides") I have 6 sides
Multithreading in Python 3
A thread is the smallest unit of a program or process executed
independently or scheduled by the Operating System. In the computer
system, an Operating System achieves multitasking by dividing the
process into threads. A thread is a lightweight process that ensures the
execution of the process separately on the system. In Python 3, when
multiple processors are running on a program, each processor runs
simultaneously to execute its tasks separately.
Benefits of Multithreading in Python
Following are the benefits to create a multithreaded
application in Python, as follows:
1.It ensures effective utilization of computer system
resources.
2.Multithreaded applications are more responsive.
3.It shares resources and its state with sub-threads (child)
which makes it more economical.
4.It makes the multiprocessor architecture more effective
due to similarity.
5.It saves time by executing multiple threads at the same
time.
6.The system does not require too much memory to store
multiple threads.
• A thread contains all this information in a Thread
Control Block (TCB):
• Thread Identifier: Unique id (TID) is assigned to every
new thread
• Stack pointer: Points to thread’s stack in the process.
Stack contains the local variables under thread’s scope.
• Program counter: a register that stores the address of
the instruction currently being executed by thread.
• Thread state: can be running, ready, waiting, start or
done.
• Thread’s register set: registers assigned to thread for
computations.
• Parent process Pointer: A pointer to the Process
control block (PCB) of the process that the thread lives
on.
Methods Description

start() A start() method is used to initiate the activity of a


thread. And it calls only once for each thread so that the
execution of the thread can begin.

run() A run() method is used to define a thread's activity and


can be overridden by a class that extends the threads
class.

join() A join() method is used to block the execution of another


code until the thread terminates
Follow the given below steps to implement the threading module in Python
Multithreading:

1. Import the threading module


Create a new thread by importing the threading module, as shown.
Syntax:
import threading

2. Declaration of the thread parameters:


It contains the target function, argument, and kwargs as the parameter in the Thread() class.

Target: It defines the function name that is executed by the thread.


Args: It defines the arguments that are passed to the target function name.
For example:

import threading
def print_hello(n):
print("Hello, how old are you ", n)
t1 = threading.Thread( target = print_hello, args =(18, ))
3. Start a new thread:
To start a thread in Python multithreading, call the thread class's object. The start() method can be called once for
each thread object; otherwise, it throws an exception error.

Syntax:
t1.start()
t2.start()

4. Join method:
It is a join() method used in the thread class to halt the main thread's execution and waits till the complete
execution of the thread object. When the thread object is completed, it starts the execution of the main thread in
Python.

Joinmethod.py
import threading
def print_hello(n):
Print("Hello, how old are you? ", n)
T1 = threading.Thread( target = print_hello, args = (20, ))
T1.start()
T1.join()
Print("Thank you")
Output:
Hello, how old are you? 20
Thank you
5. Synchronizing Threads in Python

It is a thread synchronization mechanism that ensures no two threads can


simultaneously execute a particular segment inside the program to access the
shared resources. The situation may be termed a critical section. We use a race
condition to avoid the critical section condition, in which two threads do not
access resources at the same time.
Let's write a program to use the threading module in Python Multithreading.
Example:

import time # import time module


import threading t = time.time() # get total time to execute the functions
from threading import * #cal_cube(ar)
def cal_sqre(num): # define a square calculating function #cal_sqre(ar)
print(" Calculate the square root of the given number") th1 = threading.Thread(target=cal_sqre, args=(ar, ))
for n in num: # Use for loop th2 = threading.Thread(target=cal_cube, args=(ar, ))
time.sleep(0.3) # at each iteration it waits for 0.3 time th1.start()
print(' Square is : ', n * n) th2.start()
th1.join()
def cal_cube(num): # define a cube calculating function th2.join()
print(" Calculate the cube of the given number") print(" Total time taking by threads is :", time.time() -
for n in num: # for loop t) # print the total time
time.sleep(0.3) # at each iteration it waits for 0.3 time print(" Again executing the main thread")
print(" Cube is : ", n * n *n) print(" Thread 1 and Thread 2 have finished their execution.")

ar = [4, 5, 6, 7, 2] # given array


OUTPUT:

Calculate the square root of the given number


Calculate the cube of the given number
Square is: 16
Cube is: 64
Square is: 25
Cube is: 125
Square is: 36
Cube is: 216
Square is: 49
Cube is: 343
Square is: 4
Cube is: 8
Total time taken by threads is: 1.5140972137451172
Again executing the main thread
Thread 1 and Thread 2 have finished their execution.
Thank You

You might also like