摘要:

本文基于python的图书馆管理系统和读者系统,实现了登录、注册、忘记密码、书籍查询、借阅、归还、修改等功能,通过csv文件将数据存储在本地。注册时采用了邮箱验证码,模拟了现实场景。(全部源代码地址见文末)如果有其他奇思妙想或者bug欢迎提出来!

一、效果图

主页面

选择编码

#选择编码def Pick(number):while True:try:pick = int(input('请输入需要的编号:'))if pick not in [i for i in range(1,number+1)]:print('编号无效!请重新输入!')continueelse:breakexcept:print('请输入数字!') return pick

主页面

#首页def home_page():print('\n')print("* "*15,'图 书 馆 管 理 系 统',15*' *','\n')print(''*13,'1.管理员登录',''*3,'2.读者登录\n')print(''*13,'3.管理员注册',''*3,'4.读者注册\n')print(''*13,'5.退出系统\n')print('* '*41)print('\n')pick = Pick(5)return pick

管理员界面

def root_menu():print('\n')print("* "*12,'欢 迎 登 录 图 书 馆 管 理 员 系 统',11*' *','\n')print(''*13,'1.书籍录入',''*3,'2.书籍查询\n')print(''*13,'3.书籍删除',''*3,'4.书籍修改\n')print(''*13,'5.借阅登记',''*3,'6.归还登记\n')print(''*13,'7.读者信息',''*3,'8.退出登录\n')# print(''*13,'9.归还提醒',''*3,'10.退出登录\n')print('* '*41)print('\n')pick = Pick(8)return pick

读者界面

def user_menu():print('\n')print("* "*13,'欢 迎 登 录 图 书 馆 读 者 系 统',13*' *','\n')print(''*13,'1.书籍查询',''*3,'2.自主还书\n')print(''*13,'3.个人信息',''*3,'4.自主借阅\n')print(''*13,'5.退出登录')print('* '*41)print('\n')pick = Pick(5)return pick

功能介绍:

1、登录

会判断账号是否存在和输入是否正确,密码错误可以进行忘记密码操作。

# 登录(记录操作者)def Sign_in(x):#管理员账号表或读者账号表,0管理员,1读者global administratorsglobal user#判断学号密码是否正确#学号必须是数字while True:try:id = int(input('请输入学号:'))breakexcept:print('学号必须是数字!')password = input('请输入密码:')#查询学号是否存在,密码是否正确if x==0:sign_in_data = administratorselif x==1:sign_in_data = user#print(sign_in_data)while (id not in sign_in_data['学号'].values)or(sign_in_data[sign_in_data['学号']==id]['密码'].values[0] != password):print('账号或密码输入错误!\n')print('\n* * * * * * * * 请 选 择 所 需 功 能 * * * * * * * * \n\n\t\t1.重新尝试\n\t\t2.忘记密码\n\t\t3.退回首页\n\n* * * * * * * * * * * * * * * * * * * * * * * * * *\n')pick = Pick(3)if pick == 1:return 11elif pick == 2:#忘记密码操作email = (sign_in_data.loc[sign_in_data['学号']==id]['邮箱'].values[0])if email != 0:#账号存在if x == 0: return forget(email[0],0)elif x==1:return forget(email[0],1)else:print('账号不存在!')return 0elif pick == 3:return 0print("正在登录.......")time.sleep(3)print('登录成功!')return id

2、注册

会判断账号是否存在,账号、密码格式是否正确,会向所填邮箱发送验证码,并将注册后的账号密码等信息记录起来。(QQ和QQ授权码需要换成自己的)

发送验证码

#发验证码def to_email(email,txt):# 发信方的信息:发信邮箱,QQ 邮箱授权码from_addr = '自己的@qq.com'password = '自己的邮箱授权码'# 发信服务器smtp_server = 'smtp.qq.com'msg = MIMEMultipart()msg['From'] = formataddr(["图书馆管理系统",from_addr])msg['To'] = formataddr(['',email])msg['Subject'] = Header('图书馆管理系统-邮箱验证')# 邮箱正文内容,第一个参数为内容,第二个参数为格式(plain 为纯文本),第三个参数为编码#生成一个随机验证码if txt == 0:code = ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(5))txt='【图书馆管理系统】本次验证码为'+code+',您正在申请通过图书馆管理系统验证,如非本人操作,请忽略。'msg.attach(MIMEText(txt, 'plain', 'utf-8'))server = smtplib.SMTP_SSL(smtp_server)server.connect(smtp_server,465)server.login(from_addr, password)server.sendmail(from_addr, email, msg.as_string())# 关闭服务器server.quit()print(f'验证码已发送至{email},请注意查收!')return code

密码格式判断

# 密码格式判断def count(s):num, char, space, d ,count= 0, 0, 0, 0 ,0 # 分别统计数字、字母、空格、其他字符个数for i in s:if i.isdigit():num += 1elif i.isalpha():char += 1elif i == ' ':space += 1print('密码存在空格!')return 0else:d += 1for i in [num, char, d]:if i >0:count += 1if count>=2:return 1else:print('密码应该包含数字、字母、标点符号中的两种或两种以上!')return 0

