鱼C论坛

 找回密码
 立即注册
查看: 29298|回复: 228

[技术交流] 【详解】python信息管理系统【新】

  [复制链接]
发表于 2020-9-19 16:32:28 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 昨非 于 2020-10-14 18:33 编辑

【详解】python信息管理系统


一、前言
    花了整整一天时间搞了个python的信息管理系统,完成一大半了突然发现,鱼c已经有@zltzlt大佬做过了,而且功能十分齐全(比我做的好),一时间有点儿懊恼,大家能理解这种心理就好...
    毕竟鱼c只有三种帖子最火,第一种——官方教程等,这个理所当然,没啥意见;第二种——pygame小游戏诸如此类,毕竟原版教程就是冲着这个去的,忍了;第三种——爬取妹子图,花样爬取妹子图,爬取花样妹子图......,我:????
    转念一想,作为后来者,目前我们所做的东西绝大多数都是前人做过的,这本就是一种“前人栽树,后人乘凉”的体现。代码上,我承认以我入门不久的水平是不可能做到超越,不过我可以把整个程序描述的更详细点儿。
  我承认做不到100%的原创,也感谢前人给的参考,具体内容如下,帖子的顺序基本上算是还原了整个程序的制作过程了。

注:
本篇只是简单完成了信息管理系统的基本增删改查功能并注以解释,其余功能未完成或尚待优化之处,今后笔者会尽力更新的,还望读者见谅。
初次运行,请将【数据存储】部分students列表定义代码解除注释并将下方两行读取文件注释掉,避免因json文件不存在而报错。这一不足笔者后续会改善的,见谅

(完成不易,求大家评分支持!!)



二、代码及详解

1、信息管理系统框架

首先要完成的是打印出一个交互界面(相信大家学c过语言的都有经验),本质上就是一个菜单+死循环,在死循环中,通过input()函数满足交互需要,并依照菜单所示,完成分支的框架搭建,这部分没什么难度,附上代码和效果图:
#打印菜单,提示如何操作:
def menu():
    #菜单以多行字符串打印
    str_menu = """
\t欢迎使用【学生信息管理系统】
********************************************
请输入您想要进行的操作:
1.添加指定信息
2.显示全部信息
3.查询指定信息
4.删除指定信息
5.修改指定信息
6.打印操作提示

0.退出系统
********************************************
"""
    print(str_menu)

menu()

#主体循环
while True:
    #输入操作:
    action = input("请输入您想要进行的操作:")
    
    #分支判断
    #1.添加指定信息
    if action == "1":
        print("【添加指定信息】")
        pass
    
    
    #2.显示全部信息
    elif action == "2":
       print("【显示全部信息】")
       pass
    
    #3.查询指定信息
    elif action == "3":
       print("【查询指定信息】")
       pass
    
    #4.删除指定信息
    elif action == "4":
       print("【删除指定信息】")
       pass
    
    #5.修改指定信息
    elif action == "5":
       print("【修改指定信息】")
       pass
    
    #6.打印操作提示
    elif action == "6":
       print("【打印操作提示】")
       pass
    
    #0.退出系统
    elif action == "0":
        print("退出【信息管理系统】,欢迎下次使用!")
        break
    #输入错误:
    else:
        print("输入操作不存在,请按提示正确输入!")


                               
登录/注册后可看大图



2、选择数据存储方式

  我们知道,数据可以保存在内存中,也可以保存在本地。
  在内存中保存的数据,只在程序执行过程中存在,具有一些局限性,因此我们更提倡另一种方式——以文件形式保存在本地。
  可选的文件格式有很多种,诸如:txt,csv, xml,json,html 以及小甲鱼讲过的pkl, 这里我选择数据格式为json,想用pkl的可以参考https://fishc.com.cn/thread-144923-1-1.html
  针对信息管理系统:多个学员,以列表存储;每个学员,以字典保存各属性及数据;故:列表包含字典来存储。
样例数据为:
students = [
        {'name':'李四','chinese':'64','math':'65','English':'66','total':195},
        {'name':'王五','chinese':'65','math':'65','English':'66','total':196},
        {'name':'赵六','chinese':'66','math':'65','English':'66','total':197}
        ]


3、功能实现-打印

   有了数据,我们从简单的开始,先实现【全部数据打印】:
   即:遍历列表打印字典的值:



                               
登录/注册后可看大图



以*解包,(加入分隔符)效果如下:


                               
登录/注册后可看大图


这部分的代码如下:
#显示全部信息
def print_info():
    print('姓名    语文    数学    英语    总分')
    for student in students:
        print(*student.values(),sep="     ")


