前言:由于技术原因,此项目目前仍处于开发状态,已开源到CSDN(全代码放在文末)和qinhao2008.top(要求环境:python3.6及以上,第三方库:matplotlib,xlrd,pylab)现积极准备打包成exe及配置相关环境
灵感来源:如今老师在拿到全班成绩单时面临着这样一种困境:既不能把成绩单直接发到家长群,又必须让学生知晓自己是否有退步,偏科等问题 ,虽然我校配备了查分公众号,但对于某科的高低程度判断仍有盲区,为了解决这一问题,我专门开发了这个项目
本人初三
功能介绍
1.自动读取表单
成绩单为随机数随机生成
读取表单后以x_axis_data,y_axis_data(翻译:x轴数据,y轴数据)两个列表来存储读取内容,需要时直接读取即可
2.分析历次成绩走势
(再说一遍这是随机数!!!)
这里我使用了两个函数(为了方便大家了解用处以及我后期维护,函数名使用中文)
def 读取(name):
读取函数用来读取各个表单并存放数据到列表里,传入的参数name用来控制读取文件的文件名
def 折线图():
3.超过全班人数
这里使用的函数是
def 饼状图():
主要思路是把各科成绩排名,读取本人的名次,用全班人数减名次,然后让计算机自己计算比例
4.与全班、所处分段平均分对比(最大创新)
在班里分析成绩的时候,会着重注意“偏科”,按照“全班平均分”来比较往往不够适合,对于成绩好的学生,极可能会超过全班平均成绩;对于成绩差的,又要求过高;所以,我采用了“分段平均”这种方式,即把全班分成n个分段,10人一分段,最后不够10人合并成一组,算取分段内平均分,以此来比较
这样对于偏科就很直观的表现出来了,比如“全科比较”这张图很直观看出,语文数学明显偏科(这是随机数生成的!!!)从饼状图也能直接看出
5.全自动生成文件与文件夹——python的巨大优势
最后一点就是全自动生成文件,全程只需要手动输入名字(未来会加考号确认及全班一键分析)就能直接在文件夹里看到我们的分析结果了
6.未来的改进计划
1.与刚刚自学的网站开发联合,程序完成后打开一个网页来看(为了现在看直观关掉了自适应)
2.将整个程序完全达到全自动,实际上程序还有很大部分并未完全自动化,是固定的数值
3.搭建一个网站,在服务器上运行程序让大家从网页上就能查到分析结果,目前由于技术原因暂未开始
源代码
不建议现在复制,未进行检查,打包等
import xlrd
from matplotlib import font_manager
from pylab import *
import os
plt.rcParams['font.sans-serif'] = ['SimHei'] # 解决中文显示问题
plt.rcParams['axes.unicode_minus'] = False # 解决中文显示问题
my_font = font_manager.FontProperties(fname="C:\Windows\Fonts\msyh.ttc")
work_book = xlrd.open_workbook('成绩单.xls') # 读取成绩单
x_axis_data = []
y_axis_data = []
sheet_1 = work_book.sheet_by_index(0)
def 保存分段与个人对比():
# 这两行代码解决 plt 中文显示的问题
# 输入统计数据
科目名称 = list(科目name)[:8]
分段成绩 = 各科分段平均分[:8]
个人成绩 = 个人各科成绩[:8]
bar_width = 0.4 # 条形宽度
index_male = np.arange(len(科目名称)) # 分段条形图的横坐标
index_female = index_male + bar_width # 个人条形图的横坐标
# 使用两次 bar 函数画出两组条形图
plt.bar(index_male, height=分段成绩, width=bar_width, color='springgreen', label='分段平均成绩')
plt.bar(index_female, height=个人成绩, width=bar_width, color='dodgerblue', label='你的成绩')
plt.legend() # 显示图例
plt.xticks(index_male + bar_width/2, 科目名称) # 让横坐标轴刻度显示
plt.ylabel('分数') # 纵坐标轴标题
plt.title('第{0}分段平均成绩与你的成绩对比'.format(所处分段)) # 图形标题
plt.savefig('{0}/0各科成绩对比.jpg'.format(username)) # 保存图片
plt.close()
def 各科全班与分段对比():
科目名称 = list(科目name)
分段成绩 = 各科分段平均分
全班成绩 = 各科全班平均分
个人成绩 = 个人各科成绩
waters = ('分段平均','全班平均', '你的成绩')
颜色 = ['orange', 'cornflowerblue', 'limegreen']
for i in range(9):
buy_number = [分段成绩[i], 全班成绩[i], 个人成绩[i]]
plt.bar(waters, buy_number, color=颜色)
plt.title('{0}成绩的对比图'.format(科目名称[i]))
plt.text(1, 全班成绩[i] + 0.5, int(全班成绩[i])) # 添加具体成绩标签
plt.text(0, 分段成绩[i] + 0.5, int(分段成绩[i]))
plt.text(2, 个人成绩[i] + 0.5, int(个人成绩[i]))
plt.savefig('{0}/{1}成绩对比.jpg'.format(username, 科目名称[i])) # 保存图片
plt.close()
# 创建文件夹
def 创建文件夹(path):
folder = os.path.exists(path)
if not folder: # 判断是否存在文件夹如果不存在则创建为文件夹
os.makedirs(path) # makedirs 创建文件时如果路径不存在会创建这个路径
print("--- 创建文件夹成功 ---")
print('正在保存您的成绩,请稍后')
else:
print("--- 文件夹被创建过了! ---")
print('正在保存您的成绩,请稍后')
def 饼状图():
for i in range(9):
#饼状图占比
fraces = [len(allname) - 个人各科成绩排名[i], 个人各科成绩排名[i]]
#设置显示方式为标准圆
plt.axes(aspect=1)
#设置两个数据得文字说明
plt.pie(x=fraces, autopct='%3.1f%%', labels=['您超过的', '全班人数'])
#显示上部文字说明
plt.title(科目name[i] + '超过全班')
#设置图片
photo = '{1}/{0}{1}.jpg'.format(科目name[i], username)
plt.savefig(photo) # 保存图片
# plt.show()
plt.close()
data_col_history = []
data_row_history = []
def 读取(name):
work_book = xlrd.open_workbook(name)
sheet_1 = work_book.sheet_by_index(0)
global data_col_history
data_col_history.append([sheet_1.col_values(i) for i in range(sheet_1.ncols)])
for row in range(sheet_1.nrows):
data_row_history.append(sheet_1.row_values(row))
读取('成绩单.xls')
读取('成绩单02.xls')
读取('成绩单03.xls')
def 折线图():
各科成绩=[]
位置=data_col_history[0][0].index(username)
各科历次成绩=[]
for j in range(len(data_col_history)):
for i in range(8):
各科成绩.append(data_col_history[j][i+1][位置])
各科历次成绩.append(各科成绩)
各科成绩=[]
mpl.rcParams['font.sans-serif'] = ['SimHei'] # 添加这条可以让图形显示中文
y_axis_data=[]
科目名称=['语文', '数学', '英语', '政治', '历史', '地理', '生物', '物理']
for i in range(8):
x_axis_data = [1, 2, 3]
for j in range(len(各科历次成绩)):
y_axis_data .append([各科历次成绩[j][i]])
#print(y_axis_data)
# plot中参数的含义分别是横轴值,纵轴值,线的形状,颜色,透明度,线的宽度和标签
plt.plot(x_axis_data, y_axis_data, 'ro-', color='#4169E1', alpha=0.8, linewidth=1, label=科目名称[i])
# 显示标签,如果不加这句,即使在plot中加了label='一些数字'的参数,最终还是不会显示标签
plt.legend(loc="upper right")
plt.xlabel('考试次数')
plt.ylabel('分数')
for x in range(3):
plt.text(x_axis_data[x],float(y_axis_data[x][0])+0.2,str(y_axis_data[x][0]))
plt.savefig('{1}/{0}.jpg'.format(科目名称[i],username))
plt.close()
y_axis_data=[]
# 按列读取
data_col = [sheet_1.col_values(i) for i in range(sheet_1.ncols)]
# 按行读取
data_row = []
for row in range(sheet_1.nrows):
data_row.append(sheet_1.row_values(row))
# print(data_col)
#删除第一横排第一项:姓名
data_row[0].pop(0)
# 设置全班名字,删除第一竖排第0项‘姓名’
allname = data_col[0]
allname.pop(0)
科目 = ['yuwen', 'shuxue', 'yingyu', 'zhengzhi', 'lishi', 'dili', 'shenngwu', 'wuli','zongfen']
科目name = tuple(data_row[0])
各科成绩排名 = []
科目字典 = data_row[0]
各科全班平均分=[]
各科分段平均分=[]
print(科目name)
for i in range(9):
# 读取各科成绩单
科目[i] = data_col[i + 1]
#删除此列第一项(第一项为科目名称,转为纯数字列表来排序)
科目[i].pop(0)
#排序
各科成绩排名.append(sorted(科目[i], reverse=True))
# 把姓名与各科成绩结合成字典
科目[i] = zip(allname, 科目[i])
# yuwen.sort(reverse = True)
科目[i] = dict(科目[i])
科目字典[i] = dict(科目[i])
科目[i] = sorted(科目[i].items(), key=lambda x: x[1], reverse=True)
#计算平均分
各科目成绩 = data_col[i+1]
各科全班平均分.append(sum(各科目成绩) / len(allname))
# print(科目name[i],科目[i])
# print(各科成绩排名)
个人各科成绩 = list(科目name)#读取各个科目
个人各科成绩排名 = []
所处分段=0
username = input("请输入您的姓名")
if username in allname:
print('查询到以下结果')
#处理各科分数
for i in range(9):
#print(科目字典)
#读取个人各科成绩,前面已经准备好各人对应的各科成绩
个人各科成绩[i] = 科目字典[i].get(username)
#将个人各科排名添加进列表
个人各科成绩排名.append(各科成绩排名[i].index(个人各科成绩[i]))
print(科目name[i], 个人各科成绩[i])
#处理分段分数
#获取个人分段
所处分段 = (个人各科成绩排名[-1] + 1) // 10
for i in range(9):
#计算平均分
各科目成绩 = data_col[i+1][(所处分段)*10:(所处分段+1)*10+1]
#print(各科目成绩)
#print((所处分段)*10,(所处分段+1)*10)
各科分段平均分.append(sum(各科目成绩) / len(各科目成绩))
# print(科目name)
# print()
# print(个人各科成绩)
# 创建文件夹
# 调用函数
file = "{0}".format(username)
创建文件夹(file)# 这些都是函数!!!!!!!!!!
饼状图() #为了方便直观直接以中文定义
保存分段与个人对比()
各科全班与分段对比()
折线图()
else:
print('对不起,没有找到相关学生')
# print(个人各科成绩排名)
作品,文章著作权属作者本人,未经允许不得转载