注册

#注册def logon(x):global administratorsglobal userwhile True:try:id = int(input('请输入学号:'))breakexcept:print('请输入数字!')name = input('请输入姓名:')major = input('请输入专业名:')#验证学号是否注册过if x==0: #管理员idlist = [administrators['学号'].values[0]]elif x==1: #读者idlist = [user['学号'].values[0]]while id in idlist:print('学号已注册过!\n')print('\n* * * * * * * * 请 选 择 所 需 功 能 * * * * * * * * \n\n\t\t1.重新尝试\n\t\t2.退回首页\n\n* * * * * * * * * * * * * * * * * * * * * * * * * *\n')pick = Pick(2)if pick == 1:while True:try:id = int(input('请输入学号:'))breakexcept:print('请输入数字!')breakelse:return 0while True:password = input('请输入密码:')if (len(password)10):print('密码应该长度大于6且小于10')continueelse:if count(password): #正确就退出breakelse:continue#发邮件while True:try:email = input('请输入邮箱账号:') code_x = to_email(email,0)while True:code_y = input('请输入验证码:')if code_x == code_y:pick = 0breakelse:print('验证码输入错误!')print('\n* * * * * * * * 请 选 择 所 需 功 能 * * * * * * * * \n\n\t\t1.重新输入邮箱\n\t\t2.重新输入验证码\n\t\t3.返回首页\n\n* * * * * * * * * * * * * * * * * * * * * * * * * *\n')pick=Pick(3)if pick == 1:breakelif pick == 2:continueelse:return 0except:print('邮箱账号错误!')print('\n* * * * * * * * 请 选 择 所 需 功 能 * * * * * * * * \n\n\t\t1.重新输入\n\t\t2.返回首页\n\n* * * * * * * * * * * * * * * * * * * * * * * * * *\n')pick = Pick(2)if pick == 1:continueelse:return 0if pick == 2:continueelif pick ==0:breakprint('正在注册......')time.sleep(3)#存贮if x==0:administrators0 = pd.DataFrame([{'学号':id,'姓名':name,'专业':major,'邮箱':email,'密码':password}])administrators = pd.concat([administrators,administrators0],axis = 0).reset_index(drop=True)administrators.to_csv(resource_path(os.path.join("res",'administrators.csv')),index=False)else:user0 = pd.DataFrame([{'学号':id,'姓名':name,'专业':major,'邮箱':email,'密码':password}])user = pd.concat([user,user0],axis = 0).reset_index(drop=True)user.to_csv(resource_path(os.path.join("res",'user.csv')),index=False)print('注册成功!\n')return 0

忘记密码

#忘记密码def forget(email,x):#0管理员,1读者global administratorsglobal userprint('正在发送验证码....')try:code_x = to_email(email,0)except:print('邮箱错误!')return desktop.home_page()code_y =input('请输入验证码:')count_ = 0#计算次数while code_x!=code_y:print('验证码输入错误!')count_+=1if count_==5:print('连续错误5次,需要重新发送验证码!')code_x = to_email(email,0)print(f'验证码已发送至{email},请注意查收!')count_=0else:code_y = input('请输入验证码:')print('验证码输入正确!')while True:newpassword = input('请输入新的密码:')if (len(newpassword)10):print('密码应该长度大于6且小于10')continueelse:if count(newpassword): #正确就退出breakelse:continueprint('正在修改........')if x==0: administrators.loc[administrators['邮箱']==email,'密码'] = newpassword administrators.to_csv(resource_path(os.path.join("res",'administrators.csv')),index=False) else:user.loc[user['邮箱']==email,'密码'] = newpassworduser.to_csv(resource_path(os.path.join("res",'user.csv')),index=False) print('密码修改成功!')return desktop.home_page()

二、管理员系统

功能介绍:

1.书籍录入

判断书籍有没有存在,存在表现为书籍数量的增加,不存在为种类和数量的增加,记录操作者和操作时间。