4、功能实现-插入

  我们知道,每个学员的信息以字典的形式储存在列表students中,所以插入分为两步;
【收集信息】->【添加到students列表】
收集信息时应注意,input函数返回的为字符串类型,所以作为成绩相加应该转为int

代码及效果图如下:
#添加指定信息
def insert():
    #收集(输入)信息
    name = input('请输入学生姓名:')
    chinese = int(input('请输入学生语文成绩:'))
    math = int(input('请输入学生数学成绩:'))
    English = int(input('请输入学生英语成绩:'))
    total = chinese + math + English
    
    #添加到students列表中
    students.append(
             {'name':name,'chinese':chinese,'math':math,'English':English,'total':total}
            )


                               
登录/注册后可看大图



5、功能实现-查找

查找的本质是从students列表里面查找,但实际的操作对象确实内部的字典。
因此,需要将列表数据一个个取出来(遍历),然后对比字典name项。
存在一个问题,在找不到的情况下能直接搭配if使用else吗?

错误代码:

def search():
    name = input('请输入需查询学生姓名:')
    
    for student in students: #遍历列表
        if name == student['name']: #对比字典的name
            print('姓名    语文    数学    英语    总分')
            print(*student.values(),sep="     ")
          
        else:
            print("该学生不存在!")

产生的效果如下:



                               
登录/注册后可看大图


【解决方案】:else与for搭配使用,在执行完for后会执行else
众鱼友:好像还是不对啊?
当然,需要在if判断查找到后加一个break,跳出for循环,之后的else自然就不会再执行了。反之,当没有查找到时,自然就不会执行break,else照常打印。

正确代码:

def search():
    name = input('请输入需查询学生姓名:')
    
    for student in students: #遍历列表
        if name == student['name']: #对比字典的name
            print('姓名    语文    数学    英语    总分')
            print(*student.values(),sep="     ")
            break
    else:
        print("该学生不存在!")

效果图:


                               
登录/注册后可看大图




5、功能实现-删除和修改

自不必多说,苍老师说过:“能找到,就能为所欲为”
你会发现这部分和查找何其相似(搬砖暴露了)。
代码如下:

#删除指定信息√
def delete_info():
    name = input('请输入需删除的学生姓名:')
    
    for student in students: #遍历列表
        if name == student['name']: #对比字典的name
            students.remove(student)
            break
    else:
        print("该学生不存在!")

#修改指定信息√
def modify_info():
    name = input('请输入需修改的学生姓名:')
    
    for student in students: #遍历列表
        if name == student['name']: #对比字典的name
            student['name']= input('请输入更新后学生姓名:')
            student['chinese'] = int(input('请输入更新后学生语文成绩:'))
            student['math']  = int(input('请输入更新后学生数学成绩:'))
            student['English'] = int(input('请输入更新后学生英语成绩:'))
            student['total']  = student['chinese'] +student['math'] + student['English']
            break
    else:
        print("该学生不存在!")

效果图如下:



                               
登录/注册后可看大图



                               
登录/注册后可看大图



6、功能实现-保存与后期读取

本程序默认退出程序时自动将内存中的students列表以json格式保存到本地。代码位于最后部分以with语句嵌入:
 #0.退出系统(自动保存到本地json形式)
    elif action == "0":
        print("退出【学生信息管理系统】")
        print("欢迎下次使用!")
        with open("data.json",mode='w',encoding="utf-8") as f:
             #将对象写入文件而不改变格式
            #f.write(json.dumps(students)) #这样写json格式中文会是“乱码”
            f.write(json.dumps(students,ensure_ascii=False))
        break



所谓“乱码”即为json格式里中文的sacii码,在dumps方法中加入ensure_ascii=False参数即可正确显示中文内容。
json格式中文“乱码”及修正后效果图:



                               
登录/注册后可看大图
         

                               
登录/注册后可看大图




后期读取代码在【数据存储】部分,这部分可与初始化时students列表相互替代:
with open("data.json",mode='r',encoding="utf-8") as f:
    students = json.loads(f.read()) #注:read读取出来的时字符串,需要转为json对象



三、全部代码

游客,如果您要查看本帖隐藏内容请回复



四、更新部分


1、更新内容概述:

(1)、数据存储部分,排除初次运行时json文件不存在需要手动修改代码的不便
(2)、部分注释内容不准确
(3)、数据结构中加入唯一ID解决按名字查找的重名问题
(4)、添加(多标准)排序功能  




2、具体内容


关于问题一,笔者通过加入打开文件的异常处理解决,这样即保留了必要的初始数据,也不会影响到后续读取文件已有内容。
代码如下:

try:
    with open("data.json",mode='r',encoding="utf-8") as f:
        students = json.loads(f.read())
        #注:read读取出来的时字符串,需要转为json对象

