Python基础语法体系,基础I/O,基础数据分析(numpy,pandas,matplotlib,xlrd)学习总结————以学生成绩信息管理系统为例

前言

笔者在学完简单的Python入门知识,尝试通过一个例子将学习到的一些知识点进行总结与应用,在这里涉及到:

1.pandas读取xlsx文件数据,对数据进行合并与分组,pandas的一些统计函数,pandas官网
2.应用matplotlib第三方库进行频率直方图、柱状图、并列柱状图的绘制,Matplotlib官网
3.组合数据类型的使用(列表、集合、字典)
4.控制结构与函数的使用


本文用到的Python库

import os
import time
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
import turtle
import xlrd
filename='student.txt'

一、多重索引模块

def show():
    student_lst=[]
    if os.path.exists(filename):
        with open(filename,'r',encoding='utf-8') as rfile:
            students=rfile.readlines()
            if students:
                for item in students:
                    d=dict(eval(item))
                    student_lst.append(d)
                show_student(student_lst)
        number=0
        for item in students:
            d=eval(item)
            d=pd.Series(d)
            if number==0:
                d1=d
            else:
                d1=pd.concat([d1,d],join='outer',axis=1)
            number+=1
        d2=d1.T
        d2.index=list(range(d2.shape[0]))
        df=d2
        d1=df.groupby(by=[df["classid"],df["gender"]])
        type_s=[]
        me_s=[]
        Ch=input('请选择一个科目:')
        for i,j in d1:
            type_s.append(i)
            me_s.append(round((j[Ch]).astype(int).mean(),2))
        name_list=['11班','12班','14班','15班','16班']
        num_list=me_s[::2]
        num_list1=me_s[1::2]
        x =list(range(len(num_list)))
        total_width, n = 0.6, 2
        width = total_width / n
        plt.rcParams['font.sans-serif']=['SimHei'] #显示中文标签
        plt.rcParams['axes.unicode_minus']=False
        plt.bar(x, num_list, width=width, label='boy',fc = 'y')
        for i in range(len(x)):
            x[i] = x[i] + width
        plt.bar(x, num_list1, width=width, label='girl',tick_label = name_list,fc = 'r')
        plt.legend()
        plt.xlabel('班级')
        plt.ylabel('{}课程考试班级平均成绩'.format(Ch))
        plt.savefig('fenbutu.jpg')
        plt.show()
        df=d2
        Ch=input('请选择一个科目:')
        d3=df[Ch].astype(int).values
        plt.hist(d3,d3.max()-d3.min()+1)
        plt.rcParams['font.sans-serif']=['SimHei'] #显示中文标签
        plt.rcParams['axes.unicode_minus']=False
        plt.xlabel('分数')
        plt.ylabel('人数')
        plt.savefig('pinlvzhifangtu.jpg')
        plt.show()
    else:
        print("暂未保存数据信息......")

按班级和性别两个选项,统计得到的C考试的平均分柱状图如下图所示:
在这里插入图片描述
下图是Python成绩的频率分布图:
在这里插入图片描述

二、排序模块

def sort():
    with open(filename,'r',encoding='utf-8') as rfile:
        student=rfile.readlines()
    number=0
    for item in student:
        d=eval(item)
        d=pd.Series(d)
        if number==0:
            d1=d
        else:
            d1=pd.concat([d1,d],join='outer',axis=1)
        number+=1
    d2=d1.T
    d2.index=list(range(d2.shape[0]))
    answer=input("按照什么排序(java,python,english,C)")
    d2.sort_values(answer,inplace=True,ascending=False)
    print(d2.head(10))
    time.sleep(3)

C成绩前十名如下图所示:
在这里插入图片描述

三、学生信息统计模块

def total():
    if os.path.exists(filename):
        with open(filename,'r',encoding='utf-8') as rfile:
            students=rfile.readlines()
            if students:
                print(f'一共有{len(students)}名学生')
                number=0
                for item in students:
                    d=eval(item)
                    d=pd.Series(d)
                    if number==0:
                        d1=d
                    else:
                        d1=pd.concat([d1,d],join='outer',axis=1)
                    number+=1
                d2=d1.T
                d2.index=list(range(d2.shape[0]))
                d2.sort_values("java",inplace=True,ascending=False)
                d3=d2.groupby(by="classid").count()["name"]
                _x=d3.index
                print(_x)
                _y=d3.values
                format_title='{:^12}\t{:^12}\t{:^12}\t{:^12}\t{:^12}\t'
                format_data='{:^12}\t{:^12}\t{:^12}\t{:^12}\t{:^12}\t'
                print(format_title.format(_x[0],_x[1],_x[2],_x[3],_x[4]))
                print(format_data.format(_y[0],_y[1],_y[3],_y[3],_y[4]))
                plt.figure(figsize=(8,4),dpi=80)
                plt.bar(range(len(_x)),_y,width=0.1,color="orange")
                plt.xticks(range(len(_x)),_x,fontsize=15,rotation=45)
                plt.show()

            else:
                print('还没有录入学生信息数据')
        
    else:
        print("暂未保存数据信息......")