#1.书籍录入#填写日志def book_add(id):global booksglobal book_reworkwhile True:books_name = input('书籍名称:')books_author = input('作者:')books_date1 = input('书籍出版日期:')press = input('出版社:')books_date2 = time.strftime("%Y-%m-%d %H:%M:%S")#获取当前时间while True:try:books_count = int(input('书籍数量:'))breakexcept:print('请输入数字!')#书籍编号,判断书籍是否存在query = books[books['书籍名称']==books_name]if len(query):query = query[query['作者']==books_author]if len(query):query = query[query['出版日期']==books_date1]if len(query):#说明书籍存在print('正在录入.......')#查找书籍编号books_no = query.iloc[:1,0].values[0]#馆藏和可借数量增加books.loc[books['书籍编号']==books_no,'馆藏'] = books.loc[books['书籍编号']==books_no,'馆藏'] + books_countbooks.loc[books['书籍编号']==books_no,'可借'] = books.loc[books['书籍编号']==books_no,'可借'] + books_countbooks.to_csv(resource_path(os.path.join("res",'books.csv')),index=False) #将修改记录保存起来book_rework0 = pd.DataFrame([{'姓名':administrators.loc[administrators['学号']==id]['姓名'][0],'学号':administrators.loc[administrators['学号']==id]['学号'][0],'书籍编号':books_no,'修改列':'馆藏和可借','原来-现在':f'增加{books_count}','修改时间':time.strftime("%Y-%m-%d %H:%M:%S")}])book_rework = pd.concat([book_rework,book_rework0],axis = 0).reset_index(drop=True)book_rework.to_csv(resource_path(os.path.join("res",'book_rework.csv')),index=False)#不存在时(按编号最大的加1) if len(query) == 0:print('正在录入.......')books_id = max(books['书籍编号']) + 1books0 = pd.DataFrame([{'书籍编号':books_id,'书籍名称':books_name,'作者':books_author,'出版日期':books_date1,'出版社':press,'导入日期':books_date2,'馆藏':books_count,'可借':books_count}])books = pd.concat([books,books0],axis = 0).reset_index(drop=True) #合并并重置索引books.to_csv(resource_path(os.path.join("res",'books.csv')),index=False)#将修改记录保存起来book_rework0 = pd.DataFrame([{'姓名':administrators.loc[administrators['学号']==id]['姓名'].values[0],'学号':administrators.loc[administrators['学号']==id]['学号'].values[0],'书籍编号':books_id,'修改列':'全部','原来-现在':f'增加《{books_name}》{books_count}本','修改时间':time.strftime("%Y-%m-%d %H:%M:%S")}])book_rework = pd.concat([book_rework,book_rework0]).reset_index(drop=True)book_rework.to_csv(resource_path(os.path.join("res",'book_rework.csv')),index=False)print('录入成功!')print('\n* * * * * * * * 请 选 择 所 需 功 能 * * * * * * * * \n\n\t\t1.继续录入\n\t\t2.返回首页\n\n* * * * * * * * * * * * * * * * * * * * * * * * * *\n')num = Pick(2)if num == 1:continueelse:return desktop.root_menu()

2.书籍查询

可以按编号、书籍名、作者进行模糊查询

#2.书籍查询def book_query(id):while True:print('\n* * * * * * * * 请 选 择 查 询 方 式 * * * * * * * * \n\n\t\t1.按书籍编号查询\n\t\t2.按书籍名称查询\n\t\t3.按作者查询\n\n* * * * * * * * * * * * * * * * * * * * * * * * * *\n')query_x = Pick(3)if query_x==1:while True:try:query_y = int(input('请输入查询信息:'))breakexcept:print('请输入数字!')book_ = books.loc[books['书籍编号']==int(query_y)]elif query_x==2:query_y = input('请输入查询信息:')book_ = books[books.书籍名称.str.contains(query_y,na=False)]elif query_x==3:query_y = input('请输入查询信息:')book_ = books[books.作者.str.contains(query_y,na=False)]if len(book_)==0:print('查询书籍不存在!')print('\n* * * * * * * * 请 选 择 所 需 功 能 * * * * * * * * \n\n\t\t1.重新查询\n\t\t2.返回首页\n\n* * * * * * * * * * * * * * * * * * * * * * * * * *\n')num = Pick(2)if num == 1:continueelse:return desktop.root_menu()else:print('\n')print(tabulate(book_, headers = 'keys', tablefmt = 'pretty'))print('\n* * * * * * * * 请 选 择 所 需 功 能 * * * * * * * * \n\n\t\t1.重新查询\n\t\t2.书籍删除\n\t\t3.借阅登记\n\t\t4.返回首页\n\n* * * * * * * * * * * * * * * * * * * * * * * * * *\n')num = Pick(4)if num == 1:continue elif num == 2:return book_delete(id)elif num == 3:return book_borrow()else:return desktop.root_menu()

3.书籍删除

删除对应书籍的全部信息,记录操作者和操作时间