except FileNotFoundError:
    students = [  #初始数据,初次运行时避免文件打开报错
        {'id':'20200001','name':'李四','chinese':'64','math':'65','English':'66','total':195},
        {'id':'20200002','name':'王五','chinese':'65','math':'65','English':'66','total':196},
        {'id':'20200003','name':'赵六','chinese':'66','math':'65','English':'66','total':197}
        ]


关于问题二、三,内容在此不作赘述,详情请参考下方更新后的代码,有不足或可改进之处,欢迎评论指出。


新增排序功能部分:

列表的sort方法可以实现将一个列表中元素按照升序排列。然后,sort方法还可以按照我们选定的标准进行元素排序。

list.sort(key=None, reverse=False)

key:匹配一个一元的函数或者表达式,按照这个值决定对应元素在列表中的位置。这里我们定义一个函数sort_key()来作为标准,并利用交互界面提供给用户选择标准的操作空间。
reverse: 一个布尔值,若是True,表示要逆序即从大到小,False表示顺序从小到大。
排序部分代码如下:


#自定义排序(按各成绩)
def sorted_by_grade():
    sort_way = input(
                "请选择排序方式:\n"
                "1按语文成绩排序\n"
                "2按数学成绩排序\n"
                "3按英语成绩排序\n"
                "0按总成绩排序")
    while sort_way not in ['0', '1', '2', '3']:
        sort_way = input(
                    "输入无效!请选择排序方式:\n"
                    "1按语文成绩排序\n"
                    "2按数学成绩排序\n"
                    "3按英语成绩排序\n"
                    "0按总成绩排序")
    if sort_way == '0':
        def sort_key(x):
            return x['total']
    elif sort_way == '1':
        def sort_key(x):
            return int(x['chinese'])
    elif sort_way == '2':
        def sort_key(x):
            return int(x['math'])
    else:
        def sort_key(x):
            return int(x['English'])
    new_students = sorted(students, key=sort_key, reverse=True)
    print(title) #打印
    for student in new_students:
        print(*student.values(),sep="\t")  


排完序后,可以由用户选择是否保存到本地,代码如下:

    #保存入文件
    save_in = input("是否将默认学号顺序存入文件 (y/n)?")
    while save_in not in ['y', 'n']:
        save_in = input("输入无效!是否保存 (y/n)?")
    if save_in == 'y':
         f = open("data.json",mode='w',encoding="utf-8")       
         f.write(json.dumps(new_students,ensure_ascii=False))
         print('保存成功!')
    else:
        print('排序结果如上!')
        print('如之后还有需要,请重新排序或选择存入文件!')


但笔者在测试时却出现了问题,即:排序后结果正确打印,选择保存到本地后,在此调用print_info()函数发现,打印顺序仍为排序前的顺序。整体语法上没有报错,那么问题只会出现在逻辑上。

经反复检查,发现问题所在:
函数中排序后的new_students列表是区别于students列表的局部变量,而在打印函数中,打印的始终是students列表。
有鱼友可能会问,退出系统(自动保存)后再运行不就好了吗?
但是还是不对的:退出系统的自动保存students 会覆盖排序后的new_students的保存效果。

为此,笔者专门去查看了一下@zltzlt的代码(连接见上文),发现他的每个函数都是独立打开文件并关闭实现操作的,而笔者的初衷是将students列表作为自始至终的操作对象。

【解决办法】:在调用环节嵌入文件读取,对new_students列表刚刚保存进去的数据进行读取,并依旧使用students作为列表名称。

代码如下:

    #7.恢复默认顺序(学号顺序)
    elif action == "7":
        print("【恢复默认学号顺序】")
        sorted_by_id()#存入重新打开
        with open("data.json",mode='r',encoding="utf-8") as f:
            students = json.loads(f.read())
        
    #8.自定义排序(按各成绩)
    elif action == "8":
        print("【自定义排序(按各成绩)】")    
        sorted_by_grade()#存入重新打开
        with open("data.json",mode='r',encoding="utf-8") as f:
            students = json.loads(f.read())
        


完成排序的效果图如下:
id默认排序:


                               
登录/注册后可看大图


成绩排序:

                               
登录/注册后可看大图



3、更新后全部代码


游客,如果您要查看本帖隐藏内容请回复


五、结语

   感谢众多鱼友提出的宝贵建议,根据这几天大家的提示,我把我能做出来的部分都做了,可能依旧微不足道。
