You are on page 1of 32

END TERM ASSIGNMENT







Python is an open source, general purpose programming language that is easy to
read and powerful. It is an interpreted language, which do not need to be
compiled to run. Python is a high level language that will make a programmer
focus on what to do instead of how to do. Python has been designed to emphasize
on code readability with its significant use of whitespace. The simplicity of Python
language is that the code is Laconic and understandable even to those who have
never written it.

The uses of Python are for websites and web development, desktop GUI
applications development, automation scripts, complex calculation systems, life
support management systems, Games, Robotics, Scientific Computing, Natural
Learning Language and many more. It is designed with features to facilitate data
analysis and visualization.

▪ Free and open-source - You can freely use and distribute


Python, even for commercial use.
▪ Easy to learn - Python has a very simple and elegant syntax. It's
much easier to read and write Python programs compared to
other languages like C++, Java, C#.
▪ Portable - You can move Python programs from one platform
to another, and run it without any changes.
▪ Benefits of Python Programming Language:

1. Interpreted language: the language is processed by the interpreter at

runtime, like PHP or PERL, so you don’t have to compile the program before

execution.

2. Interactive: it can directly interact with the interpreter at the Python

prompt for writing your program.

3. Simplicity: Python is said to be a minimalistic language because it is very


easy to write and read. In case, a programmer faces any problem in using
it, then he can focus only on the issue and not on the language and its
syntax.
4. Free: Python is an open source and free of cost language for which a
developer does not have to pay anything for buying it. Python can be easily
shared, copied and changed too. Because of this feature, Python has been
able to create a very strong community around itself that only makes it
stronger and helps it develop even faster. This community a medium
through which experienced Python professionals share their knowledge
and experience with beginners.
5. Compatibility: A developer can relax and use Python language without
bothering about any compatibility issues because Python is compatible
with numerous platforms, which often is not the case with other languages.
6. Object-Oriented: Both procedure oriented and object oriented
programming is supported by Python. In a procedure oriented
programming, reusable pieces of code are applied by the developer.
Whereas, in object oriented programming, the objects that are based on
data and functionality are used by the developer. Though it is a fact that
OOP languages tend to be complex, Python has managed to stay simple
and neat.
7. Robust Standard Libraries: The Python community has formed a huge
pile of various libraries for Python with the help of which, a developer can
manage documentation, perform unit testing, databases, web browsers,
email, cryptography, graphical user interface and many more things.
A data structure is a specialized format for organizing, processing, retrieving
and storing data. There are several basic and advanced types of data
structures, all designed to arrange data to suit a specific purpose .Most
importantly, data structures frame the organization of information so that
machines and humans can better understand it.

▪ Features :
• Storing data
• Managing resources and services.
• Data exchange.
• Ordering and sorting
• Indexing.
• Searching
• Scalability
▪ Python Specific Data Structures:
These data structures are specific to python language and they give greater
flexibility in storing different types of data and faster processing in python
environment.

• List: It is similar to array with the exception that the data elements
can be of different data types. You can have both numeric and
string data in a python list.
• Tuple: Tuples are similar to lists but they are immutable which
means the values in a tuple cannot be modified they can only be
read.
• Dictionary: The dictionary contains Key-value pairs as its data
elements
• Linked lists :are best if a program is managing a collection of
items that don't need to be ordered, constant time is required for
adding or removing an item from the collection and increased
search time is OK.
• Stacks: are best if the program is managing a collection that
needs to support a LIFO order.
• Queues: should be used if the program is managing a collection
that needs to support a FIFO order.
• Binary trees :are good for managing a collection of items with a
parent-child relationship, such as a family tree.
• Binary search trees: are appropriate for managing a sorted
collection where the goal is to optimize the time it takes to find
specific items in the collection.
• Graphs: work best if the application will analyze connectivity and
relationships among a collection of individuals in a social media
network.

o Description

The program takes a list and key as input and finds the index of the key in
the list using linear search.

Linear search is a method of finding elements within a list. It is also called a


sequential search. It is the simplest searching algorithm because it
searches the desired element in a sequential manner.

It compares each and every element with the value that we are searching
for. If both are matched, the element is found, and the algorithm returns
the key's index position.

o Solution

I. Create a function linear_search that takes a list and key as arguments.


II.
A loop iterates through the list and when an item matching the key is
found, the corresponding index is returned.
III.
If no such item is found, -1 is returned.

o Source code

def linear_search(alist, key):


for i in range(len(alist)):
if alist[i] == key:
return i
return -1