#3.书籍删除#会直接删除书籍的全部信息def book_delete(id):global booksglobal book_reworkwhile True:while True:try:query_y = int(input('请输入书籍编号:'))breakexcept:print('请输入数字!')book_ = books.loc[books['书籍编号']==query_y]if len(book_)==0:print('书籍不存在!')print('\n* * * * * * * * 请 选 择 所 需 功 能 * * * * * * * * \n\n\t\t1.重新输入\n\t\t2.返回首页\n\n* * * * * * * * * * * * * * * * * * * * * * * * * *\n')pick = Pick(2)if pick == 1:continueelse:return desktop.root_menu()else:print(book_)print('\n* * * * * * * * 请 选 择 所 需 功 能 * * * * * * * * \n\n\t\t1.删除书籍\n\t\t2.重新输入\n\t\t3.返回首页\n\n* * * * * * * * * * * * * * * * * * * * * * * * * *\n')pick = Pick(3)if pick ==1:print('正在删除......')#删除书籍books = books.drop(books.loc[books['书籍编号']==query_y].index, axis=0)books.to_csv(resource_path(os.path.join("res",'books.csv')),index=False)#将修改记录保存起来book_rework0 = pd.DataFrame([{'姓名':administrators.loc[administrators['学号']==id]['姓名'].values[0],'学号':administrators.loc[administrators['学号']==id]['学号'].values[0],'书籍编号':query_y,'修改列':'全部列','原来-现在':list(books.loc[books['书籍编号']==query_y].values),'修改时间':time.strftime("%Y-%m-%d %H:%M:%S")}])book_rework = pd.concat([book_rework,book_rework0]).reset_index(drop=True)books.to_csv(resource_path(os.path.join("res",'books.csv')),index=False)print('删除成功!')print('\n* * * * * * * * 请 选 择 所 需 功 能 * * * * * * * * \n\n\t\t1.继续删除\n\t\t2.返回首页\n\n* * * * * * * * * * * * * * * * * * * * * * * * * *\n')pick = Pick(2)if pick == 1:continueelse:return desktop.root_menu()elif pick == 2:continueelse:return desktop.root_menu()

4.书籍修改

修改书籍数据,记录操作者和操作时间

#4.书籍修改#需要填写修改日志def book_Rework(id):global booksglobal book_reworkwhile True:while True:try:query_y = int(input('请输入书籍编号:'))breakexcept:print('请输入数字!')book_ = books.loc[books['书籍编号']==query_y]if len(book_)==0:print('书籍不存在!')print('\n* * * * * * * * 请 选 择 所 需 功 能 * * * * * * * * \n\n\t\t1.重新输入\n\t\t2.返回首页\n\n* * * * * * * * * * * * * * * * * * * * * * * * * *\n')pick = Pick(2)if pick == 1:continueelse:return desktop.root_menu()else:print(tabulate(book_, headers = 'keys', tablefmt = 'pretty'))print('\n* * * * * * * * 请 选 择 所 需 功 能 * * * * * * * * \n\n\t\t1.修改书籍\n\t\t2.重新输入\n\t\t3.返回首页\n\n* * * * * * * * * * * * * * * * * * * * * * * * * *\n')pick = Pick(3)if pick ==1:print('\n* * * * * * * * 请 选 择 修 改 字 段* * * * * * * * \n\n\t\t1.修改书籍名称\n\t\t2.修改书籍作者\n\t\t3.修改馆藏\n\t\t4.修改可借\n\n* * * * * * * * * * * * * * * * * * * * * * * * * *\n')pick = Pick(3)if pick == 1:book_newname = input('请输入新的书籍名称:')#将修改记录保存起来old = books.loc[books['书籍编号'] == query_y,'书籍名称'].valuesbook_rework0 = pd.DataFrame([{'姓名':administrators.loc[administrators['学号']==id]['姓名'].values[0],'学号':administrators.loc[administrators['学号']==id]['学号'].values[0],'书籍编号':query_y,'修改列':'书籍名称','原来-现在':f'{old[0]}'+'-'+f'{book_newname}','修改时间':time.strftime("%Y-%m-%d %H:%M:%S")}])books.loc[books['书籍编号'] == query_y,'书籍名称'] = book_newnameelif pick == 2:book_author = input('请输入新的作者:')#将修改记录保存起来old = books.loc[books['书籍编号'] == query_y,'作者'].valuesbook_rework0 = pd.DataFrame([{'姓名':administrators.loc[administrators['学号']==id]['姓名'].values[0],'学号':administrators.loc[administrators['学号']==id]['学号'].values[0],'书籍编号':query_y,'修改列':'作者','原来-现在':f'{old[0]}'+'-'+f'{book_author}','修改时间':time.strftime("%Y-%m-%d %H:%M:%S")}])books.loc[books['书籍编号'] == query_y,'作者'] = book_authorelif pick == 3:while True:try:book_collection = int(input('请输入新的馆藏:'))breakexcept:print('请输入数字!')#将修改记录保存起来old = books.loc[books['书籍编号'] == query_y,'馆藏'].valuesbook_rework0 = pd.DataFrame([{'姓名':administrators.loc[administrators['学号']==id]['姓名'].values[0],'学号':administrators.loc[administrators['学号']==id]['学号'].values[0],'书籍编号':query_y,'修改列':'馆藏','原来-现在':f'{old[0]}'+'-'+f'{book_collection}','修改时间':time.strftime("%Y-%m-%d %H:%M:%S")}])books.loc[books['书籍编号'] == query_y,'馆藏'] = book_collectionelse:while True:try:book_borrow = int(input('请输入新的可借:'))breakexcept:print('请输入数字!')#将修改记录保存起来old = books.loc[books['书籍编号'] == query_y,'可借'].valuesbook_rework0 = pd.DataFrame([{'姓名':administrators.loc[administrators['学号']==id]['姓名'].values[0],'学号':administrators.loc[administrators['学号']==id]['学号'].values[0],'书籍编号':query_y,'修改列':'全部列','原来-现在':f'{old[0]}'+'-'+f'{book_borrow}','修改时间':time.strftime("%Y-%m-%d %H:%M:%S")}])books.loc[books['书籍编号'] == query_y,'可借'] = book_borrowprint('正在修改........')book_rework = pd.concat([book_rework,book_rework0]).reset_index(drop=True)books.to_csv(resource_path(os.path.join("res",'books.csv')),index=False)book_rework.to_csv(resource_path(os.path.join("res",'book_rework.csv')),index=False)print('修改成功!')print('\n* * * * * * * * 请 选 择 所 需 功 能 * * * * * * * * \n\n\t\t1.继续修改\n\t\t2.返回首页\n\n* * * * * * * * * * * * * * * * * * * * * * * * * *\n')pick = Pick(2)if pick == 1:continueelse:return desktop.root_menu()elif pick == 2:continueelse:return desktop.root_menu()