下图是统计到的各个班级的总人数
各班总人数

下面这个函数用来统计选择的科目的最大值,最小值,平均值,标准差,统计该门考试的每班考试成绩第一名

def tongji():
    #if os.path.exists(filename):
    with open(filename,'r',encoding='utf-8') as rfile:
        students=rfile.readlines()
    #else:
        #print('还没有录入学生信息,即将返回主菜单!!!')
        #return
    number=0
    for item in students:
        d=eval(item)
        d=pd.Series(d)
        if number==0:
            d1=d
        else:
            d1=pd.concat([d1,d],join='outer',axis=1)
        number+=1
    d2=d1.T
    d2.index=list(range(d2.shape[0]))
    d2.sort_values("java",inplace=True,ascending=False)
    d3=d2.groupby(by="classid")
    choice=input('请选择要查询的科目(Python,Java,English,C)')
    for i,j in d3:
        print('\t\t\t\t{}班的{}成绩统计结果'.format(i,choice))
        format_title='{:^12}\t{:^12}\t{:^12}\t{:^12}\t'
        format_data='{:^12}\t{:^12}\t{:^12}\t{:^12}\t'
        print(format_title.format('最大值','最小值','平均值','标准差'))
        print(format_data.format(j[choice].astype(int).max(),j[choice].astype(int).min(),\
                                 round(j[choice].astype(int).mean(),2),round(j[choice].astype(int).std(),2)))
        print('\t{}班{}考试成绩第一名是{}同学'.format(i,choice,j["name"][j[choice]==j[choice].max()].values))
        print("*"*80)

统计结果如下图所示:
在这里插入图片描述

四、修改信息模块

开始
请求用户输入要修改的学生的ID
请求用户输入要修改的选项
是否输入全部选项?
按顺序修改
结束

程序按照这个流程进行计算,首先要判断文件是否存在,是否为空,文件若存在,接着以‘w’的方式打开txt文件,文件指针将从开头开始编辑文档,即原有内容会被删除。

def modify():
    show()
    if os.path.exists(filename):
        with open(filename,'r',encoding='utf-8') as rfile:
            student_old=rfile.readlines()
    else:
        return
    student_id=input('请输入要修改的学生的ID:')
    with open(filename,'w',encoding='utf-8') as wfile:
        number=0
        flag=[]
        for item in student_old:
            number+=1
            d=eval(item)
            if d['id']==int(student_id):
                print('找到学生信息,可以修改他的信息了!')
                flag.append(number)
                chioce=[]
                c_count=0
                while True:
                    chioce1=input('请输入要修改的选项(id,name,classid,gender,english,python,java,C)')
                    c_count=c_count+1
                    answer=input('是否要增加其他的选项?y/n\n')
                    chioce.append(chioce1)
                    if answer=='y' or answer=='Y':
                        continue
                    else:
                        print('您选择了{}个选项,是{}'.format(c_count,chioce))
                        break
                while True:
                    try:
                        for item in chioce:
                            d[item]=input('请输入{}:'.format(item))
                    except:
                        print('您的输入有误,请重新输入')
                    else:
                        break
                wfile.write(str(d)+'\n')
                print('修改成功')
            else:
                wfile.write(str(d)+'\n')
        answer=input('是否继续修改其他学生信息?y/n\n')
        if answer=='y':
            modify()

五、录入信息模块

因为一个个地录入数据很麻烦,这里在excel用随机数产生了一个100*8的矩阵,后面基于这个矩阵进行计算。
在这里插入图片描述
应用xlrd和pandas库读取excel中的数据,并将读取的数据写入“student.txt”文件中。

import xlrd
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
def save(lst):
    try:
        stu_txt=open(filename,'a',encoding='utf-8')
    except:
        stu_txt=open(filename,'w',encoding='utf-8')
    for item in lst:
        stu_txt.write(str(item)+'\n')
    stu_txt.close()
