DSA-Lab Manual Data Science 2022-23
DSA-Lab Manual Data Science 2022-23
LAB MANUAL
(2023-24)
CONTENTS
To be the fountainhead of novel ideas & innovations in science & technology & persist to be a
foundation of pride for all Indians.
To provide value based broad Engineering, Technology and Science where education
in students are urged to develop their professional skills.
Attaining global recognition in computer science and engineering education, research and
training to meet the growing needs of the industry and society.
Provide quality undergraduate and postgraduate education, in both the theoretical and applied
foundations of computer science, and train students to effectively apply this education to solve
real-world problems, thus amplifying their potential for lifelong high-quality careers.
1. To prepare students for successful careers in software industry that meet the needs of
Indian and multinational companies.
2. To develop the skills among students to analyze real world problem & implement with
computer engineering solution and in multidisciplinary projects.
4. To develop the ability to work with the core competence of computer science &
engineering i.e. software engineering, hardware structure & networking concepts so that
one can find feasible solution to real world problems.
PO2. Problem analysis: Identify, formulate, research literature, and analyze complex
engineering problems reaching substantiated conclusions using first principles of mathematics,
natural sciences, and engineering sciences.
PO5. Modern tool usage: Create, select, and apply appropriate techniques, resources, and
modern engineering and IT tools including prediction and modeling to complex engineering
activities with an understanding of the limitations.
PO6. The engineer and society: Apply reasoning informed by the contextual knowledge to
assess societal, health, safety, legal and cultural issues and the consequent responsibilities
relevant to the professional engineering practice.
PO8. Ethics: Apply ethical principles and commit to professional ethics and responsibilities
and norms of the engineering practice.
PO9. Individual and team work: Function effectively as an individual, and as a member or
leader in diverse teams, and in multidisciplinary settings.
PO11. Project management and finance: Demonstrate knowledge and understanding of the
engineering and management principles and apply these to one’s own work, as a member and
leader in a team, to manage projects and in multidisciplinary environments.
PO12. Life-long learning: Recognize the need for, and have the preparation and ability to
engage in independent and life-long learning in the broadest context of technological change
LC-DS02.1 Understand basic data structures such as arrays, linked lists. BT-1
LC-DS02.2 Introduce the concept of data structures through ADT including stack. BT-2
LC-DS02.4 Understand the basic concept of Tree and Graph and their operations. BT-2
INDEX
Experiment No. 1
Program for insertion and deletion in array at different positions
#include<stdio.h>
#include<stdlib.h>
int Insert();
int Delete();
int main()
{
int ch;
while(1){
ch=menu();
switch(ch)
{
case 1:
Insert();
break;
case 2:
Delete();
break;
case 3:
printf("===========Thank You=============\n");
exit(0);
default:
printf("Wrong choice\n");
}
}
return 0;
}
int menu(){
int ch;
printf("\nWhat your want to do in your array\n");
printf("\nOPERATIONS \n\n");
printf("1.Insert\n");
printf("2.Delete\n");
printf("3.Close\n");
scanf("%d",&ch);
return ch;
}
for(i=siz;i>pos-1;i--)
{
a[i]=a[i-1];
}
a[pos-1]=value; printf("Your value ");
printf("%d",value);printf(" is inserted at ");
printf("%d",pos);printf(" position\n");
printf("# your new array after insertion is :-\n");
for(i=0;i<=siz;i++)
{
if(i==pos-1)
{
printf("%d ",a[i]);
}
else
{
printf("%d ",a[i]);
}
}
}
return 0;
}
Output
Output
Ans.) Advantages:
We can put in place other data structures like stacks, queues, linked lists, trees, graphs,
etc. in Array.
Arrays can sort multiple elements at a time.
We can access an element of Array by using an index.
Disadvantages:
We have to declare Size of an array in advance. However, we may not know what size
we need at the time of array declaration.
The array is static structure. It means array size is always fixed, so we cannot increase or
decrease memory allocation.
Q.2: Can you declare an array without assigning the size of an array?
Ans.) No we cannot declare an array without assigning size. If we declare an array without
size, it will throw compile time error Example: marks = new int []; //COMPILER ERROR
Ans.) Any new Array is always initialized with a default value as follows
Experiment No. 2
Program to perform Insertion and deletion operation in linked
list.
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
struct node
{
int d;
struct node *link;
};
struct node *root=NULL; int len;
void append(void);
void begin(void);
void after(void);
int length(void);
void display(void);
void del(void);
int main()
{
int c; while(1)
{
printf("\nSingle link list operations: ");
printf("\n1.append");
printf("\n2. Insertion in begin ");
printf("\n3. Insertion in between ");
printf("\n4. Show Length ");
printf("\n5. Display List ");
printf("\n6. Delete elements ");
printf("\n7. Close ");
printf("\nEnter your choice: ");
scanf("%d",&c);
switch(c)
{
case 1: append(); break;
case 4: len=length();
case 7: exit(1);
3rd SEM DATA STRUCTURE & ALGORITHM (LC-DS02) 2023-24
IPS ACADEMY, INSTITUTE OF ENGINEERING AND SCIENCE- INDORE
void append()
{
struct node *temp;
temp=(struct node*)malloc(sizeof(struct node)); printf("\nEnter the data in node "); scanf("%d",&temp-
>d);
temp->link=NULL;
if(root==NULL)
{
root=temp;
}
else
{
struct node *p;
p=root;
while(p->link!=NULL)
{
p= p->link;
}
p->link=temp;
}
}
int length()
{
int count;
struct node *temp; temp=root; while(temp!=NULL)
{
count++; temp=temp->link;
}
return count;
}
void display()
{
struct node *temp; temp=root;
if(temp==NULL)
{
printf("\nEmpty list ");
}
else
{
while(temp!=NULL)
3rd SEM DATA STRUCTURE & ALGORITHM (LC-DS02) 2023-24
IPS ACADEMY, INSTITUTE OF ENGINEERING AND SCIENCE- INDORE
{
printf("%d--->",temp->d); temp=temp->link;
}
printf("NULL");
printf("\n\n\n");
}
}
void begin()
{
struct node *temp;
temp=(struct node*)malloc(sizeof(struct node));
printf("\nEnter the d in node ");
scanf("%d",&temp->d);
temp->link=NULL;
if(root==NULL)
{
root=temp;
}
else
{
temp->link=root; root=temp;
}
void after()
{
struct node *temp, *p; int loc,i=1;
printf("\nEnter Location where element to be inserted: ");
scanf("%d",&loc);
len=length();
if(loc>len)
{
printf("\nInvalid location ");
}
else
{
p=root;
while(i<loc)
{
i++;
p=p->link;
}
3rd SEM DATA STRUCTURE & ALGORITHM (LC-DS02) 2023-24
IPS ACADEMY, INSTITUTE OF ENGINEERING AND SCIENCE- INDORE
void del()
{
struct node *temp; int i=1;
struct node *p; struct node *q; int loc;
printf("\nEnter location which has to delete ");
scanf("%d",&loc);
if(loc>length())
{
printf("\nInvalid input");
}
else
{
if(loc==1)
{
temp=root; root=temp->link; temp->link=NULL; free(temp);
}
else
{
p=root;
while(i<loc-1)
{
i++;
p=p->link;
q=p->link; p->link=q->link;
q->link=NULL;
free(q);
}
}
}
Output
Viva Questions
Ans.) A linked list is a dynamic data structure where each element (called a node) is
made up of two items: the data and a reference (or pointer), which points to the next
node. A linked list is a collection of nodes where each node is connected to the next node
through a pointer.
Ans) Dynamic data structure: A linked list is a dynamic arrangement so it can grow and
shrink at runtime by allocating and deallocating memory. So there is no need to give the
initial size of the linked list.
No memory wastage: In the Linked list, efficient memory utilization can be achieved
since the size of the linked list increase or decrease at run time so there is no memory
wastage and there is no need to pre-allocate the memory.
Implementation: Linear data structures like stack and queues are often easily
implemented using a linked list.
Insertion and Deletion Operations: Insertion and deletion operations are quite easier
in the linked list. There is no need to shift elements after the insertion or deletion of
an element only the address present in the next pointer needs to be updated.
Experiment No. 3
Program to perform Push, Pop & top operations in stack
#include<stdio.h>
#include<conio.h>
#include<process.h>
#define max 5//preprocessor macros
int stack[max],top=-1;
void push(int);
int pop(void);
int Full(void);
int
Empty(void);
void traverse(void);
void peek(void);
void main()
{
clrscr();
int c; int item;
printf("+++++++++++++OPERATIONS ON STACK+++++++++++++++++++++");
while(1)
{
printf("\n1.PUSH \n");
printf("2.POP \n");
printf("3.PEEK \n");
printf("4.TRAVERSE \n");
printf("5.CLOSE\n");
switch(c)
{
case 1: printf("Enter element: ");
scanf("%d",&item);
push(item);
break;
case 2: item=pop();
if(item==0)
printf("\nStack Underflow ");
else
printf("Poped item is %d ",item);
break;
case 3: peek();
break;
case 4: traverse();
break;
3rd SEM DATA STRUCTURE & ALGORITHM (LC-DS02) 2023-24
IPS ACADEMY, INSTITUTE OF ENGINEERING AND SCIENCE- INDORE
case 5: exit(0);
int Full()
{
if(top==max-1)
{
return 1;
}
else
{
return 0;
}
}
int pop()
{
if(Empty())
{
return 0;
}
else
{
return stack[top--];
}
}
int Empty()
{
if(top==-1)
{
return 1;
3rd SEM DATA STRUCTURE & ALGORITHM (LC-DS02) 2023-24
IPS ACADEMY, INSTITUTE OF ENGINEERING AND SCIENCE- INDORE
}
else
{
return 0;
}
}
void peek()
{
if(Empty())
{
printf("\nStack Underflow ");
}
else
{
printf("\nPeek Element is %d \n",stack[top]);
}
}
void traverse()
{
if(Empty())
{
printf("\nStack is Empty ");
}
else
{
int i;
printf("\nStacks Elements are: \n");
for(i=0;i<=top;i++)
{
printf("%d\n",stack[i]);
}
}
}
Output
Viva Questions
Q.1. What is the time complexity of push and pop function using Linked List implementation?
Ans) When we use Linked List to implement stack then time taken for insertion and deletion
is O(1).
Ans) Prefix and Postfix expressions can be evaluated faster than an infix expression. This is
because we don't need to process any brackets or follow operator precedence rule. In postfix
and prefix expressions which ever operator comes before will be evaluated first, irrespective
of its priority.
Experiment No. 4
Program to perform Insertion and Deletion operation in queue.
#include<stdio.h>
#include<conio.h>
#include<process.h>
#define CAPACITY 5
int queue[CAPACITY];
int front=0; int rear=0;
void insert(int);
void remo(void);
void
traverse(void);
void main()
{
int c,item;
while(1)
{
printf("\n1.Insert\n");
printf("2.Delete\n");
printf("3.Traverse\n");
printf("4.Quit\n");
switch(c)
{
case 1 : insert(item);
break;
case 2: remo();break;
case 3: traverse();break;
case 4: exit(0);
default: printf("\nInvalid Input ");
}
}
}
scanf("%d",&ele);
queue[rear]=ele; rear+
+;
}
}
void remo()
{ int i;
if(front==rear)
{
printf("\nQueue is Empty- \n");
}
else
{
printf("\nDeleted item is %d",queue[front]);
for(i=front;i<rear;i++)
{
queue[i]=queue[i+1];
} rear--;
}
}
void traverse()
{ int i;
if(front==rear)
{
printf("\nQueue is Empty \n");
}
else
{
printf("\nQueue Elements are \n");
for(i=front;i<rear;i++)
{
printf("%d\t",queue[i]);
}
printf("\n");
}
}
Output
Viva Questions
Ans) Queue is ordered collection of items in which items can be inserted from rear (back) end
and elements can be deleted from front end. Queue works on FIFO rule.
Ans) Priority Queue is an extension of Queue with following properties. 1. Every item has a
priority associated with it. 2. An element with high priority is dequeued before an element
with low priority. 3. If two elements have the same priority, they are served according to their
order in the queue.
Experiment No. 5
Program to create a Binary Tree.
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
struct node
{
int num;
struct node *left;
struct node *right;
};
typedef struct node node;
node *P=NULL;
node *insert(node *P,intnum);
void search(node *P,intnum);
voidinorder(node *P);
void preorder( node *P);
voidpostorder( node
*P); void main()
{
intc,d;
printf("\tBINARY SEARCH TREE\n");
while(1)
{
switch(c)
{
case 1: printf("\nEnter a no. you want to add to tree to quit enter 0: ");
scanf("%d",&d);
while(d!=0)
{
P=insert(P,d);
scanf("%d\n",&d);
} continue;
continue;
else
if(d< P->num)
{
P->left=insert (P->left,d);
}
else
if(d> P->num)
{
P->right =insert (P->right,d);
}
else
if(d== P->num)
{
puts("\nDuplicate node: Program exited "); exit(0);
}
3rd SEM DATA STRUCTURE & ALGORITHM (LC-DS02) 2023-24
IPS ACADEMY, INSTITUTE OF ENGINEERING AND SCIENCE- INDORE
return(P);
Output
Viva Questions
Ans) Any node in a binary tree or a tree that does not have any children is called a leaf node.
Ans) A binary search tree (BST) is a special type of binary tree in which each internal node
contains a key. For a binary search tree, the rule is: 1. a) A node can have a key that is greater
than all the keys in the node’s left subtree. 2. b) A node can have a key that is smaller than all
the keys in the node’s right subtree.
Experiment No. 6
Program for traversing a graph through BFS and DFS
#include<stdio.h>
#include<conio.h>
#define MAX 20
typedef enum boolean{false,true}
bool; int adj[MAX][MAX];
bool visited[MAX];
int n; /* Denotes number of nodes in the graph */
main()
{
int i,v,choice;
create_graph();
while(1)
{
printf("\n");
printf("1. Adjacency matrix\n");
printf("2. Depth First Search through recursion\n");
printf("3. Breadth First Search\n");
printf("4. Adjacent vertices\
n"); printf("5. Exit\n");
printf("Enter your choice : ");
scanf("%d",&choice);
switch(choice)
{
case 1:
printf("Adjacency Matrix\n");
display();
break;
case 2:
printf("Enter starting node for Depth First Search : ");
scanf("%d",&v);
for(i=1;i<=n;i++)
visited[i]=false;
dfs_rec(v);
break;
case 3:
printf("Enter starting node for Breadth First Search : ");
scanf("%d", &v);
for(i=1;i<=n;i++)
visited[i]=false;
bfs(v);
break;
case 4:
printf("Enter node to find adjacent vertices : ");
scanf("%d", &v);
printf("Adjacent Vertices are : ");
adj_nodes(v);
break;
case 5:
exit(1);
default:
3rd SEM DATA STRUCTURE & ALGORITHM (LC-DS02) 2023-24
IPS ACADEMY, INSTITUTE OF ENGINEERING AND SCIENCE- INDORE
printf("Wrong choice\n");
break;
}/*End of switch*/
}/*End of while*/
}/*End of main()*/
create_graph()
{
int i,max_edges,origin,destin;
printf("Enter number of nodes : ");
scanf("%d",&n);
max_edges=n*(n-1);
for(i=1;i<=max_edges;i++)
{
printf("Enter edge %d( 0 0 to quit ) : ",i);
scanf("%d %d",&origin,&destin);
if((origin==0) && (destin==0))
break;
if( origin > n || destin > n || origin<=0 || destin<=0)
{
printf("Invalid edge!\
n"); i--;
}
else
{
adj[origin][destin]=1;
}
}/*End of for*/
}/*End of create_graph()*/
display()
{
int i,j;
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
printf("%4d",adj[i][j]);
printf("\n");
}
}/*End of display()*/
dfs_rec(int v)
{
int i;
visited[v]=true;
printf("%d ",v);
for(i=1;i<=n;i++)
if(adj[v][i]==1 && visited[i]==false)
dfs_rec(i);
}/*End of dfs_rec()*/
bfs(int v)
{
int i,front,rear;
3rd SEM DATA STRUCTURE & ALGORITHM (LC-DS02) 2023-24
IPS ACADEMY, INSTITUTE OF ENGINEERING AND SCIENCE- INDORE
int que[20];
front=rear= -1;
printf("%d
",v);
visited[v]=true;
rear++; front+
+; que[rear]=v;
while(front<=rear)
{
v=que[front]; /* delete from queue */
front++;
for(i=1;i<=n;i++)
{
/* Check for adjacent unvisited nodes
*/ if( adj[v][i]==1 &&
visited[i]==false) int i;
for(i=1;i<=n;i++)
if(adj[v][i]==1)
printf("%d ",i);
printf("\n");
{
printf("%d ",i);
visited[i]=true;
rear++;
que[rear]=i;
}
}
}/*End of while*/
}/*End of bfs()*/
adj_nodes(int v)
{
}/*End of adj_nodes()*/
Output
Enter number of nodes : 8
Enter edge 1( 0 0 to quit ) : 1 2
Enter edge 2( 0 0 to quit ) : 1 3
Enter edge 3( 0 0 to quit ) : 2 4
Enter edge 4( 0 0 to quit ) : 2 5
Enter edge 5( 0 0 to quit ) : 3 6
Enter edge 6( 0 0 to quit ) : 3 7
Enter edge 7( 0 0 to quit ) : 4 8
Enter edge 8( 0 0 to quit ) : 5 8
Enter edge 9( 0 0 to quit ) : 6 8
Enter edge 10( 0 0 to quit ) : 7 8
Enter edge 11( 0 0 to quit ) : 0 0
1. Adjacency matrix
2. Depth First Search through recursion
3. Breadth First Search
4. Adjacent vertices
5. Exit
Enter your choice : 2
Enter starting node for Depth First Search : 1
12485367
1. Adjacency matrix
2. Depth First Search through recursion
3. Breadth First Search
4. Adjacent vertices
5. Exit
Enter your choice : 3
Enter starting node for Breadth First Search : 1
12345678
1. Adjacency matrix
2. Depth First Search through recursion
3. Breadth First Search
4. Adjacent vertices
5. Exit
Enter your choice : 1
Adjacency Matrix
01100000
00011000
00000110
00000001
00000001
00000001
00000001
00000000
1. Adjacency matrix
2. Depth First Search through recursion
3. Breadth First Search
4. Adjacent vertices
5. Exit
Enter your choice : 4
3rd SEM DATA STRUCTURE & ALGORITHM (LC-DS02) 2023-24
IPS ACADEMY, INSTITUTE OF ENGINEERING AND SCIENCE- INDORE
Viva Questions
Ans) A graph consists of vertices and edges. Vertices: Vertices are similar to nodes. Vertices
usually have a label for identification in addition to other properties. Examples of vertices are
cities in a map and pins in a circuit. Edges: An edge connects two vertices. Examples of
edges are roadways that connect cities in a map, and traces that connect pins in a circuit
diagram.
Ans) In a connected graph there is at-least one path from every vertex to every other vertex.
In a non-connected graph every vertex may not be connected to every other vertex.
Experiment No. 7
Program to implement Insertion Sort.
#include<stdio.h>
#include<conio.h>
int main()
{
int a[100],n,k,i,j,temp;
for(k=1;k<=n-1;k++)
{
temp=a[k];
j=k-1;
while((temp<a[j])&&(j>=0))
{
a[j+1]=a[j];
j=j-1;
}
a[j+1]=temp;
}
Output
Viva Questions
Q.1: Which sorting algorithm is best suited if the elements are already sorted?
Ans) Insertion-sort is best sited if elements are already sorted. The best case running time of
the insertion sort is O(n). The best case occurs when the input array is already sorted. As the
elements are already sorted, only one comparison is made on each pass, so that the time
required is O(n).
Q.2: The worst case time complexity of insertion sort is O(n 2 ). What will be the worst
case time complexity of insertion sort if the correct position for inserting element is
calculated using binary search?
Ans) The use of binary search reduces the time of finding the correct position from O(n) to
O(logn). But the worst case of insertion sort remains O(n2 ) because of the series of swapping
operations required for each insertion.
Experiment No. 8
Program to implement Quick Sort.
#include<conio.h>
#include<stdio.h>
int main()
{
int data[100], i, n;
printf("Give numbers to be input : "); //asking for number to be
input scanf("%d",&n);
printf("Enter %d numbers : \n", n);
b[m++]=a[q];
count++;
}
else
b[n--]=a[q];
b[i]=b[i+count];
b[i+count]=p;
*l=i+count;
Output
Viva Questions
Q.1: What is the worst case time complexity of the Quick sort?
Ans) The worst case running time for Quick sort is O(n 2 ). In Quick sort, the worst case
behaviour occurs when the partitioning routine produces two sub- arrays one with n – 1
element and other with 0 elements.
Ans) In stable sorting algorithm the records with equal keys appear in the same order in the
sorted sequence as they appear in the input unsorted sequence. Quick sort does not preserve
the relative order of equal sort items. Therefore, Quick sort is not a stable sort.
Experiment No. 9
Program to solve 8 queen’s problem.
#include<stdio.h>
int q[50],n;
void printQueens();
int isConsistent(int);
void enumerate(int);
int main()
{
printf("Enter the size of board:");
scanf("%d",&n);
if(n==2||n==3)
{
printf("Can't play the game..");
return 0;
}
enumerate(0);
return 0;
}
void enumerate(int c)
{
int i;
if (c == n)
printQueens();
else
{
for(i = 0; i < n; i++)
{
q1 = i;
if(isConsistent(c))
enumerate(c+1);
}
}
}
void printQueens()
{
static int count=1;
int i,j;
printf("Combination %d\n",count++);
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
if(q[i]==j)
printf("Q ");
else
printf("* ");
printf("\n");
}
printf("\n\n");
}
int isConsistent(int c)
{
int i;
for (i = 0; i < c; i++)
{
if (q[i] == q1)
return 0; // same column
if ((q[i] - q1) == (c - i))
return 0; // same major diagonal
if ((q1 - q[i]) == (c - i))
return 0; // same minor diagonal
}
return 1;
}
Output
Execution:
Enter the size of board:1
Combination 1
Q
Execution:
Enter the size of board:3
Can’t play the game..
Execution:
Enter the size of board:4
Combination 1
*Q**
***Q
Q***
**Q*
Combination 2
**Q*
Q***
***Q
*Q**
Execution:
Enter the size of board: 8
————
————
Combination 91
*******Q
**Q*****
Q*******
*****Q**
*Q******
****Q***
******Q*
***Q****
Combination 92
*******Q
***Q****
Q*******
**Q*****
*****Q**
*Q******
******Q*
****Q***
Viva Questions
Ans) Queens attack each other in three directions- vertical, horizontal and diagonal.
Ans) For an 8-queen problem, there are 92 possible combinations of optimal solutions.
Experiment No. 10
Program to implement Traveling salesman problem.
#include<stdio.h>
int ary[10][10],completed[10],n,cost=0;
void takeInput()
{
int i,j;
completed[i]=0;
}
completed[city]=1;
printf("%d--->",city+1);
ncity=least(city);
if(ncity==999)
{
ncity=0;
printf("%d",ncity+1);
cost+=ary[city][ncity];
return;
}
mincost(ncity);
}
int least(int c)
{
int i,nc=999;
int min=999,kmin;
if(min!=999)
cost+=kmin;
return nc;
}
int main()
{
takeInput();
return 0;
}
Output
Minimum cost is 7
Viva Questions
Ans) To solve the TSP using the Brute-Force approach, we must calculate the total number of
routes and then draw and list all the possible routes. Calculate the distance of each route and
then choose the shortest one—this is the optimal solution. This method breaks a problem to be
solved into several sub-problems.
Ans) The traveling salesman problem (TSP) is an algorithmic problem tasked with finding the
shortest route between a set of points and locations that must be visited. In the problem
statement, the points are the cities a salesperson might visit.
#include<stdio.h>
#include<conio.h>
main()
{
int a[50][50],r,c,m,n;
printf("Enter the no. of rows and column in a matrix- ");
scanf("%d %d",&m,&n);
Output
Viva Questions
Ans) The transpose of a matrix is the one whose rows are columns of the original matrix, i.e.
if A and B are two matrices such that the rows of the matrix B are the columns of the matrix
A then Matrix B is said to be the transpose of Matrix A.
Ans) The transpose of a matrix is obtained by changing the rows into columns and columns
into rows for a given matrix. Transpose of a matrix is especially useful in applications where
inverse and adjoint of matrices are to be obtained.
IPS CADEMY
16 Colleges, 71 Courses, 51 Acre Campus
ISO 9001: 2008 Certified
Knowledge Village Rajendra Nagar A.B.Road Indore 452012(M.P.) India
Ph: 0731-4014601-604 Mo: 07746000161
E Mail: [email protected]
Website: ies.ipsacademy.org & www.ipsacademy.org