5.借阅登记

记录借阅者和借阅数据

#5.借阅登记def book_borrow():global booksglobal readerswhile True:while True:try:query_y = int(input('请输入书籍编号:'))breakexcept:print('请输入数字!')book_ = books.loc[books['书籍编号']==query_y]if len(book_)==0:print('书籍不存在!')print('\n* * * * * * * * 请 选 择 所 需 功 能 * * * * * * * * \n\n\t\t1.重新输入\n\t\t2.返回首页\n\n* * * * * * * * * * * * * * * * * * * * * * * * * *\n')pick = Pick(2)if pick == 1:return book_borrow()else:return desktop.root_menu()else:print('\n')print(tabulate(book_, headers = 'keys', tablefmt = 'pretty'))print('\n')#可借为0if book_['可借'].values==0 :print('书籍数量为0,无法借阅!')else:print('\n* * * * * * * * 请 选 择 所 需 功 能 * * * * * * * * \n\n\t\t1.借阅书籍\n\t\t2.重新输入\n\t\t3.返回首页\n\n* * * * * * * * * * * * * * * * * * * * * * * * * *\n')pick = Pick(3)if pick == 1:while True:try:booknum = int(input('请输入借阅数量:'))if booknum  book_['可借'].values:print('借阅数量不能多于可借书籍!')else:breakexcept:print('请输入数字!')while True:try:sno = int(input('请输入学号:'))breakexcept:print('请输入数字!')name = input('请输入姓名:')major = input('请输入专业名:')#记录借阅 readers.csvprint('正在借阅......')readers0 = pd.DataFrame([{'学号':sno,'姓名':name,'专业':major,'书籍编号':query_y,'书籍名':(books.loc[books['书籍编号']==query_y]['书籍名称'].values)[0],'作者':(books.loc[books['书籍编号']==query_y]['作者'].values)[0],'数量':booknum,'借阅/归还':'借阅','时间':time.strftime("%Y-%m-%d %H:%M:%S")}])readers = pd.concat([readers,readers0]).reset_index(drop=True)readers.to_csv(resource_path(os.path.join("res",'readers.csv')),index=False)#书籍表更改books.loc[books['书籍编号'] == query_y,'可借'] -= booknumbooks.to_csv(resource_path(os.path.join("res",'books.csv')),index=False)elif pick == 2:continueelse:return desktop.root_menu()print('借阅成功!')print('\n* * * * * * * * 请 选 择 所 需 功 能 * * * * * * * * \n\n\t\t1.继续借阅\n\t\t2.返回首页\n\n* * * * * * * * * * * * * * * * * * * * * * * * * *\n')pick = Pick(2)if pick == 1:continueelse:return desktop.root_menu()

6.归还登记

记录归还者和归还记录

