PROJECT ON
Library Management System
Submitted by: Anish Kumar Mohanta
Class: XII A
Roll No:
                      CERTIFICATE
              CLASS: XII-A                  YEAR: 2020-2021
This is to certify that the Investigatory Project is successfully completed by
Anish Kumar Mohanta of Class: XII, Division: A, Roll no.: ……………... for
the academic year 2020-2021 in the School Computer lab.
DATE:
Internal Examiner:
Name:
ROLL NO:
                     Acknowledgement
In the accomplishment of this project successfully, many People have best owned upon me their
blessings and the heart pledged support. This time I am utilizing to thank all the people who have
been concerned with this project.
Primarily I would thank God for being able to complete
This project with success. Then I would like to thank Mr. Siddhartha Ratha, Principal of Delhi Public
School, Rourkela.
And our Computer Science teacher Mrs. Smitha R Athreya
Whose valuable guidance has been the ones that helped me patch this project and make it full proof
success. Their suggestion and instructions have served as the major contributor towards the
completion of the project.
Then I would like to thank my parents and friends who have helped me with their valuable
suggestions. Their guidance has been very helpful in various phases of completion of project.
Last but not the least I would like to thank my classmates who have helped me a lot.
                                        INDEX
  I. Brief Overview of Project
  II. Need for Computerization
 III. Available Features
 IV. System Design and Project Description
 V. Software Requirements and Testing
 VI. Advantages and Limitations of the Project
VII. Flowchart
VIII. Source Code of the Project
 IX. Possible Future Enhancements
 X. Output Screen
 XI. Bibliography
      Brief Overview of the Project
The main objective of this python project is to assist libraries in
managing details of their members, borrowed books, member
dues and several other details. The system revolves around the
day-to-day activities of a librarian of any large library where
members are allowed to borrow books.
The aim of this project is hence to reduce the manual work done
by a librarian and automate most of the processes. This is done
with the help of a database connected to a python CLI
(command line interface) to enter data and persistently store
them. Several features like the ability to add and remove books ,
issuing and registering returns of books , maintaining details
regarding member dues and late fines etc.
It is also ensured that only the administrator (e.g a librarian) can
access this interface. To do this a password system has been
implemented into the system
      Need for Computerization
Several libraries maintain a handwritten ledger for accounting
and management of their day-to-day activities. This is error
prone, redundant and has the risk of data loss. Moreover, it is
inefficient as the administrator has the overhead of maintaining
and writing the ledger which is a time-consuming process.
To prevent this, an automated computerized system linked with
an RDBMS can improve the efficiency of the library
administration several fold.
Advantages of using an RDBMS over Manual Ledgers:
        ● Removing Redundancy: Using a database over
           manual ledgers ensures that duplicate entries are not
           inserted.
        ● Shared Data: Data need not be updated across
           several sections manually; this implies changing an
           entry at one place also changes the same data in
           other entries.
         ● Data Integrity: Data integrity means that the data is
            accurate and consistent across the database. Several
            rules and checks can be employed during data entry
            to prevent entering incorrect information.
         ● Backup and Recovery: Database Management
            System automatically takes care of backup and
            recovery. The users don't need to backup data
            periodically because this is taken care of by the
            DBMS.
Hence with the above advantages, it can be clearly said that
investing on a computerized system for library management is a
good administrative decision.
Apart from the typical benefits that come with any computerized
version of a manual management process, there are several
other side benefits as well. For example , a computerized system
is environmentally friendly and saves an organization several
rolls of paper.
                Available Features
The library management system described in this project is
capable of the following tasks:
        ● Login System for Admin Access: - The interface
           only allows an authenticated user (i.e. an admin) to
           access the management CLI (command Line
           Interface) portal. The login credentials are securely
           stored in a separate Table in a MySQL database.
        ● Persistent Storage with MySQL :- The software
           efficiently stores entered details across several tables
           which are manipulated with the help of Python
           MySQL.connector module. This is a better design
           decision as a database is more reliable than a file-
           based storage option like csv or json files.
        ● Books Information Management: The software
           allows the admin to add new books to the system as
           they are added to the library as well as remove them.
  The database uses the International Standard Book
  Number (ISBN) as the primary identifier for each
  book.
● Member Management: Members of the library (users
  who can borrow books from the library) can be added
  by the admin. The librarian can also check which
  books are due on a particular date (set to the current
  date by default), they can also check the list of all
  books that are to be returned and the expected return
  date.