至今还没有完成的内容:
一、加入图形化界面:这个笔者学的不到家,还做不出来,不过今后如果我学会了,可以考虑补上。
二、调整数据结构以优化运行速度:首先感谢您的宝贵意见,但是以笔者的水平,只能说暂时还考虑不到哪一步了,所以十分抱歉。

   这篇帖子从代码到排版花了好久才完成,首先是真正意义上体会了一遍小甲鱼作扩展阅读之类教程的不容易。和甲鱼哥的目的差不多,这篇内容主要面向新手,所以没有什么太过硬核的东西,之前有鱼友评论说有些内容描述不准确,希望理解下,谢谢。
   内容上,我已经尽力完善了整个信息管理系统的功能,我知道这类代码随便一搜就是一大堆,这也是我在篇头说看到已经有人发过了而感到有些负面情绪的原因。但我也可以肯定,我应该是这里面写的最详细的一批了。


比不过大佬的游戏、爬虫那么吸引眼球,但也求一波评分支持!
Best wishes to FishC !

评分

参与人数 15荣誉 +24 鱼币 +21 贡献 +13 收起 理由
nizitao + 5 + 5
柿子饼同学 + 3
亢一飞 + 1 + 1 + 1 鱼C有你更精彩^_^
不会起名字的我 + 2 感谢楼主无私奉献!
小伤口 + 1 + 1 感谢楼主无私奉献!
严凯 + 5 + 3 鱼C有你更精彩^_^
Nate_2020 + 1 + 1 鱼C有你更精彩^_^
weiter + 2 + 3
zltzlt + 2 + 3 + 3 支持楼主!
my少年时代 + 1 感谢楼主无私奉献!

查看全部评分

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-9-23 11:46:47 | 显示全部楼层
已更新至2.0版本,跪求评分支持!

评分

参与人数 1荣誉 +1 鱼币 +1 收起 理由
开心小傻猪 + 1 + 1 用心,好评

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-9-19 16:35:37 | 显示全部楼层
@不二如是 @zltzlt 这个能申精吗(新人正儿八经发的第一帖,求通过)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-19 16:46:27 | 显示全部楼层
感谢分享!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-9-19 17:04:55 | 显示全部楼层

没事,欢迎评论领鱼币
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-19 17:26:50 | 显示全部楼层

回帖奖励 +3 鱼币

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-9-19 17:33:43 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-19 18:13:56 | 显示全部楼层
支持支持
前几天入python,希望有一天我也能在python写出数据库
到时希望各位大佬多多回答我的提问
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-9-19 18:40:14 | 显示全部楼层
巴巴鲁 发表于 2020-9-19 18:13
支持支持
前几天入python,希望有一天我也能在python写出数据库
到时希望各位大佬多多回答我的提问{:10_2 ...

我水平有限,一起学吧
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-19 18:46:45 | 显示全部楼层

回帖奖励 +3 鱼币

支持
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-9-19 18:47:10 | 显示全部楼层

回帖奖励 +3 鱼币

感谢分享~~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-19 21:20:30 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-9-20 08:29:20 | 显示全部楼层

回帖奖励 +3 鱼币

昨非 发表于 2020-9-19 16:35
@不二如是 @zltzlt 这个能申精吗(新人正儿八经发的第一帖,求通过)

嗯嗯,可以哦!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-9-20 08:40:28 From FishC Mobile | 显示全部楼层
不二如是 发表于 2020-9-20 08:29
嗯嗯,可以哦!!

谢谢肯定
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-20 08:53:22 | 显示全部楼层

回帖奖励 +3 鱼币

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-9-20 08:57:03 From FishC Mobile | 显示全部楼层

回帖奖励 +3 鱼币

支持
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-9-20 08:57:32 From FishC Mobile | 显示全部楼层
hrp 发表于 2020-9-20 08:57
支持

谢谢肯定
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-20 09:17:57 | 显示全部楼层

回帖奖励 +3 鱼币

66
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-9-20 10:36:11 | 显示全部楼层
1
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-9-20 12:40:35 | 显示全部楼层

回帖奖励 +3 鱼币

本帖最后由 疾风怪盗 于 2020-9-20 12:42 编辑

写得不错啊。。。。。。
1、能不能加图形化界面。。。。。。。。
2、如果学生重名,怎么办?
3、复制了代码,运行报错
FileNotFoundError: [Errno 2] No such file or directory: 'data.json'
是否可以增加判断,如果没有这个文件就新建一个空的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-9-20 12:42:04 | 显示全部楼层
疾风怪盗 发表于 2020-9-20 12:40
写得不错啊。。。。。。
能不能加图形化界面。。。。。。。。
考虑一个问题,如果学生重名,怎 ...

可以加的,还有排序,查找依据也不唯一。。。。
能优化的地方多了去了,
。。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-21 22:29

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表