alist = input('Enter the list of numbers: ')


alist = alist.split()
alist = [int(x) for x in alist]
key = int(input('The number to search for: '))

index = linear_search(alist, key)


if index < 0:
print('{} was not found.'.format(key))
else:
print('{} was found at index {}.'.format(key, index))

o Problem explanation

1. The user is prompted to enter a list of numbers.


2. The user is then asked to enter a key to search for.
3. The list and key is passed to linear_search.
4. If the return value is -1, the key is not found and a message is displayed,
otherwise the index of the found item is displayed.

o Runtime test case

Case 1: Case 2:
Enter the list of numbers: 4 5 3 7 Enter the list of numbers: 3 5 6
The number to search for: 7 The number to search for: 2
7 was found at index 3. 2 was not found.
o Description

A list of items is given in random order, and we would like to arrange the
items in an orderly manner
Bubble sort is also known as sinking sort. It is a simple sorting algorithm
that continuously steps through the list to be sorted, comparing each pair
of adjacent items and swapping them if they are not in the correct order.
The steps are repeated until no more swaps are needed, which is when the
list is sorted.

o Solution

I. we have defined a bubble_sort() function which takes list1 as an


argument.
II. Inside the function create a loop with a loop variable i that counts
from the length of the list – 1 to 1.
III. Create an inner loop with a loop variable that counts from 0 up to i
– 1.

IV. Inside the inner loop, if the elements at indexes j and j + 1 are out
of order, then swap them.

V. If in one iteration of the inner loop there were no swaps, then the
list is sorted and one can return prematurely.

o Source code

def bubble_sort(list1):
for i in range(0,len(list1)-1):
for j in range(len(list1)-1):
if(list1[j]>list1[j+1]):
list1[j],list1[j+1] = list1[j+1], list1[j]
return list1

list1 = input('Enter the list of numbers: ').split()


list1 = [int(x) for x in list1]
print("The sorted list is: ", bubble_sort(list1))

o Problem explanation
1. Theuser is prompted to enter a list of numbers.
2. The list is passed to the bubble_sort function.
3. The sorted list is displayed.

o Runtime test case

Case 2:
Case 1:
Enter the list of numbers: 7 3 1 -5 2 10
Enter the list of numbers: 4 2 38 10 5
Sorted list: [-5, 1, 2, 3, 7, 10]
Sorted list: [2, 4, 5, 10, 38]
o Description

The program creates a queue and allows the user to perform enqueue and
dequeue operations on it.

queue is a linear data structure that stores items in First In First Out (FIFO)
manner. With a queue the least recently added item is removed first

o Solution

I. Create a class Queue with instance variable items initialized to an empty list.
II. Define methods enqueue, dequeue and is_empty inside the class Queue.
III. The method enqueue appends data to items.
IV. The method dequeue dequeues the first element in items.
V. The method is_empty returns True only if items is empty.
VI. Create an instance of Queue and present a menu to the user to perform
operations on the queue.

o Source code

class Queue:
def __init__(self):
self.items = []

def is_empty(self):
return self.items == []

def enqueue(self, data):


self.items.append(data)

def dequeue(self):
return self.items.pop(0)

q = Queue()
while True:
print('enqueue <value>')
print('dequeue')
print('quit')
do = input('What would you like to do? ').split()

operation = do[0].strip().lower()
if operation == 'enqueue':
q.enqueue(int(do[1]))
elif operation == 'dequeue':
if q.is_empty():
print('Queue is empty.')
else:
print('Dequeued value: ', q.dequeue())
elif operation == 'quit':
break
o Problem explanation
1. An instance of Queue is created.

2. The user is presented with a menu to perform enqueue and dequeue

operations on the queue.

3. The chosen operation is performed by calling the corresponding method of

the queue.
o Runtime test case

enqueue <value>
dequeue
quit
What would you like to do? dequeue
Queue is empty.
enqueue <value>
dequeue
quit
What would you like to do? enqueue 7
enqueue <value>
dequeue
quit
What would you like to do? dequeue
Dequeued value: 7
enqueue <value>
dequeue
quit
What would you like to do? dequeue
Queue is empty.
enqueue <value>
dequeue
quit
What would you like to do? quit
o Description

The program creates a Graph data structure and allows the user to add vertices
and edges to it
A graph can be easily presented using the python dictionary data types. We
represent the vertices as the keys of the dictionary and the connection between
the vertices also called edges as the values in the dictionary.
Take a look at the following graph −