● Borrowing and Returns Tracking:- The software
  allows easy tracking of the books borrowed and when
  they are to be returned, when a book is borrowed , it is
  automatically marked as “unavailable” to prevent it
  being issued to another member. Similarly , the
  librarian can register the return date so as to account
  for any differences between the actual date the book
         was returned and when it was expected to be
         returned.
      ● Late Fines System:- Since borrowing and returns are
         being tracked, members can be charged a “late fine”
         based on the number of days they defaulted from the
         expected return date. This is automatically calculated
         by the software and is stored appropriately in the
         database.
          System Design and Project
                 Description
There are 2 main components in the Library Management
System. A database (MySQL) and a Python Console. These 2
components are connected through an sql connector
(mysql.connector here). The python acts an interface for the
user to enter data which is passed to the database through the
mysql connector.
Database Structure
There are 4 tables in our database. They are named as “books”,
“admins”, “issues” and “members”. The books table contains
the names and details of all books in the library, members
table contains information regarding the members , issues
about the borrows and issues and admins about the details of
the admin members.
The structure of columns of each table is described below:
Books
     Field                                               type
     book_id                                             CHAR(13)
     title                                               VARCHAR(255)
     authors                                             VARCHAR(500)
     categories                                          VARCHAR(255)
     available                                           tinyint(1)
     Here book_id is the ISBN number of the book and categories is the genre the book belongs to
Members
     Field            type
     member_id        CHAR(7)
     member_name      VARCHAR(500)
     issued_books     VARCHAR(490)
     member_dues      int
Issues
     Field            type
     issue_id         CHAR(7)
     book_id          CHAR(13)
     member_id        CHAR(7)
     issue_date       date
     return_date      date
     is_returned      tinyint(1)
Admins
     Field            type
     admin_username   CHAR(7)
     admin_password   CHAR(13)
Source Structure
For better organization and readability , source code for the
application is distributed across 3 modules namely,
“librarian_interface.py”, “main.py” and “utils.py”.The “main.py”
contains code for the CLI interface. All functions used for each
feature are declared in the “librarian_interface.py” module and
some utility functions are declared in the “utis.py” module.
Execution Method
The “main.py” contains a menu driven program with the 2 following
topmost options:
            1. Login as Librarian (the admin access user)
            2. Create a new member
The first option allows the admin to enter their username and
password. Actual credentials are stored in the “admins” table which
are checked for equality with the ones entered. The second option
allows the user to enter a member id and their name to create a new
user.
Options Available:
Under the admin menu 8 options are available. They are:
       1. Add a book to library
       2. Remove a book from library
       3. Issue a book to member
       4. Issue a return from member
       5. See List of books due today
       6. See List of all books due
       7. Clear Late fines for a member
       8. Exit
All the options are in an if-elif-else loop. When an option is triggered a
handler function is executed which handles all the input and checks
for them. If the input details are correct , then a mysql.connector
query is
executed for each of the tasks. Therefore the python interface acts as
a user-friendly and error-checking layer for the system. The following
diagram explains the execution properly.
                     User                    Option
                    enters                   Handler
                    option
                               mysql.conn
                               ector
                             Mysql Query
                             Execution
This structure of using a handler function defined in another
file instead of directly writing all the program logic in one
“main.py” file allows better software testing as discussed in
the next section.
This pattern of organizing code into handler functions is part of
a popular design pattern in software applications and is known
as the “Model View Controller” or MVC design pattern. In this
design pattern the presentation layer called the “View” (the cli
interface in this case), the functionality layer called the
“Controller” (handler functions in this case) and the data
manipulation layer (mysql.connector in this case) are all
decoupled from each other.
          Software Requirements and
                   Testing
Software Requirements
   ● Windows 7/8/10 / MacOS / Linux or any other compatible
       operating system
   ● A working installation of Python 3.8.1
   ● A working installation of MySQL 5.0.4 or later
   ● Module mysql-connector installed
   Likewise , compatible hardware associated must be used to
   prevent any compatibility issues.
