Assignment - 2
Assignment - 2
1. Introduction
2. Abstract
3. Purpose
5. Project selection
Abstract:
Upon registration, patrons gain the ability to browse the library's catalog, check the
availability of books, and request loans for specific titles. The system empowers
library administrators to oversee and control the entire library ecosystem through a
centralized online interface. Essential features such as book borrowing, staff
management, and other library services are integrated into this project.
Administrators can update the system with information about available books and
manage staff efficiently. Patrons, on the other hand, can explore the library's
collection, reserve books, and access other library services remotely. The LMS
enhances the overall management of library operations, providing a user-friendly
platform for patrons to interact with the library's resources from the comfort of
their homes.
Purpose:
The Library Management System (LMS) Software Requirement Specification
(SRS) serves as a comprehensive document outlining the specific needs and
functionalities required for the development of the LMS. This document is pivotal
in providing a detailed understanding of the expected features and operations of the
proposed system. The primary goal is to ensure that the subsequent phases of the
project, including system design, development, and testing, align with the
envisioned requirements.
By offering a clear and concise overview of the system's specifications, the SRS
lays the foundation for the entire project. It acts as a guide for the development
team, enabling them to comprehend the intricacies of the LMS and build software
that meets the end users' expectations. The SRS is a crucial tool for collaboration
between the development team and the stakeholders involved in the library,
ensuring a shared understanding of the system's requirements.
The Library Management System SRS serves a dual purpose, benefiting both the
development team and the end users. For the development team, it provides a
blueprint for building the LMS, guiding them through the various stages of
development. Simultaneously, the end users, which include library staff and
patrons, can utilize the SRS as a benchmark to assess whether the proposed system
aligns with their specific needs and expectations.
The proposed Library Management System (LMS) aims to revolutionize the day-
to-day operations of the library, providing an automated solution for efficient
management and accessibility of library resources. The system will cater to the
needs of library patrons and staff, streamlining various services and enhancing
overall functionality.
Key Components:
Catalog Management:
The LMS will include a robust catalog management system to organize and
categorize the library's collection, making it easy for users to browse and locate
books.
Reservation System:
User Management:
Access Control:
The LMS will implement access control features to define different user roles,
including administrators, librarians, and patrons. Each role will have specific
permissions, ensuring secure and restricted access to sensitive information
stocking.
Ease of Use:
The system will be designed with a user-friendly interface, ensuring ease of use for
both library staff and patrons. Intuitive navigation and clear functionalities will
contribute to a positive user experience.
Error Recovery:
Project Selection:
The Library Management System (LMS) project has been selected in response to
the critical need for a centralized and technologically advanced solution in the
realm of library services. The challenges faced by libraries in efficiently managing
resources, facilitating user interactions, and adapting to the evolving demands of
modern users have prompted the selection of this project. The LMS project
addresses several key aspects of library management, encompassing catalog
organization, user interactions, inventory control, and overall operational
efficiency.
Key Considerations:
Resource Organization:
User Experience:
Resource Utilization:
Libraries, like hotels, are repositories of valuable resources. The LMS project aims
to optimize resource utilization by implementing efficient cataloging systems,
enabling effective inventory management, and enhancing the accessibility of
resources for patrons.
Operational Efficiency:
Stacks:
To implement the stack, it is required to maintain the pointer to the top of the
stack, which is the last element to be inserted because we can access the
elements only on the top of the stack.
This strategy states that the element that is inserted last will come out
first. You can take a pile of plates kept on top of each other as a real-
life example. The plate which we put last is on the top and since we
remove the plate that is at the top, we can say that the plate that was
put last comes out first.
Push:
Adds an item to the stack. If the stack is full, then it is said to be an Overflow
condition.
begin
if stack is full
return
endif
else
increment top
end else
end procedure
Pop:
Removes an item from the stack. The items are popped in the reversed order in
which they are pushed. If the stack is empty, then it is said to be
an Underflow condition.
begin
if stack is empty
return
endif
else
decrement top
return value
end else
end procedure
Top:
Returns the top element of the stack.
Algorithm for Top:
begin
return stack[top]
end procedure
isEmpty:
Returns true if the stack is empty, else false.
begin
if top < 1
return true
else
return false
end procedure
Complexity Analysis:
• Time Complexity
Operations Complexity
push() O(1)
pop() O(1)
isEmpty() O(1)
size() O(1)
Types of Stacks:
• Fixed Size Stack: As the name suggests, a fixed size stack has a fixed size and
cannot grow or shrink dynamically. If the stack is full and an attempt is made to
add an element to it, an overflow error occurs. If the stack is empty and an
attempt is made to remove an element from it, an underflow error occurs.
• Dynamic Size Stack: A dynamic size stack can grow or shrink dynamically.
When the stack is full, it automatically increases its size to accommodate the
new element, and when the stack is empty, it decreases its size. This type of
stack is implemented using a linked list, as it allows for easy resizing of the
stack.
In addition to these two main types, there are several other variations of Stacks,
including:
1. Infix to Postfix Stack: This type of stack is used to convert infix expressions
to postfix expressions.
2. Expression Evaluation Stack: This type of stack is used to evaluate postfix
expressions.
3. Recursion Stack: This type of stack is used to keep track of function calls in a
computer program and to return control to the correct function when a function
returns.
4. Memory Management Stack: This type of stack is used to store the values of
the program counter and the values of the registers in a computer program,
allowing the program to return to the previous state when a function returns.
5. Balanced Parenthesis Stack: This type of stack is used to check the balance of
parentheses in an expression.
6. Undo-Redo Stack: This type of stack is used in computer programs to allow
• Using array
• Using linked list
#include <iostream>
class Stack {
int top;
public:
int a[MAX]; // Maximum size of Stack
bool Stack::push(int x)
{
if (top >= (MAX - 1)) {
cout << "Stack Overflow";
return false;
}
else {
a[++top] = x;
cout << x << " pushed into stack\n";
return true;
}
}
int Stack::pop()
{
if (top < 0) {
cout << "Stack Underflow";
return 0;
}
else {
int x = a[top--];
return x;
}
}
int Stack::peek()
{
if (top < 0) {
cout << "Stack is Empty";
return 0;
}
else {
int x = a[top];
return x;
}
}
bool Stack::isEmpty()
{
return (top < 0);
}
return 0;
}
Advantages of array implementation:
• Easy to implement.
• Memory is saved as pointers are not involved.
Disadvantages of array implementation:
• It is not dynamic i.e., it doesn’t grow and shrink depending on needs at
runtime. [But in case of dynamic sized arrays like vector in C++, list in Python,
ArrayList in Java, stacks can grow and shrink with array implementation as well].
• The total size of the stack must be defined beforehand.
Implementing Stack using Linked List:
return popped;
}
// Driver code
int main()
{
StackNode* root = NULL;
push(&root, 10);
push(&root, 20);
push(&root, 30);
return 0;
}
Advantages of Linked List implementation:
• The linked list implementation of a stack can grow and shrink according to the
needs at runtime.
• It is used in many virtual machines like JVM.
Disadvantages of Linked List implementation:
• Requires extra memory due to the involvement of pointers.
• Random accessing is not possible in stack.
•
Stack is a simple linear data structure used for storing data. Stack follows
the LIFO(Last In First Out) strategy that states that the element that is inserted last
will come out first. You can take a pile of plates kept on top of each other as a real-
life example. The plate which we put last is on the top and since we remove the
plate that is at the top, we can say that the plate that was put last comes out first. It
can be implemented through an array or linked lists. Some of its main operations
are: push(), pop(), top(), isEmpty(), size(), etc. In order to make manipulations
in a stack, there are certain operations provided to us. When we want to insert an
element into the stack the operation is known as the push operation whereas when
we want to remove an element from the stack the operation is known as the pop
operation. If we try to pop from an empty stack then it is known as underflow and
if we try to push an element in a stack that is already full, then it is known as
overflow.
• void push(int data): When this operation is performed, an element is inserted into
the stack.
• int pop(): When this operation is performed, an element is removed from the
top of the stack and is returned.
Auxiliary Stack Operations:
• int top(): This operation will return the last inserted element that is at the top
without removing it.
• int size(): This operation will return the size of the stack i.e. the total number of
elements present in the stack.
• int isEmpty(): This operation indicates whether the stack is empty or not.
• int isFull(): This operation indicates whether the stack is full or not.
Types of Stacks:
• Register Stack: This type of stack is also a memory element present in the
memory unit and can handle a small amount of data only. The height of the
register stack is always limited as the size of the register stack is very small
compared to the memory.
• Memory Stack: This type of stack can handle a large amount of memory data.
The height of the memory stack is flexible as it occupies a large amount of
memory data.
What is meant by Top of the Stack?
• When a new element is added to the stack, it is placed on top of the existing
elements. Similarly, when an element is removed from the stack, the topmost
element is removed first. The top of the stack is always the element that is
currently accessible for viewing or manipulation.
• The pointer through which the elements are accessed, inserted, and deleted in the
stack is called the top of the stack. It is the pointer to the topmost element of the
stack.
STACK:
• CD/DVD stand.
• Stack of books in a book shop.
• Call center systems.
• Undo and Redo mechanism in text editors.
• The history of a web browser is stored in the form of a stack.
• Call logs, E-mails, and Google photos in any gallery are also stored in form of a
stack.
• YouTube downloads and Notifications are also shown in LIFO format(the latest
appears first ).
• Allocation of memory by an operating system while executing a process.
Advantages of Stack:
• Limited capacity: Stack data structure has a limited capacity as it can only hold
a fixed number of elements. If the stack becomes full, adding new elements may
result in stack overflow, leading to the loss of data.
• No random access: Stack data structure does not allow for random access to its
elements, and it only allows for adding and removing elements from the top of
the stack. To access an element in the middle of the stack, all the elements above
it must be removed.
• Memory management: Stack data structure uses a contiguous block of memory,
which can result in memory fragmentation if elements are added and removed
frequently.
• Not suitable for certain applications: Stack data structure is not suitable for
applications that require accessing elements in the middle of the stack, like
searching or sorting algorithms.
• Stack overflow and underflow: Stack data structure can result in stack overflow
if too many elements are pushed onto the stack, and it can result in stack
underflow if too many elements are popped from the stack.
• Recursive function calls limitations: While stack data structure supports
recursive function calls, too many recursive function calls can lead to stack
overflow, resulting in the termination of the program.
2. Queue:
A queue is a linear data structure that is open at both ends and the
operations are performed in First In First Out (FIFO) order.
We define a queue to be a list in which all additions to the list are
made at one end, and all deletions from the list are made at the other
end. The element which is first pushed into the order, the delete
operation is first performed on that.
Characteristics of Queue:
• Queue can handle multiple data.
• We can access both ends.
• They are fast and flexible.
Queue Representation:
1. Array Representation of Queue:
Like stacks, Queues can also be represented in an array: In this representation, the
Queue is implemented using the array. Variables used in this case are
• Linked-lists,
• Pointers, and
• Structures.
Types of Queue:
There are different types of queues:
1. Input Restricted Queue: This is a simple queue. In this type of queue, the
input can be taken from only one end but deletion can be done from any of the
ends.
2. Output Restricted Queue: This is also a simple queue. In this type of queue,
the input can be taken from both ends but deletion can be done from only one
end.
3. Circular Queue: This is a special type of queue where the last position is
connected back to the first position. Here also the operations are performed in
FIFO order. To know more refer this.
4. Double-Ended Queue (Dequeue): In a double-ended queue the insertion and
deletion operations, both can be performed from both ends. To know more
refer this.
5. Priority Queue: A priority queue is a special queue where the elements are
accessed based on the priority assigned to them. To know more refer this.
To learn more about different types of queues, read the article on “Types of
Queues“.
3. Peek() or front()- Acquires the data element available at the front node of the
1. Enqueue():
Enqueue() operation in Queue adds (or stores) an element to the end of the
queue.
The following steps should be taken to enqueue (insert) data into a queue:
2. Dequeue():
Removes (or access) the first element from the queue.
The following steps are taken to perform the dequeue operation:
Implementation of dequeue:
3. front():
This operation returns the element at the front end without removing it.
4. rear():
This operation returns the element at the rear end without removing it.
5. isEmpty():
This operation returns a boolean value that indicates whether the queue is empty
or not.
6. isFull():
This operation returns a boolean value that indicates whether the queue is full or
not.
Implementation of Queue:
Queue can be implemented using following data structures:
Applications of Queue:
Application of queue is common. In a computer system, there may be queues of
tasks waiting for the printer, for access to disk storage, or even in a time-sharing
system, for use of the CPU. Within a single program, there may be multiple
requests to be kept in a queue, or one task may create other tasks, which must be
done in turn by keeping them in a queue.
1. Single-linked list
1. Singly-linked list
Traversal of items can be done in the forward direction only due to the linking of
every node to its next node.
Commonly used operations on Singly Linked List:
• Insertion: The insertion operation can be performed in three ways. They are as
follows…
• Inserting At the Beginning of the list
• Inserting At End of the list
• Inserting At Specific location in the list
• Deletion: The deletion operation can be performed in three ways. They are as
follows…
• Deleting from the Beginning of the list
• Deleting from the End of the list
• Deleting a Specific Node
• Search: It is a process of determining and retrieving a specific node either from
the front, the end or anywhere in the list.
• Display: This process displays the elements of a Single-linked list.
// A Single linked list node
class Node {
public:
int data;
Node* next;
};
• Linear data structures such as stack, queue, and non-linear data structures such
as hash maps, and graphs can be implemented using linked lists.
• Dynamic memory allocation: We use a linked list of free blocks.
• Implementation of graphs: Adjacency list representation of graphs is the most
popular in that it uses linked lists to store adjacent vertices.
• In web browsers and editors, doubly linked lists can be used to build a forwards
and backward navigation button.
• A circular doubly linked list can also be used for implementing data structures
like Fibonacci heaps.
Applications of Linked Lists in real world:
• The list of songs in the music player is linked to the previous and next songs.
• In a web browser, previous and next web page URLs are linked through the
previous and next buttons.
• In the image viewer, the previous and next images are linked with the help of
the previous and next buttons.
• Switching between two applications is carried out by using “alt+tab” in
windows and “cmd+tab” in mac book. It requires the functionality of a circular
linked list.
• In mobile phones, we save the contacts of people. The newly entered contact
details will be placed at the correct alphabetical order.
• This can be achieved by a linked list to set contact at the correct alphabetical
position.
• The modifications that we made in the documents are actually created as nodes
in doubly linked list. We can simply use the undo option by pressing Ctrl+Z to
modify the contents. It is done by the functionality of a linked list.
output operations
class Book {
private:
book
public:
// Here we will use Constructor to initialize the
Author(Author), Available(true) {}
of the book
return Title;
the book
return Available;
borrowing a book
void borrowBook() {
if (Available) {
Available = false;
successfully.\n";
} else {
cout << "Sorry, the book \"" << Title << "\"
is not available.\n";
void returnBook() {
Available = true;
successfully.\n";
}
};
class Member {
private:
public:
name(name), memberId(memberId) {}
// Getter method to retrieve the name of the
member
return name;
ID of the member
return memberId;
};
// Class representing a Library
class Library {
private:
library
public:
bookList.push_back(book);
members.push_back(member);
}
// Method to display the list of books in the
library
}
// Method to display the list of members in the
library
book by a member
void borrowBook(int memberId, const string&
bookTitle) {
if (book.getTitle() == bookTitle) {
if (member.getMemberId() ==
memberId) {
book.borrowBook();
borrowedBooks.push(book);
return;
found.\n";
library
if (book.getTitle() == bookTitle) {
book.returnBook();
returnedBooks.push(book);
return;
found.\n";
books
while (!tempStack.empty()) {
cout << "Title: " <<
tempStack.pop();
while (!tempQueue.empty()) {
cout << "Title: " <<
tempQueue.pop();
};
void printMenu() {
functins
int main() {
the library
library.addBook(Book("The Reluctant
Daniyal Mueenuddin"));
Tehmina Durrani"));
library.addBook(Book("To Kill a Mockingbird",
"Harper Lee"));
library.addBook(Book("Kartography", "Kamila
Shamsie"));
library.addBook(Book("The Crow
Eaters","Bapsi Sidhwa"));
"Harper Lee"));
library.addBook(Book("1984", "George
Orwell"));
library.addMember(Member("Emily Johnson",
3));
library.addMember(Member("Sarah
Thompson", 5));
library.addMember(Member("Ahmad khan",
6));
library.addMember(Member("Alexander jone",
9));
library.addMember(Member("Ayesha memon",
10));
library.addMember(Member("Daniel mitchell",
11));
library.addMember(Member("tayaba sadd",
14));
library.addMember(Member("hira hocane",
15));
int choice;
do {
printMenu(); // we will display menu options
switch (choice) {
case 1: {
cin.ignore();
getline(cin, title);
getline(cin, author);
library.addBook(Book(title, author)); //
break;
case 2: {
string name;
int memberId;
cin.ignore();
getline(cin, name);
break;
case 3:
break;
case 4:
library.displayMembers(); // this
library
break;
case 5: {
int memberId;
string bookTitle;
cin.ignore();
getline(cin, bookTitle);
library.borrowBook(memberId,
break;
case 6: {
string bookTitle;
cout << "Enter book title: ";
cin.ignore();
getline(cin, bookTitle);
library.returnBook(bookTitle); // This
break;
case 7:
library.displayBorrowedBooks();
break;
case 8:
library.displayReturnedBooks(); // here
case 9:
break;
library.addBook(Book("New Book
break;
default:
invalid choices
}
return 0;
1. Classes and Object-Oriented Programming (OOP):
Usage: The code is organized using three classes: Book, Member, and Library.
2. Data Structures:
Vector (std::vector):
List (std::list):
Explanation: Linked lists are utilized to allow efficient addition and removal of
books, supporting dynamic updates without the need for extensive memory
reallocation.
Stack (std::stack):
Last In, First Out (LIFO) principle, reflecting the borrowing and returning
sequence.
Queue (std::queue):
3. Linked Lists:
Explanation: Linked lists facilitate dynamic updates to the book list, ensuring
4. Search Algorithms:
methods.
member based on the provided title or ID, enabling borrowing and returning
functionalities.
Usage: Memory is dynamically allocated for storing objects like books and
6. Input/Output Operations:
7. Error Handling:
Usage: A default case in the switch statement handles invalid user choices.
Summary:
of various DSA concepts, including vector, list, stack, queue, linked list, dynamic