filename='student.txt'
df=pd.read_excel('学生信息管理系统.xlsx')
student_list=[]
for i in range(df.shape[0]):
    student={'id':str(df["id"][i]),'name':str(df["name"][i]),"gender":str(df["gender"][i]),'classid':str(df["classid"][i]),\
             'english':str(df["English"][i]),'python':str(df["Python"][i]),'java':str(df["Java"][i]),'C':str(df["C"][i])}
    student_list.append(student)
save(student_list)

这里在录入数据时,需要判断数据是否空,判断输入数据是否有误。

def insert():
    student_list=[]
    while True:
        id=input('请输入ID(如1001)')
        if not id:
            break
        name=input('请输入姓名:')
        if not name:
            break
        classid=input('请输入班级(如0011):')
        if not classid:
            break
        gender=input('请输入性别:')
        if not gender:
            break
        try:
            english=int(input('请输入英语成绩:'))
            python=int(input('请输入Python成绩'))
            java=int(input('请输入Java成绩'))
            C=int(input('请输入C成绩'))
        except:
            print('输入无效,不是整数类型,请重新输入')
            continue
        student={'id':id,'name':name,'gender':gender,'classid':classid,\
                 'english':english,'python':python,'java':java,'C':C}
        student_list.append(student)
        answer=input('是否继续添加?y/n\n')
        if answer=='y' or answer=='Y':
            continue
        else:
            break
    save(student_list)
    print('学生信息录入完毕')

六、将数据写入txt文件模块

6.1 Python open() 函数

最常用的有两个参数: open(filename, mode)。
第一个参数是包含文件名的字符串。第二个参数是另一个字符串,其中包含一些描述文件使用方式的字符。mode 参数是可选的;省略时默认为 ‘r’。

mode描述
r只能读取
w只能写入(已存在的同名文件会被删除)
a打开文件以追加内容,任何写入的数据会自动添加到文件的末尾
r+打开文件进行读写

在处理文件对象时,最好使用 with 关键字。 优点是当子句体结束后文件会正确关闭,即使在某个时刻引发了异常。

6.2 函数

以“a”的方式打开文档,将新的信息增加到文档。

def save(lst):
    try:
        stu_txt=open(filename,'a',encoding='utf-8')
    except:
        stu_txt=open(filename,'w',encoding='utf-8')
    for item in lst:
        stu_txt.write(str(item)+'\n')
    stu_txt.close()

七、查询信息模块

7.1 查询函数

def search():
    student_query=[]
    while True:
        id=''
        name=''
        if os.path.exists(filename):
            mode=input('ID查询请输入1,姓名查询请输入2:')
            if mode=='1':
                id=input('请输入学生ID:')
            elif mode=='2':
                name=input('请输入学生姓名:')
            else:
                print('您的输入有误,请重新输入')
                search()
            with open(filename,'r',encoding='utf-8') as rfile:
                 student=rfile.readlines()
                 for item in student:
                     d=eval(item)
                     if id!='':
                         if d['id']==int(id):
                             student_query.append(d)
                     elif name!='':
                         if d['name']==name:
                             student_query.append(d)
            show_student(student_query)
            student_query.clear()
            answer=input('是否要继续查询?y/n\n')
            if answer=='y' or answer=='Y':
                 continue
            else:
                 break
        else:
            print('暂无保存学生信息')
            return

7.2展示结果函数

7.2.1 print函数的使用

7.2.1.1不换行输出

当使用print函数时,它会自动打印一个换行符,这会导致输出提前进入下一行。如果不想在使用print函数后换行,可以在调用print函数时传递一个特殊的参数end=“anyendingstring”。

for i in range(30):
    print(i,end='-')

输出结果为:
在这里插入图片描述

7.2.2.2 格式化字符串字面值
import math
for i in range(30):
    print(i,end='-')
print('\n')
print(f'The value of pi is approximately {math.pi:.3f}.')

在这里插入图片描述

在 ‘:’ 后传递一个整数可以让该字段成为最小字符宽度。这在使列对齐时很有用。

import math
for i in range(30):
    print(i,end='-')
print('\n')
print(f'The value of pi is approximately {math.pi:.3f}.')
print('我今年已经{:^10.3f}了。'.format(20))
print('半径为4厘米的圆的面积为{:^15}。'.format(str(round(math.pi*4*4,4))+'平方厘米'))
print("baidu","www","com",sep='.')

可以通过sep="string"来设置间隔符。
在这里插入图片描述

Python print函数的官网文档

7.3函数