#6.归还登记def book_return():global readersglobal bookswhile True:while True:try:sno = int(input('请输入学号:'))breakexcept:print('请输入数字!')name = input('请输入姓名:')major = input('请输入专业名:')newdf = pd.DataFrame(readers[readers['学号']==sno].groupby(by=['书籍编号','书籍名称','作者'],as_index=False)['数量'].agg(sum)).rename(columns={'数量':'未归还数量'})newdf = newdf[newdf['未归还数量']>0]if len(newdf) == 0:print('您未借阅过任何书籍!')else:print(newdf)while True:try:query_y = int(input('请输入书籍编号:'))breakexcept:print('请输入数字!')newdf_ = newdf.loc[newdf['书籍编号']==query_y]if len(newdf_)==0:print('书籍不存在!')print('\n* * * * * * * * 请 选 择 所 需 功 能 * * * * * * * * \n\n\t\t1.重新输入\n\t\t2.返回首页\n\n* * * * * * * * * * * * * * * * * * * * * * * * * *\n')pick = Pick(2)if pick == 1:continueelse:return desktop.root_menu()else:print(newdf_)print('\n* * * * * * * * 请 选 择 所 需 功 能 * * * * * * * * \n\n\t\t1.归还书籍\n\t\t2.重新输入\n\t\t3.返回首页\n\n* * * * * * * * * * * * * * * * * * * * * * * * * *\n')pick = Pick(3)if pick == 1:while True:try:booknum = int(input('请输入归还数量:'))if booknum  newdf_['未归还数量'].values:print('归还数量不能多于借出的数量!')else:breakexcept:print('请输入数字!')#归还登记 readers.csvprint('正在归还......')readers0 = pd.DataFrame([{'学号':sno,'姓名':name,'专业':major,'书籍编号':query_y,'书籍名称':(books.loc[books['书籍编号']==query_y]['书籍名称'].values)[0],'作者':(books.loc[books['书籍编号']==query_y]['作者'].values)[0],'数量':-booknum,'借阅/归还':'归还','时间':time.strftime("%Y-%m-%d %H:%M:%S")}])readers = pd.concat([readers,readers0]).reset_index(drop=True)readers.to_csv(resource_path(os.path.join("res",'readers.csv')),index=False)#bookS表改变books.loc[books['书籍编号'] == query_y,'可借'] += booknumbooks.to_csv(resource_path(os.path.join("res",'books.csv')),index=False)print('归还成功!')print('\n* * * * * * * * 请 选 择 所 需 功 能 * * * * * * * * \n\n\t\t1.继续归还\n\t\t2.返回首页\n\n* * * * * * * * * * * * * * * * * * * * * * * * * *\n')pick = Pick(2)if pick == 1:continueelse:return desktop.root_menu()elif pick == 2:continueelse:return desktop.root_menu()

7.读者信息

可以改变读者的密码等操作

#7.读者信息def readers_news():#读者可以通过这个找回丢失的密码global userwhile True:while True:try:u_id = int(input('请输入用户学号:'))breakexcept:print('请输入数字!')name = input('请输入用户姓名:')major = input('请输入用户专业名:')#查找user_ = user.loc[(user['学号'] == u_id )].loc[user['姓名']==name].loc[user['专业'] == major]if len(user_)==0:print('用户不存在!')print('\n* * * * * * * * 请 选 择 所 需 功 能 * * * * * * * * \n\n\t\t1.重新输入\n\t\t2.返回首页\n\n* * * * * * * * * * * * * * * * * * * * * * * * * *\n')pick = Pick(2)if pick == 1:continueelse:return desktop.root_menu()else:print(tabulate(user_, headers = 'keys', tablefmt = 'pretty'))#可以对学生信息进行修改print('\n* * * * * * * * 请 选 择 所 需 功 能 * * * * * * * * \n\n\t\t1.修改邮箱\n\t\t2.修改密码\n\t\t3.返回首页\n\n* * * * * * * * * * * * * * * * * * * * * * * * * *\n')pick = Pick(3)if pick == 1 :while True:try:new_email = input('请输入新的邮箱账号:') code_x = main_desktop.to_email(new_email,0)while True:code_y = input('请输入验证码:')if code_x == code_y:print('正在修改.......')user.loc[(user['学号'] == u_id) & (user['姓名']==name) &(user['专业'] == major),'邮箱'] = new_emailprint('修改成功!')pick = 0#退出breakelse:print('验证码输入错误!')print('\n* * * * * * * * 请 选 择 所 需 功 能 * * * * * * * * \n\n\t\t1.重新输入邮箱\n\t\t2.重新输入验证码\n\t\t3.返回首页\n\n* * * * * * * * * * * * * * * * * * * * * * * * * *\n')pick = Pick(3)if pick == 1:breakelif pick == 2:continueelse:return desktop.root_menu()except:print('邮箱账号错误!')print('\n* * * * * * * * 请 选 择 所 需 功 能 * * * * * * * * \n\n\t\t1.重新输入\n\t\t2.返回首页\n\n* * * * * * * * * * * * * * * * * * * * * * * * * *\n')pick = Pick(2)if pick == 1:continueelse:return desktop.root_menu()if pick == 2:continueelif pick == 0:breakelif pick == 2:while True:new_password = input('请输入密码:')if (len(new_password)10):print('密码应该长度大于6且小于10')else:if main_desktop.count(new_password): #正确就退出breakuser.loc[(user['学号'] == u_id) & (user['姓名']==name) &(user['专业'] == major),'密码'] = new_passworduser.to_csv(resource_path(os.path.join("res",'user.csv')),index=False)print('修改成功!')print('\n* * * * * * * * 请 选 择 所 需 功 能 * * * * * * * * \n\n\t\t1.继续修改\n\t\t2.返回首页\n\n* * * * * * * * * * * * * * * * * * * * * * * * * *\n')pick = Pick(2)if pick == 1:continueelse:return desktop.root_menu()

三、读者系统

功能

1.书籍查询

2.自主还书

3.个人信息

4.自主借阅

类似于管理员系统

代码