Testing
Testing is vital for any software application , it ensures the
features are working correctly and in the expected manner. To
test the project properly, each feature is separated into an
individual function. This is called “program decomposition”.
Decomposing a software into several smaller sections allows
easier testing of each feature. This also has several other
benefits like:
Maintainability: Separate functions are easier to edit,change
and review compared to one homogenous codebase.
Reusability: When frequently occurring components of a
program are separated into individual functions , they can be
easily called and reused several times. This is what the
functions in the “utils.py” file do.
Understandability: Separating the functions into separate
chunks can enhance the ability to review the code. Size of
“main.py” is comparatively smaller as compared to
“librarian_interface.py” because all of the functions are defined
in the latter , this allows easier understanding for main.py file.
           Advantages and Limitations of
                   the Project
Advantages
●      Solves a practical real world problem of library management of a
library.
●      Automates many redundant tasks, helps organize and
computerize the information for an organization.
●      Digitizes processes and information which makes it less prone to
data-loss like in manual handwritten systems.
●      Increases data integrity, reduces data redundancy and improves
backup and recovery of lost data
●      Administrative tasks are a lot easier
Limitations
●     Not General Purpose , is customly designed based on several
assumptions and features which may not be suitable for particular
organizations.
●     Features may or may not be adequate for each and every library
●     Is CLI based and not Graphical
Flowchart
    Source code of the program