def show_student(lst):
    if len(lst)==0:
        print('没有查询到学生信息,无数据显示!!!')
        return
    format_title='{:^6}\t{:^12}\t{:^8}\t{:^8}\t{:^10}\t{:^10}\t{:^8}\t{:^8}\t{:^8}\t'
    print(format_title.format('id','name','gender','class','english','python','java','C','总成绩'))
    format_data='{:^6}\t{:^12}\t{:^8}\t{:^8}\t{:^10}\t{:^10}\t{:^8}\t{:^8}\t{:^8}\t'
    for item in lst:
        print(format_data.format(item.get('id'),item.get('name'),item.get('gender'),item.get('classid'),item.get('english'),\
                                 item.get('python'),item.get('java'),item.get('C'),\
                                 int(item.get('english'))+int(item.get('python'))+int(item.get('java'))+int(item.get('C'))))

八、主界面函数

def menum():
    a='学生信息管理系统'
    c1=a.center(81,'=')
    print(c1)
    b='功能菜单'
    c2=b.center(84,'=')
    print(c2)
    print("\t\t\t\t    1.录入学生信息")
    print("\t\t\t\t    2.查找学生信息")
    print("\t\t\t\t    3.删除学生信息")
    print("\t\t\t\t    4.修改学生信息")
    print("\t\t\t\t    5.成绩排序")
    print("\t\t\t\t    6.统计学生总人数,每个成绩平均分,最高分,最低分")
    print("\t\t\t\t    7.显示所有学生信息,成绩分布图(按性别或按班级)")
    print("\t\t\t\t    0.退出")
    print("-"*86)

九、删除信息模块

def delete():
    show_IDandName()
    while True:
        student_id=input('请输入要删除的学生的ID:')
        if student_id!='':
            if os.path.exists(filename):
                with open(filename,'r',encoding='utf-8') as file:
                    student_old=file.readlines()
            else:
                student_old=[]
            flag=False
            if student_old:
                with open(filename,'w',encoding='utf-8') as wfile:
                    d={}
                    for item in student_old:
                        d=dict(eval(item))
                        if d['id']!=student_id:
                            wfile.write(str(d)+'\n')
                        else:
                            flag=True
                    if flag:
                        print(f'id为{student_id}的学生信息已被删除')
                    else:
                        print(f'没有找到ID为{student_id}的学生信息')
            else:
                print('无学生信息')
                break
            answer=input('是否继续删除y/n\n?')
            if answer=='y' or answer=='Y':
                continue
            else:
                break

这个代码用来显示目前所有的学生信息ID和姓名。

def show_IDandName():
    student_list=[]
    with open(filename,'r',encoding='utf-8') as rfile:
        student_old=rfile.readlines()
    if student_old==[]:
        print('没有查询到学生信息,无数据显示!!!')
        return
    for item in student_old:
        d=eval(item)
        student_list.append(d)
    format_title='{:^6}\t{:^12}\t'
    format_data='{:^6}\t{:^12}\t'
    print(format_title.format('id','name'))
    for item in student_list:
        print(format_data.format(item.get('id'),item.get('name')))

十、主函数模块

def txtmain():
    while True:
        menum()
        choice=int(input('请选择'))
        if choice in list(range(8)):
            if choice==0:
                answer=input('您确定要退出系统吗?y/n\n')
                if answer=='y' or answer=='Y':
                    print('谢谢您的使用!!!')
                    break
                else:
                    continue
            elif choice==1:
                insert()
            elif choice==2:
                search()
            elif choice==3:
                delete()
            elif choice==4:
                modify()
            elif choice==5:
                sort()
            elif choice==6:
                total()
                tongji()
            elif choice==7:
                show()

十一、用集合统计班级个数

import pandas as pd
import numpy as np
filename='student.txt'
with open(filename,'r',encoding='utf-8') as rfile:
    students=rfile.readlines()
number=0
for item in students:
    d=eval(item)
    d=pd.Series(d)
    if number==0:
        d1=d
    else:
        d1=pd.concat([d1,d],join='outer',axis=1)
    number+=1
d2=d1.T
d2.index=list(range(d2.shape[0]))
d3=set(d2["classid"])
t1=[i+'班' for i in d3]
print('总共有{}个班级,分别是{}'.format(len(d3),t1))

在这里插入图片描述

十二、系统运行截图

选择界面
在这里插入图片描述
在键盘中输入相应的数字,就可以进入相应的模块。
在这里插入图片描述
输入0,退出系统。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

leetteel

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值