#user_function.py#用于存放读者的各种功能from tabulate import tabulateimport pandas as pdimport desktopimport main_desktopimport timeimport sysimport os#生成资源文件目录访问路径def resource_path(relative_path):if getattr(sys, 'frozen', False): #是否Bundle Resourcebase_path = sys._MEIPASSelse:base_path = os.path.abspath(".")return os.path.join(base_path, relative_path)#访问res文件夹下数据#各种表格user = pd.read_csv(resource_path(os.path.join("res","user.csv"))) #读者账号表books = pd.read_csv(resource_path(os.path.join("res","books.csv")))#书籍表readers = pd.read_csv(resource_path(os.path.join("res","readers.csv")))#读者借阅\归还记录#选择编码def Pick(number):while True:try:pick = int(input('请输入需要的编号:'))if pick not in [i for i in range(1,number+1)]:print('编号无效!请重新输入!')continueelse:breakexcept:print('请输入数字!') return pick#1.书籍查询def book_query():while True:print('\n* * * * * * * * 请 选 择 查 询 方 式 * * * * * * * * \n\n\t\t1.按书籍编号查询\n\t\t2.按书籍名称查询\n\t\t3.按作者查询\n\n* * * * * * * * * * * * * * * * * * * * * * * * * *\n')query_x = Pick(3)if query_x==1:while True:try:query_y = int(input('请输入查询信息:'))breakexcept:print('请输入数字!')book_ = books.loc[books['书籍编号']==int(query_y)]elif query_x==2:query_y = input('请输入查询信息:')book_ = books[books.书籍名称.str.contains(query_y)]elif query_x==3:query_y = input('请输入查询信息:')book_ = books[books.作者.str.contains(query_y)]if len(book_)==0:print('查询书籍不存在!')else:print('\n')print(tabulate(book_, headers = 'keys', tablefmt = 'pretty'))print('\n* * * * * * * * 请 选 择 所 需 功 能 * * * * * * * * \n\n\t\t1.重新查询\n\t\t2.返回首页\n\n* * * * * * * * * * * * * * * * * * * * * * * * * *\n')num = Pick(2)if num == 1:continueelse:return desktop.user_menu()#2.自主还书(先打印这个读者借阅的书籍数据)def book_return(id):global readersglobal bookswhile True:newdf = pd.DataFrame(readers[readers['学号']==id].groupby(by=['书籍编号','书籍名称','作者'],as_index=False)['数量'].agg(sum)).rename(columns={'数量':'未归还数量'})newdf = newdf[newdf['未归还数量']>0]if len(newdf) == 0:print('您未借阅过任何书籍!')else:print(tabulate(newdf, headers = 'keys', tablefmt = 'pretty'))while True:try:query_y = int(input('请输入要归还的书籍编号:'))breakexcept:print('请输入数字!')newdf_ = newdf.loc[newdf['书籍编号']==query_y]if len(newdf_)==0:print('您未借阅该书籍!')print('\n* * * * * * * * 请 选 择 所 需 功 能 * * * * * * * * \n\n\t\t1.重新输入\n\t\t2.返回首页\n\n* * * * * * * * * * * * * * * * * * * * * * * * * *\n')pick = Pick(2)if pick == 1:continueelse:return desktop.user_menu()else:print(tabulate(newdf_, headers = 'keys', tablefmt = 'pretty'))print('\n* * * * * * * * 请 选 择 所 需 功 能 * * * * * * * * \n\n\t\t1.归还书籍\n\t\t2.重新输入\n\t\t3.返回首页\n\n* * * * * * * * * * * * * * * * * * * * * * * * * *\n')pick = Pick(3)if pick == 1:while True:try:booknum = int(input('请输入归还数量:'))if booknum  newdf_['未归还数量'].values:print('归还数量不能多于借出的数量!')else:breakexcept:print('请输入数字!')#归还登记 readers.csvprint('正在归还......')readers0 = pd.DataFrame([{'学号':id,'姓名':user.loc[user['学号']==id]['姓名'][0],'专业':user.loc[user['学号']==id]['专业'][0],'书籍编号':query_y,'书籍名称':(books.loc[books['书籍编号']==query_y]['书籍名称'].values)[0],'作者':(books.loc[books['书籍编号']==query_y]['作者'].values)[0],'数量':-booknum,'借阅/归还':'归还','时间':time.strftime("%Y-%m-%d %H:%M:%S")}])readers = pd.concat([readers,readers0]).reset_index(drop=True)readers.to_csv(resource_path(os.path.join("res",'readers.csv')),index=False)#bookS表改变books.loc[books['书籍编号'] == query_y,'可借'] += booknumbooks.to_csv(resource_path(os.path.join("res",'books.csv')),index=False)print('归还成功!')print('\n* * * * * * * * 请 选 择 所 需 功 能 * * * * * * * * \n\n\t\t1.继续归还\n\t\t2.返回首页\n\n* * * * * * * * * * * * * * * * * * * * * * * * * *\n')pick = Pick(2)if pick == 1:continueelse:return desktop.user_menu()elif pick == 2:continueelse:return desktop.user_menu()#3.个人信息def readers_news(id):#读者可以通过这个找更改密码global user#查找while True:user_ = user.loc[(user['学号'] == id )]print(tabulate(user_, headers = 'keys', tablefmt = 'pretty'))#可以对学生信息进行修改print('\n* * * * * * * * 请 选 择 所 需 功 能 * * * * * * * * \n\n\t\t1.修改邮箱\n\t\t2.修改密码\n\t\t3.返回首页\n\n* * * * * * * * * * * * * * * * * * * * * * * * * *\n')pick = Pick(3)if pick == 1 :while True:try:new_email = input('请输入新的邮箱账号:') code_x = main_desktop.to_email(new_email,0)while True:code_y = input('请输入验证码:')if code_x == code_y:print('正在修改.......')user.loc[(user['学号'] == id),'邮箱'] = new_emailprint('修改成功!')pick = 0#退出breakelse:print('验证码输入错误!')print('\n* * * * * * * * 请 选 择 所 需 功 能 * * * * * * * * \n\n\t\t1.重新输入邮箱\n\t\t2.重新输入验证码\n\t\t3.返回首页\n\n* * * * * * * * * * * * * * * * * * * * * * * * * *\n')pick = Pick(3)if pick == 1:breakelif pick == 2:continueelse:return desktop.user_menu()except:print('邮箱账号错误!')print('\n* * * * * * * * 请 选 择 所 需 功 能 * * * * * * * * \n\n\t\t1.重新输入\n\t\t2.返回首页\n\n* * * * * * * * * * * * * * * * * * * * * * * * * *\n')pick = Pick(2)if pick == 1:continueelse:return desktop.user_menu()if pick == 2:continueelif pick == 0:breakelif pick == 2:while True:new_password = input('请输入密码:')if (len(new_password)10):print('密码应该长度大于6且小于10')else:if main_desktop.count(new_password): #正确就退出breakuser.loc[(user['学号'] == id),'密码'] = new_passworduser.to_csv(resource_path(os.path.join("res",'user.csv')),index=False)print('修改成功!')print('\n* * * * * * * * 请 选 择 所 需 功 能 * * * * * * * * \n\n\t\t1.继续修改\n\t\t2.返回首页\n\n* * * * * * * * * * * * * * * * * * * * * * * * * *\n')pick = Pick(2)if pick == 1:continueelse:return desktop.user_menu()else:return desktop.user_menu()#4.自主借阅def book_borrow(id):global booksglobal readerswhile True:while True:try:query_y = int(input('请输入书籍编号:'))breakexcept:print('请输入数字!')book_ = books.loc[books['书籍编号']==query_y]if len(book_)==0:print('书籍不存在!')print('\n* * * * * * * * 请 选 择 所 需 功 能 * * * * * * * * \n\n\t\t1.重新输入\n\t\t2.返回首页\n\n* * * * * * * * * * * * * * * * * * * * * * * * * *\n')pick = Pick(2)if pick == 1:return book_borrow()else:return desktop.root_menu()else:print('\n')print(tabulate(book_, headers = 'keys', tablefmt = 'pretty'))print('\n')#可借为0if book_['可借'].values==0 :print('书籍数量为0,无法借阅!')else:print('\n* * * * * * * * 请 选 择 所 需 功 能 * * * * * * * * \n\n\t\t1.借阅书籍\n\t\t2.重新输入\n\t\t3.返回首页\n\n* * * * * * * * * * * * * * * * * * * * * * * * * *\n')pick = Pick(3)if pick == 1:while True:try:booknum = int(input('请输入借阅数量:'))if booknum  book_['可借'].values:print('借阅数量不能多于可借书籍!')else:breakexcept:print('请输入数字!')#记录借阅 readers.csvprint('正在借阅......')readers0 = pd.DataFrame([{'学号':id,'姓名':user.loc[user['学号']==id]['姓名'][0],'专业':user.loc[user['学号']==id]['专业'][0],'书籍编号':query_y,'书籍名':(books.loc[books['书籍编号']==query_y]['书籍名称'].values)[0],'作者':(books.loc[books['书籍编号']==query_y]['作者'].values)[0],'数量':booknum,'借阅/归还':'借阅','时间':time.strftime("%Y-%m-%d %H:%M:%S")}])readers = pd.concat([readers,readers0]).reset_index(drop=True)readers.to_csv(resource_path(os.path.join("res",'readers.csv')),index=False)#书籍表更改books.loc[books['书籍编号'] == query_y,'可借'] -= booknumbooks.to_csv(resource_path(os.path.join("res",'books.csv')),index=False)elif pick == 2:continueelse:return desktop.root_menu()print('借阅成功!')print('\n* * * * * * * * 请 选 择 所 需 功 能 * * * * * * * * \n\n\t\t1.继续借阅\n\t\t2.返回首页\n\n* * * * * * * * * * * * * * * * * * * * * * * * * *\n')pick = Pick(2)if pick == 1:continueelse:return desktop.root_menu()#5.退出登录def sign_out():return desktop.home_page()

链接:https://pan.baidu.com/s/1-lpT9-TtKCEUh9fkRIopkw
提取码:ljyx

注:main_desktop.py中QQ和QQ授权码需要换成自己的!!!!!!