Computer Project
Computer Project
CERTIFICATE
This is to certify that [YOUR NAME] of Class-XII SCI-{SEC} has
successfully completed the Computer Science project titled
“LIBRARY MANAGEMENT SYSTEM" as part of the Class XII
Computer Science curriculum under the CBSE guidelines.
The project has been completed with diligence and has met
the standard of the CBSE curriculum.
ACKNOWLEDGEMENT
Index
Topic Page No.
Introduction 5
System 8
Specifications
Coding 9-22
implementation
and documentation
App in working 22-28
MySQl Outputs 29
Conclusion 30
Bibliography/ 31
References
Introduction
Libraries are integral to education and self-
development, serving as repositories of
Page |5
LITERATURE REVIEW
SYSTEM SPECIFIACATIONS
OS Win 8+, Linux Win 10+, Win 7+, Linux Win 10+,
LTS Linux LTS Linux
File Structure:
DEVELOPMENT FILES
USEFUL INSTRUCTIONS
PYCACHE
CODING -</>--
mainapp.py
This is the main python program where the majority of tasks
involving database access and modifying, calling major functions
and libraries and neighbour files, and interface design, have been
written.
root.destroy()
enter_pg=ctk.CTkToplevel()
enter_pg.geometry('1000x400+100+100')
enter_pg.title("Entry Page")
enter_pg.resizable(False,False)
enter_pg.protocol('WM_DELETE_WINDOW',close_all)
tpw=None
def connection():
global tpw
if tpw is not None and tpw.winfo_exists():
tpw.lift()
else:
tpw=ctk.CTkToplevel()
tpw.title("Connect database")
tpw.geometry('400x234+600+300')
tpw.resizable(False,False)
tpw.attributes('-topmost',True)
enter_pg.attributes('-topmost',False)
ent1=ctk.CTkEntry(tpw,placeholder_text='Enter
Username',height=34,width=345)
ent2=ctk.CTkEntry(tpw,placeholder_text='Enter
Password',height=34,width=345)
ent1.pack(padx=20,pady=20)
ent2.pack(padx=20,pady=20)
def submit():
try:
dbc.connect(ent1.get(),ent2.get())
with open('Password_Store.txt','w') as f:
f.write(ent2.get())
tpw.destroy()
pass_entry.configure(state='normal')
sub1.configure(state='normal')
dbc.gcur.execute("Select * from book_info")
for row in dbc.gcur.fetchall():
table1.add_row(values=row)
dbc.gcur.execute("Select * from members")
for row in dbc.gcur.fetchall():
table2.add_row(values=row)
except Exception as e:
P a g e | 13
root.attributes('-topmost',True)
messagebox.showwarning('','Please recheck database
username and password')
sub=ctk.CTkButton(tpw,text='S u b m i
t',command=submit,font=('Bodoni
MT',16,'bold'),fg_color='#8865B1',text_color='#C7E08C',hover_color
='#785B9A')
sub.pack()
def pass_sub():
if dbc.check_pass(pass_entry.get()):
root.deiconify()
enter_pg.destroy()
mtm.Upd_Sub_Stat()
dbc.gcur.execute("Select * from issue_info")
for row in dbc.gcur.fetchall():
table3.add_row(values=row)
else:
root.attributes("-topmost", True)
messagebox.showinfo("", "Incorrect details entered!")
pass_entry.delete(0,'end')
l1=ctk.CTkLabel(enter_pg,text='Bookworm\n25 Park
Street,Kolkata',font=("Algerian",45,'bold'),text_color='coral')
l1.pack(pady=50)
pass_entry=ctk.CTkEntry(enter_pg,placeholder_text='Enter password(Same as
database)',width=300)
pass_entry.pack()
con_dat=ctk.CTkButton(enter_pg,text='Connect to
database',command=connection,height=17,width=100,font=('Bodoni
MT',16,'bold'),fg_color='#8865B1',text_color='#C7E08C',
hover_color='#785B9A')
con_dat.pack(pady=20)
sub1=ctk.CTkButton(enter_pg,text='S u b m i t P a s s w o r
d',command=pass_sub,height=17,width=100,font=('Bodoni
MT',16,'bold'),fg_color='#8865B1',text_color='#C7E08C',
hover_color='#785B9A')
sub1.pack()
if dbc.gcon is None and dbc.gcur is None:
pass_entry.configure(state='disabled')
sub1.configure(state='disabled')
l2=ctk.CTkLabel(root,text='Welcome to LibManager',font=("Eras Medium
ITC",45,'bold'),text_color='coral')
l2.pack()
tbv=ctk.CTkTabview(root,height=600,width=1100,corner_radius=30)
tbv.pack(pady=15)
ble=tbv.add("Book List and Edit")
mle=tbv.add("Member List and Edit")
finst=tbv.add("Fine due")
brb=tbv.add("Borrow books form")
rtb=tbv.add("Return books form")
addb=tbv.add("Add new books")
P a g e | 14
dat=btm.EdBookInf(bn=ent1.get(),auth=ent2.get(),pub=ent3.get(),qty=ent4.get(),_id=table1.get(row=info['row'],c
olumn=0))
table1.delete_row(index=info['row'])
table1.add_row(index=info['row'],values=dat)
tpw.destroy()
def delete():
tpw.destroy()
dele=messagebox.askyesno('','\t Confirm delete?\nPlease make sure no member is yet
to return this book..')
if dele:
btm.DelBook(table1.get(row=info['row'],column=0))
table1.delete_row(info['row'])
except Exception:
messagebox.showwarning('','Unexpected error!!!')
l=table1.get_row(row=info['row'])
ent1=ctk.CTkEntry(tpw,placeholder_text='Enter Book Name',width=250)
ent2=ctk.CTkEntry(tpw,placeholder_text='Enter Author',width=250)
ent3=ctk.CTkEntry(tpw,placeholder_text='Enter Publisher',width=250)
ent4=ctk.CTkEntry(tpw,placeholder_text='Enter Quantity',width=250)
ent1.pack(pady=5)
ent2.pack(pady=5)
ent3.pack(pady=5)
ent4.pack(pady=5)
ent1.insert(0,l[1])
ent2.insert(0,l[2])
ent3.insert(0,l[3])
ent4.insert(0,l[4])
btn1=ctk.CTkButton(tpw,text='Submit',width=170,command=submit,fg_color='#d2e909',text_color='#299815',font=('C
opperplate Gothic bold',16),hover_color='#a1b205')
btn1.pack(pady=5)
btn2=ctk.CTkButton(tpw,text='Delete',width=170,command=delete,fg_color='#d2e909',text_color='dark
red',font=('Copperplate Gothic bold',15),hover_color='#a1b205')
btn2.pack(pady=5)
P a g e | 15
def edit_minfo(info):
global tpw
if tpw is not None and tpw.winfo_exists():
tpw.lift()
else:
root.attributes('-topmost',False)
tpw=ctk.CTkToplevel()
tpw.title("EDIT MEMBER INFO")
tpw.geometry('400x234+600+300')
tpw.attributes('-topmost',True)
tpw.resizable(False,False)
try:
def submit():
if not ent1.get():
root.attributes('-topmost',True)
messagebox.showwarning('','Please enter all fields')
tpw.destroy()
return
else:
table2.insert(row=info['row'],column=1,value=ent1.get())
mtm.EdMemInf(mn=ent1.get(),_id=table2.get(row=info['row'],column=0))
tpw.destroy()
def delete():
tpw.destroy()
dele=messagebox.askyesno('','\t Confirm delete?\nPlease make sure the
member has no returns pending')
if dele:
mtm.DelMem(table2.get(row=info['row'],column=0))
table2.delete_row(info['row'])
for row in [('Member Id','Member Name','Subscription','Join Date')]
+dbc.gcur.fetchall():
table2.add_row(values=row)
def renSub():
tpw.destroy()
mtm.RenSub(table2.get(info['row'],column=0))
table2.insert(row=info['row'],column=2,value='active')
messagebox.showinfo('','Subscription renewed')
except Exception:
messagebox.showwarning('','Unexpected error!!!')
l=table2.get_row(row=info['row'])
ent1=ctk.CTkEntry(tpw,placeholder_text='Enter Member Name',width=250)
ent1.pack(pady=5)
ent1.insert(0,l[1])
btn1=ctk.CTkButton(tpw,text='Submit
',width=170,command=submit,fg_color='#d2e909',text_color='#299815',font=('Copperplate Gothic
bold',16),hover_color='#a1b205')
btn1.pack(pady=5)
btn2=ctk.CTkButton(tpw,text='Delete',width=170,command=delete,fg_color='#d2e909',text_color='dark
red',font=('Copperplate Gothic bold',15),hover_color='#a1b205')
btn2.pack(pady=5)
btn3=ctk.CTkButton(tpw,text='Renew
Subscription',width=170,command=renSub,fg_color='#d2e909',text_color='dark
blue',font=('Copperplate Gothic bold',15),
hover_color='#a1b205',text_color_disabled='#969696')
btn3.pack(pady=5)
P a g e | 16
if table2.get(row=info['row'],column=2)=='active':
btn3.configure(state='disabled')
lab2=ctk.CTkLabel(fr2,text='View all members...Click for more actions',font=('Felix
titling',20),text_color='magenta')
lab2.pack(pady=10)
table2=ctkt.CTkTable(fr2,column=4,values=[('Member Id','Member Name','Subscription','Join
Date')],command=edit_minfo,hover=True)
table2.pack(expand=True, fill="both")
table2.edit_row(row=0,state='disabled',hover=False)
,table3.get(row=info['row'],column=1),table3.get(row=info['row'],column=2)))
dbc.gcon.commit()
table3.insert(row=info['row'],column=5,value=0)
lab3=ctk.CTkLabel(fr3,text='Fine Due for all members...Click for more
actions',font=('Felix titling',20),text_color='magenta')
lab3.pack(pady=10)
table3=ctkt.CTkTable(fr3,column=6,values=[('Member Id','Book Id','Borrow Date','Return
Date','Returned On','Fine(INR)')],hover=True,command=fine_payed)
table3.pack(expand=True, fill="both")
table3.edit_row(row=0,state='disabled',hover=False)
#---borrow form code---
ent1=ctk.CTkEntry(brb,placeholder_text='Enter membership ID',width=250)
ent2=ctk.CTkEntry(brb,placeholder_text='Enter book ID',width=250)
ent1.pack(pady=20)
ent2.pack(pady=20)
def submit():
try:
if not ent1.get() or not ent2.get():
messagebox.showwarning('','All fields not entered')
return
res=ma.set_borrow_return(ent1.get(),ent2.get())
if res:
messagebox.showwarning('','Subscription expired...Please renew')
else:
dbc.gcur.execute("Select * from issue_info where mem_id='%s' and
book_id='%s' and returned_on is null order by borrow_date desc limit 1"%
(ent1.get(),ent2.get()))
dat=dbc.gcur.fetchall()[0]
table3.add_row(values=dat)
dbc.gcur.execute("Select * from book_info")
dat=dbc.gcur.fetchall()
table1.update_values(values=[('Book_Id','Book_Name','Author','Publisher','Quantity')]
+dat)
messagebox.showinfo('','Registered...Thank you')
ent1.delete(0,'end')
ent2.delete(0,'end')
except Exception:
messagebox.showwarning('','Unexpected error!!!Please recheck information')
btn1=ctk.CTkButton(brb,text='Submit',width=170,command=submit,text_color='#40e93f',fon
P a g e | 17
t=('Century Gothic',18,'bold'))
btn1.pack(pady=10)
#--Return form code--
ent3=ctk.CTkEntry(rtb,placeholder_text='Enter membership ID',width=250)
ent4=ctk.CTkEntry(rtb,placeholder_text='Enter book ID',width=250)
ent5=ctk.CTkEntry(rtb,placeholder_text='Enter return date(YYYY-MM-DD)',width=250)
ent3.pack(pady=20)
ent4.pack(pady=20)
ent5.pack(pady=20)
def subret():
try:
if not ent3.get() or not ent4.get() or not ent5.get():
messagebox.showwarning('','All fields not entered')
return
res=ma.return_book(ent5.get(),ent3.get(),ent4.get())
if res=='No fine required':
messagebox.showinfo('',res)
dbc.gcur.execute("Select * from book_info")
dat=dbc.gcur.fetchall()
dat=[('Book_Id','Book_Name','Author','Publisher','Quantity')]+dat
table1.update_values(values=dat)
dbc.gcur.execute("Select * from issue_info")
dat=dbc.gcur.fetchall()
dat=[('Member Id','Book Id','Borrow Date','Return
Date','Returned On','Fine(INR)')]+dat
table3.update_values(values=dat)
ent3.delete(0,'end')
ent4.delete(0,'end')
ent5.delete(0,'end')
else:
messagebox.showinfo('','Fine required '+str(res)+'
Inr')
dbc.gcur.execute("Select * from book_info")
dat=dbc.gcur.fetchall()
dat=[('Book_Id','Book_Name','Author','Publisher','Quantity')]+dat
table1.update_values(values=dat)
dbc.gcur.execute("Select * from issue_info")
dat=dbc.gcur.fetchall()
dat=[('Member Id','Book Id','Borrow Date','Return
Date','Returned On','Fine(INR)')]+dat
table3.update_values(values=dat)
ent3.delete(0,'end')
ent4.delete(0,'end')
ent5.delete(0,'end')
P a g e | 18
except Exception:
messagebox.showwarning('','Unexpected error!!!Please
recheck information')
btn2=ctk.CTkButton(rtb,text='Submit',width=170,command=subret,text
_color='#40e93f',font=('Century Gothic',18,'bold'))
btn2.pack(pady=10)
table1.add_row(values=[ent6.get(),ent7.get(),ent8.get(),ent9.get(),ent10.get()])
messagebox.showinfo('','New book added succesfully')
ent6.delete(0,'end')
ent7.delete(0,'end')
ent8.delete(0,'end')
ent9.delete(0,'end')
ent10.delete(0,'end')
except Exception:
messagebox.showwarning('',"Unexpected error")
btn3=ctk.CTkButton(addb,text='Submit',width=170,command=subbook,fg_color='#6e0930',text_col
or='#34cb33',font=('Berlin Sans FB Demi',19,'bold'),hover_color='#4f0722')
btn3.pack(pady=12)
#--Add members--
ent11=ctk.CTkEntry(addm,placeholder_text='Enter Member Id',width=300)
ent12=ctk.CTkEntry(addm,placeholder_text='Enter Member Name',width=300)
ent13=ctk.CTkEntry(addm,placeholder_text='Enter Join Date(YYYY-MM-DD)',width=300)
ent11.pack(pady=10)
ent12.pack(pady=10)
ent13.pack(pady=10)
def submem():
if not ent11.get() or not ent12.get() or not ent13.get():
messagebox.showwarning('','Please enter all fields')
return
else:
try:
mtm.AddNewMem(_id=ent11.get(),mn=ent12.get(),jd=ent13.get(),sub='active')
table2.add_row(values=[ent11.get(),ent12.get(),'active',ent13.get()])
P a g e | 19
db_conn.py
This module is responsible for accessing the MySQL databases
and creating the required tables for storing the library’s data.
The connect() function connects to the database and creates
the table after checking if they exist or not and a global
connection and cursor variable used across other files. The
check_pass() function checks the inputted password as given
in the mainapp.py file.
import mysql.connector
get_pass,gcon,gcur=None,None,None
def connect(u_name,passw):
global gcon,gcur
gcon=mysql.connector.connect(host='localhost',user=u
_name,password=passw)
gcur=gcon.cursor()
gcur.execute('create database if not exists
lms')
gcur.execute('use lms')
gcur.execute('create table if not exists
book_info(Book_ID varchar(10) primary key, Book_Name
varchar(100),Author varchar(30),Publ varchar(30),
Qty integer)')
gcur.execute('create table if not exists
P a g e | 20
B_Table_Mod.py
This file holds the basic functions for adding, editing
and deleting data of books in the book_info table, and
is used in the mainapp.py file.
import db_conn as dbc
def AddNewBook(_id,bn,auth,pub,qty):
dbc.gcur.execute("Insert into Book_Info values('%s','%s','%s','%s',%s)"%
(_id,bn,auth,pub,qty))
dbc.gcon.commit()
def EdBookInf(_id,bn,auth,pub,qty):
dbc.gcur.execute("Update book_info set Book_Name='%s', Author='%s',Publ='%s',Qty=%s
where Book_ID='%s'"%(bn,auth,pub,qty,_id))
dbc.gcon.commit()
dbc.gcur.execute("Select * from book_info where Book_ID='%s'"%(_id,))
return dbc.gcur.fetchone()
def DelBook(_id):
dbc.gcur.execute("Delete from book_info where Book_ID='%s'"%(_id,))
dbc.gcon.commit()
M_Table_Mod.py
This file holds the functions for adding, editing and
deleting member data in the members table. Also, it
holds functions to monitor membership status of each
member.
P a g e | 21
Mem_Activity.py
Finally, this File administers the activities of members,
which primarily focuses on issued books, and whether
they have been returned in time or not. It assigns fine
to issue_info of members who haven’t returned by the
deadline by comparing deadline date and current date
by executing the curdate() function once the app is run.
Thus, the app needs to be executed at least once
everyday for checking the issue statuses.
+interval 20 day)"%(m_id,b_id))
dbc.gcur.execute("Select count(*) from book_info where book_id='%s'"%
(b_id,))
if dbc.gcur.fetchall()[0][0]==0:
raise IOError
dbc.gcur.execute("Update Book_Info set Qty=Qty-1 where Book_ID='%s'"%
(b_id,))
dbc.gcon.commit()
else:
return True
def return_book(ret_dt,m_id,b_id):
dbc.gcur.execute("select datediff('%s',(select return_date from
issue_info where mem_id='%s' and book_id='%s' and returned_on is null order
by borrow_date desc limit 1))"%(ret_dt,m_id,b_id))
res,fine=dbc.gcur.fetchall(),0
dbc.gcur.execute("Update issue_info set returned_on='%s' where
Mem_ID='%s' and Book_ID='%s' and returned_on is null order by borrow_date
desc limit 1"%(ret_dt,m_id,b_id))
dbc.gcon.commit()
day_diff=res[0][0]
if day_diff<=3 :
dbc.gcur.execute("Update Book_Info set Qty=Qty+1 where Book_ID='%s'"%
(b_id,))
dbc.gcon.commit()
return "No fine required"
else:
fine=day_diff*3
dbc.gcur.execute("Update issue_info set Fine_INR=%s where Mem_ID='%s'
and Book_ID='%s'"%(fine,m_id,b_id))
dbc.gcur.execute("Update Book_Info set Qty=Qty+1 where Book_ID='%s'"%
(b_id,))
dbc.gcon.commit()
return fine
App in working
Fig 1.3: Empty database connection Form Fig 1.4: Filled database
connection Form
Fi
g.1.9: Books table updated with new entry
MYSQL OUTPUTS
Here are the tables and their structures used in our
Library Manager, as shown by MySQL Command Line
Client.
CONCLUSION
The Library Management System (LMS)
developed in this project showcases how
technology can streamline library operations,
making them more efficient and error-free. By
automating tasks such as book management,
member tracking, subscription handling, and fine
calculation, the system ensures an enhanced
user experience for both librarians and members.
Built using Python, MySQL, and Tkinter, the
application is lightweight, user-friendly, and well-
suited for small-scale libraries or educational
institutions.
This project is meant to be an imitation of real
softwares used in commercial levels, developed
by professional software engineers for big
companies, institutes etc. There are many scopes
of future improvements some of which are
mentioned below:
P a g e | 30
Bibliography
1.https://dev.mysql.com/doc/mysql-monitor/
8.0/en/system-prereqs-reference.html
2.https://www.geeksforgeeks.org
3.https://docs.python.org
4. https://docs.python.org/3/library/tkinter.html
5.https://realpython.com/python-gui-tkinter/
P a g e | 31