main.py
import librarian_interface
# welcome text
welcome_text = "\nWelcome to DPS Library Console Portal"
print(welcome_text)
# options text
print(
"""
Select Action
1. Login as Librarian
2. Create a new library member
"""
choice = int(input("Enter your choice (1/2): "))
# handle Librarian Menu
if choice == 1:
    # handle login
    login = False
    while login == False:
      login = librarian_interface.admin_login()
      if login == True:
         print("\n Logged in Succesfully\n")
         break
    else:
      print("Failed to Login (username or password invalid). Try again.\n")
# list options
print(
"""
What do you want to do?
1. Add a book to library
2. Remove a book from library
3. Issue a book to member
4. Issue a return from member
5. See List of books due today
6. See List of all books due
7. Clear late fines for a student
8. Exit
"""
# handle for choice
choice = (input("Enter your option (1/7 8 to exit): "))
while True:
    if int(choice) == 1:
      librarian_interface.add_book()
      choice = int(input("Enter your option (1/7 8 to exit): "
    if int(choice) == 2:
      librarian_interface.remove_book()
      choice = int(input("Enter your option (1/7 8 to exit): "
    if int(choice) == 3:
       librarian_interface.issue_book()
       choice = int(input("Enter your option (1/7 8 to exit): "))
    if int(choice) == 4:
       librarian_interface.return_book()
       choice = int(input("Enter your option (1/7 8 to exit): "))
    if int(choice) == 5:
       librarian_interface.books_due_today()
       choice = int(input("Enter your option (1/7 8 to exit): "))
    if int(choice) == 6:
       librarian_interface.all_books_due()
       choice = int(input("Enter your option (1/7 8 to exit): "))
    if int(choice) == 7:
       librarian_interface.remove_dues()
       choice = int(input("Enter your option (1/7 8 to exit): "
    if int(choice) == 8:
       break
    else:
       print("Invalid option. Try again")
       choice = (input("Enter your option (1/ 7 to exit): "))
# create a new member
if choice == 2:
  member_name = input("Enter the name of the member: ")
  member_id = input("Enter the id of the member")
  librarian_interface.add_member(member_name,member_id)
Librarian_interface.py
    import utils
    from datetime import datetime
    conn = utils.create_connection()
    cursor = conn.cursor()
    def admin_login():
      username = input("Enter admin username: ")
      entered_passwd = input("Enter admin password: ")
      # fetch username and password from admin table
      query = "SELECT admin_password from admins where admin_username=%s"
      data = (username,)
      cursor.execute(query, data)
      result = cursor.fetchone()
      # check if password is correct
      db_passwd = result[0]
      if entered_passwd == db_passwd:
        return True
      else:
        return False
    # interface for adding books
    def add_book():
      book_id = input("Enter ISBN number of book: ")
      if len(book_id) != 13 or not book_id.isnumeric():
        print("Invalid ISBN Number")
        return
  book_name = input("Enter name of book: ")
  book_category = input("Enter the category the book belongs to: ")
  book_author = input("enter the author(s) of the book: ")
  if book_id.isnumeric() and " " not in (book_id, book_name, book_author, book_category):
    query = "INSERT INTO books VALUES (%s,%s,%s,%s,%s)"
    data = (book_id, book_name, book_author, book_category, True)
   try:
         cursor.execute(query, data)
         conn.commit()
    except:
         print("Some error occured")
         return
# interface for removing books
def remove_book():
  book_id = input(
    "Enter the isbn number of book to be removed from the library: ")
  if len(book_id) != 13 or not book_id.isnumeric():
    print("Invalid ISBN number")
    return
  query = "DELETE from books where book_id={}".format(book_id)
  try:
    cursor.execute(query)
    print("Book removed or was not present in library already.")
  except:
    print("Some error happened.Check if ISBN number of book is correct")
    return
# interface for handling an issue to student
def issue_book():
  book_id = input(
    "Enter the isbn number of book to be issued: ")
  if len(book_id) != 13 or not book_id.isnumeric():
    print("Invalid ISBN number")
    return
  mem_id = input("Enter the member id of the student:")
  # check if member_id is valid
  check_member_query = "SELECT member_id,member_name from members where member_id='{}'".format(
    mem_id)
  cursor.execute(check_member_query)
  result1 = cursor.fetchone()
  # check if book_id is valid
  check_book_query = "SELECT book_id,title from books where book_id='{}'".format(
    book_id)
  cursor.execute(check_book_query)
  result2 = cursor.fetchone()
  if result1 == None or result2 == None:
    print("Member or book id invalid. Try again")
    return
  # random issue id
  issue_id = str(utils.random_number(7))
  # get issue date
issue_date = input(
  "Input issue date in YYYY-mm-dd format (or press enter to input today's date): ")
issue_date = issue_date or datetime.today().strftime("%Y-%m-%d")
# get return date
return_date = input("Input return date in YYYY-mm-dd format: ")
# first query to insert data into issues table
query = "INSERT INTO issues VALUES (%s,%s,%s,%s,%s,%s)"
data = (issue_id, book_id, mem_id, issue_date, return_date, False)
# second query to update "issued_books" column in members table
q1 = "select issued_books from members where member_id='{}'".format(mem_id)
cursor.execute(q1)
d = cursor.fetchone()
books = d[0].split()
books.append(book_id)
books = ",".join(books)
q2 = "UPDATE members SET issued_books='{}' where member_id='{}'".format(
  books, mem_id)
cursor.execute(q2)
conn.commit()
# third query to update the "available column in table books"
q3 = "UPDATE books set available=FALSE where book_id='{}'".format(book_id)
cursor.execute(q3)
conn.commit()
try:
  cursor.execute(query, data)
    conn.commit()
    print("\n")
    print("---- Book issued ----")
    print("Book id:", book_id)
    print("Book Name:", result2[1])
    print("Issued to member with id:", result1[0])
    print("Member name: ", result1[1])
    print("Issue Date: ", issue_date)
    print("Return Date: ", return_date)
  except:
    print("some error occured")
def return_book():
  book_id = input("Enter the isbn number of book to be returned: ")
  if len(book_id) != 13 or not book_id.isnumeric():
    print("Invalid ISBN number")
    return
  # check if the book_id is present in issues table
  query = "SELECT book_id,member_id,issue_date,return_date,issue_id from issues where
book_id='{}'".format(
    book_id)
  cursor.execute(query)
  data = cursor.fetchone()
  if data == None:
    print("Book with the entered isbn number was not issued.")
    return
  print("Book with entered isbn number was issued. \n Details: ")
  print("ISBN number:", book_id)
  print("ID Of student who issued the book:", data[1])
  print("Day book was issued:", data[2])
  print("Expected return date:", data[3])
  # get date when book was returned
  actual_return_date = input(
    "Input the date when student returned the book in YYYY-mm-dd format (or press enter to input today's
date): ")
  actual_return_date = actual_return_date or datetime.today().strftime("%Y-%m-%d")
  # get difference between actual_return_date and return_date and calculate late fine
  b = datetime.strptime(str(actual_return_date), "%Y-%m-%d")
  a = datetime.strptime(str(data[3]), "%Y-%m-%d")
  delta = b - a
number_of_days_late = delta.days
  if number_of_days_late < 0:
    late_fine = 0
  else:
    late_fine = number_of_days_late * 10
  print("Number of days late:",number_of_days_late)
  print("Late fines (Rs 10/day):",late_fine)
  # update the issues table and set "is_returned to true"
  try:
    q1 = "UPDATE issues SET is_returned=TRUE where issue_id={}".format(data[4])
    cursor.execute(q1)
    conn.commit()
    # pop the book from issued_books column in members table
    q2 = "select issued_books from members where member_id='{}'".format(
    data[1])
    cursor.execute(q2)
    d = cursor.fetchone()
    books = d[0].split()
    # remove last issued book
    if len(books) != 0 and book_id in books:
      books.remove(book_id)
    books = ",".join(books)
    q3 = "UPDATE members SET issued_books='{}',member_dues={} where member_id='{}'".format(
      books, late_fine, data[1])
    cursor.execute(q3)
    conn.commit()
 except:
    print("some error occured")
  # make book available again
  q3 = "UPDATE books set available=TRUE where book_id='{}'".format(book_id)
  cursor.execute(q3)
  conn.commit()
def books_due_today():
  return_date = input(
    "Input date to see list of books due on that date(or press enter to input today's date): ")
  return_date = return_date or datetime.today().strftime("%Y-%m-%d")
  query= "select book_id,member_id from issues where return_date='{}'".format(return_date)
  cursor.execute(query)
  data = cursor.fetchall()
  print("\n")
  print("---List of books due on {}----".format(return_date))
  print("Book ID (isbn)",'\t',"Book Name",'\t',"Member ID",'\t',"Member Name")
  for row in data:
    # get book name from book_id
    q2 = "select title from books where book_id='{}'".format(row[0])
    cursor.execute(q2)
    data = cursor.fetchone()
    book_name = data[0]
    # get member name from member_id
    q3 = "select member_name from members where member_id='{}'".format(row[1])
    cursor.execute(q3)
    data = cursor.fetchone()
    member_name = data[0]
    print(row[0],'\t',book_name,'\t','\t',row[1],'\t',member_name)
def all_books_due():
  query= "select book_id,member_id from issues"
  cursor.execute(query)
  data = cursor.fetchall()
  print("\n")
  print("--- List of all books due ----")
  print("Book ID (isbn)",'\t','\t','\t',"Book Name",'\t','\t','\t',"Member ID",'\t','\t','\t',"Member Name")
  for row in data:
    # get book name from book_id
    q2 = "select title from books where book_id='{}'".format(row[0])
    cursor.execute(q2)
    data = cursor.fetchone()
    book_name = data[0]
    # get member name from member_id
    q3 = "select member_name from members where member_id='{}'".format(row[1])
    cursor.execute(q3)
    data = cursor.fetchone()
    member_name = data[0]
    print(row[0],'\t','\t','\t',book_name,'\t','\t','\t',row[1],'\t','\t','\t',member_name)
def remove_dues():
  member_id = input("Enter the id of the member to clear the late fines: ")
  q = "UPDATE members set member_dues=0 where member_id={}".format(member_id)
  cursor.execute(q)
  conn.commit()
  print("all dues cleared")
def add_member(member_name,member_id):
  data = (member_id,member_name,"",0)
  query = "INSERT INTO members VALUES (%s,%s,%s,%s)"
  cursor.execute(query,data)
    conn.commit()
    print("Member added.")
utils.py
    def create_connection():
      import mysql.connector as connector
      conn = connector.connect(user='ashklempton',passwd='ash12345',host='localhost',database='librarydb')
      return conn
    # function to return a random_number of length n
    def random_number(n):
      from random import randint
      range_start = 10**(n-1)
      range_end = (10**n)-1
      return randint(range_start, range_end)
       Possible Future Enhancements
●    A member-only portal can be created for members to see which
books they have borrowed , their late fines due , information regarding
books etc.
●    A Search functionality can be created to search for present books
in the library.
●    A distributed database can be used instead of mysql to allow
more users and multiple administrative computers
●    Instead of using a CLI interface , a graphical user interface (GUI)
can be used for making the software more user-friendly.
●    Automated test suites can be used instead of manual testing to
improve quality of software
●    More features can be introduced for making the software more
general purpose , at the moment , several assumptions have been
made about how the software should function and what features it
should have so as to cater to only one organization. Removing these
assumptions can aid in making this system more general purpose.
A lot of these future enhancements are not part of the application
because they are out of the scope of this project.
                          Output Screens
Login Screen and admin options
Add member
Add book , issue book
Return book
See list of books due
                      Bibliography
● Sumita Arora, Computer Science with python textbook
● MVC - https://en.wikipedia.org/Model-view-controller
● Software Testing - https://en.wikipedia.org/wiki/Software_testing