V = {a, b, c, d, e}
E = {ab, ac, bd, cd, de}

o Solution

I. Create a class Graph.


II. Create a class Vertex.
Each object of Vertex has two instance variables, key and points_to.
III. key is the value of the Vertex object.

IV. points_to is a dictionary with keys being the Vertex objects that the
current object points to.
V. Each such Vertex object pointed to by the current object is mapped
to the weight of the corresponding directed edge.

VI. The class Vertex provides methods to get the key, to add a
neighbour, to get all neighbours, to get the weight of a directed
edge and to test whether a vertex is a neigbour of the current
Vertex object.

VII. The class Graph has one instance variable, vertices.

VIII. vertices is a dictionary that contains vertex values mapped to their


corresponding Vertex objects. Each Vertex object also stores the
vertex value in its key instance variable.

IX. The class Graph provides methods to add a vertex with a given key,
get the Vertex object with a given key, test whether a vertex with a
given key is in the Graph, add an edge between two vertices given
their keys and weight and test whether an edge exists between two
vertices given their keys. The __iter__ method is implemented to
allow iteration over the Vertex objects in the graph.

X. If whenever edge (u, v) is added to the graph, the reverse edge (v,
u) is also added, then this would become the implementation of an
undirected graph.

o Source code

class Graph:
def __init__(self):
self.vertices = {}
def add_vertex(self, key):
vertex = Vertex(key)
self.vertices[key] = vertex

def get_vertex(self, key):

return self.vertices[key]

def __contains__(self, key):


return key in self.vertices

def add_edge(self, src_key, dest_key, weight=1):

self.vertices[src_key].add_neighbour(self.vertices[dest_key], weight)
def does_edge_exist(self, src_key, dest_key):
return self.vertices[src_key].does_it_point_to(self.vertices[dest_key])

def __iter__(self):
return iter(self.vertices.values())

class Vertex:
def __init__(self, key):
self.key = key
self.points_to = {}

def get_key(self):
def add_neighbour(self, dest, weight):
self.points_to[dest] = weight

def get_neighbours(self):

return self.points_to.keys()

def get_weight(self, dest):

return self.points_to[dest]

def does_it_point_to(self, dest):


return dest in self.points_to

g = Graph()
print('Menu')
print('add vertex <key>')
print('add edge <src> <dest> [weight]')
print('display')
print('quit')

while True:
do = input('What would you like to do? ').split()
operation = do[0]
if operation == 'add':
suboperation = do[1]
if suboperation == 'vertex':
key = int(do[2])
if key not in g:
g.add_vertex(key)
else:
print('Vertex already exists.')
elif suboperation == 'edge':
src = int(do[2])
dest = int(do[3])
if src not in g:
print('Vertex {} does not exist.'.format(src))
elif dest not in g:
print('Vertex {} does not exist.'.format(dest))
else:
if not g.does_edge_exist(src, dest):
if len(do) == 5:
weight = int(do[4])
g.add_edge(src, dest, weight)
else:
g.add_edge(src, dest)
else:
print('Edge already exists.')

elif operation == 'display':


print('Vertices: ', end='')
for v in g:
print(v.get_key(), end=' ')
print()

print('Edges: ')
for v in g:
for dest in v.get_neighbours():
w = v.get_weight(dest)
print('(src={}, dest={}, weight={}) '.format(v.get_key(),
dest.get_key(), w))
print()

elif operation == 'quit':


break
o Problem explanation

1. An instance of Graph is created.


2. The user is presented with a menu to perform various operations on the
graph.
3. The corresponding methods are called to perform each operation.
4. The operations are: add vertex with a given key, add edge from a source
vertex to a destination vertex (optionally with weight specified, otherwise
weight=1 is assumed) and to display the all vertices and edges in the graph.

o Runtime test case

Menu

add vertex <key>

add edge <src> <dest> [weight]

display

quit

What would you like to do? add vertex 1


What would you like to do? add vertex 2

What would you like to do? display

Vertices: 1 2

Edges:

What would you like to do? add edge 1 2

What would you like to do? add vertex 3

What would you like to do? display

Vertices: 1 2 3

Edges:

(src=1, dest=2, weight=1)

What would you like to do? add edge 1 3

What would you like to do? add edge 3 1

What would you like to do? display

Vertices: 1 2 3

Edges:

(src=1, dest=2, weight=1)

(src=1, dest=3, weight=1)

(src=3, dest=1, weight=1)

What would you like to do? quit


o Description
A binary tree is a data structure in which every node or vertex has atmost
two children. In Python, a binary tree can be represented in different ways
with different data structures (dictionary, list) and class representation for
a node.

It is also called a sorted ordered binary tree or search tree. It is called


search tree because the search or find operation for a key requires
O(log(n)) time complexity.

Tree represents the nodes connected by edges. It is a non-linear data


structure. It has the following properties.

A Binary Tree mainly consists of three parts. Those are :-

Root or Data

Left Child

Right Child

o Solution

I. Define tree class which has three attributes namely: data left and
right. Here, left represents the left child of the tree and right
represents the right child of the tree.
II. When a tree is created, data will pass to data attribute of the tree
and both left and right will be set to null.
III. Define another class which has an attribute root.
IV. Root represents the root node of the tree and initialize it to null.

V. insert() will add a new node to the tree:

VI. It checks whether the root is null, which means the tre e is empty.
It will add the new node as root.

VII. Else, it will add root to the queue.

VIII. The variable node represents the current node.

IX. First, it checks whether a node has a left and right child. If yes, it
will add both nodes to queue.
* If the left child is not present, it will add the new node as the
left child.
* If the left is present, then it will add the new node as the right
child

o Source code

class Tree:

def __init__(self, data):

self.left = None

self.right = None

self.data = data

def insert(self, data):

if self.data:

if data < self.data:

if self.left is None:

self.left = Tree(data)

else:
self.left.insert(data)

elif data > self.data:

if self.right is None:

self.right = Tree(data)

else:

self.right.insert(data)

else:

self.data = data

def getTree(self):

if self.left:

self.left.getTree()

print( self.data),

if self.right:

self.right.getTree()

root = Tree(30)

root.insert(15)

root.insert(35)

root.insert(9)

root.insert(28)

root.insert(40)

root.getTree()
o Problem explanation

1. An instance of binary tree is created.


The user is presented with a menu to perform various operations
on the binary tree
2. The user will be asked to get values of the root data first
3. The value less than root value moves to the left node
4. The values more than the root value moves to the right node
forming a tree

o Runtime test case

Case 1
Root value =30
Insert (a) , a =15
Insert (b) , b =35
Insert (c) , c =9
Insert (d) , d =28
Insert (e) , e =40

9
15
28
30
35
40

o Description
A stack is a linear data structure that stores items in a Last-In/First-Out (LIFO) or
First-In/Last-Out (FILO) manner. In stack, a new element is added at one end and
an element is removed from that end only. The insert and delete operations are
often called push and pop.

The program creates a stack and allows the user to perform push and pop
operations on it.

o Solution

I. The ‘Stack_struct’ class with required attributes is created.


II. It has an ‘init’ function that is used to create an empty list.
III. Another method named ‘check_empty’ that checks to see if a list is empty.
IV. Another method named ‘add_elements’ is defined that adds elements to the
empty list.
V. A method named ‘delete_elements’ is defined, that deletes elements from the
list.
VI. An object of the ‘Stack_struct’ class is created.
VII. The user input is taken for the operation that needs to be performed.
VIII. Depending on the user’ choice, the operation is performed.
IX. Relevant output is displayed on the console.

o Source code
class Stack_struct:
def __init__(self):
self.items = []
def check_empty(self):
return self.items == []

def add_elements(self, my_data):


self.items.append(my_data)

def delete_elements(self):
return self.items.pop()

my_instance = Stack_struct()
while True:
print('Push <value>')
print('Pop')
print('Quit')
my_input = input('What operation would you like to perform ? ').split()

my_op = my_input[0].strip().lower()
if my_op == 'push':
my_instance.add_elements(int(my_input[1]))
elif my_op == 'pop':
if my_instance.check_empty():
print('The stack is empty')
else:
print('The deleted value is : ', my_instance.delete_elements())
elif my_op == 'Quit':
break
o Problem explanation
1. An instance of Stack is created.
2. The user is presented with a menu to perform push and pop operations on the
stack.
3. The chosen operation is performed by calling the corresponding method of the
stack.

o Runtime test case

Push <value>
Pop
Quit
What operation would you like to perform ? push 2
Push <value>
Pop
Quit
What operation would you like to perform ? push 8
Push <value>
Pop
Quit
What operation would you like to perform ? push 4
Push <value>
Pop
Quit
What operation would you like to perform ? pop
The deleted value is : 4
Push <value>
Pop
Quit
What operation would you like to perform ?
THANK YOU

You might also like