Bootstrap

Python实现学生成绩分析

第一步 生成月考成绩表
第二步 生成学生成绩总表
第三步 数据分析
第三步 数据呈现
第四步 自动生成word报告

"""
实现生成12个月份10名同学成绩的随机数
"""
import random
from openpyxl import Workbook

#新建空表
#写二月份到十二月份数据
filenum = 12 #文件数
head = ["姓名","语文","数学","英语","地理","生物","物理","化学"]



name = []
grad = []
all_name = []
nber = 11 #人数
p = 1

xing = ['赵', '钱', '孙', '李', '周', '吴', '郑', '王', '冯', '陈', '褚', '卫', '蒋', '沈', '韩', '杨']
ming = ['明','刚','红','越','芳','花','颖','鹏','柯','心','航','睿']
#把名字写入文件
def writename(number):
	for i in range(1,number):
		name = xing[random.randint(0,len(xing)-1)]+ming[random.randint(0,len(ming)-1)]
		#ws.cell(row=i+1,column=1).value = name
		all_name.append(name)
	return all_name

#把分数写入文件
def writescore(number):
	for i in range(1,number):
		for j in range(2,len(head)+1):
			grad = random.randint(int(random.gauss(65,6)),100)
			ws.cell(row=i+1,column=j).value = int(grad)


#存储数据,写入文件
def savedata(sheet,lsts):
	for i in range(1,len(lsts)+1):
		ws.cell(row=i+1,column=1).value = lsts[i-1]
		

#批量写文件
for i in range(1,filenum+1):
	wb = Workbook()
	ws = wb.active	
	#生成表名和表头
	ws.title = str(i)+"月份成绩"
	ws.append(head)
	if p == 1: 
		wname = writename(nber)
		p = 0
	print(wname)
	savedata(ws,wname)
	writescore(nber)
	wb.save("./crtdata/"+str(i)+"月份成绩表.xlsx")
#获取输入字符串所在行的数据
from openpyxl import Workbook
from openpyxl import load_workbook

import numpy as np
import os
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['Arial Unicode MS']

filepath = "/Users/hangyang/Documents/python_work/crtdata/"
dirs = os.listdir(filepath)

filepath1 = "/Users/hangyang/Documents/python_work/学生情况1/"

filepath2 = "/Users/hangyang/Documents/python_work/学生情况2/"

filepath3 = "/Users/hangyang/Documents/python_work/学生成绩/"

head = ["姓名","语文","数学","英语","地理","生物","物理","化学"]
pie_head = ["语文","数学","英语","地理","生物","物理","化学"]
pie_month = ["1月份","2月份","3月份","4月份","5月份","6月份","7月份","8月份","9月份","10月份","11月份","12月份"]

#获取相同信息所在行数据
def getsameinfo(sheet,st1,rows,cols):
	lst = []
	for i in range(1,rows+1):
		for j in range(1,cols+1):
			if str(sheet.cell(row=i,column=j).value) == st1:
				for k in range(j,cols+1):
					cel = sheet.cell(row=i,column=k).value
					lst.append(cel)
				return lst

#获取相同信息所在列数据
def getsamecolumninfo(sheet,st1,rows,cols):
	lst = []
	for i in range(1,rows+1):
		for j in range(1,cols+1):
			if str(sheet.cell(row=i,column=j).value) == st1:
				for k in range(i+1,rows+1):
					cel = sheet.cell(row=k,column=j).value
					lst.append(cel)
				return lst

#存储数据,写入文件
def writedata(sheet,lsts,tmp):
	for data in lsts:
		for j in range(1,len(data)+1):
			sheet.cell(row=tmp,column=j).value = data[j-1]
		tmp=tmp+1
	return tmp

#获取人名
def getstudentname(path,dir):
	wkbk = load_workbook(path+dir[0])
	wkst = wkbk.active
	rows = wkst.max_row
	cols = wkst.max_column
	student = getsamecolumninfo(wkst,"姓名",rows,cols)
	return student

#打开Excel文件,获取相同信息并保存
def deal2save_Excel(filepath,dirs,info):
	lst2 = []
	for d in dirs:
		if d.split(".")[1] in ["xlsx","xls"]:
			wb1 = load_workbook(filepath+d)
			ws1 = wb1.active
			rows = ws1.max_row
			cols = ws1.max_column
			lst1 = getsameinfo(ws1,info,rows,cols)
			lst2.insert(1,lst1)
		elif d in ["DS_Store"]:
			os.remove("DS_Store")
	return lst2

#根据人名创建sheet存储分类后的数据
def classifyasname_single(path,dirs,stu):
	#按学生名新建sheet
	wb = Workbook()
	ws = wb.active	
	ws.append(head)
	#按学生名新建多个空sheet
	for name in stu:
		wb.create_sheet(name)
	wb.remove(wb['Sheet'])
	
	#把学生数据写入sheet
	ID = 0
	tmp = 2
	for i in wb.sheetnames:
		ws = wb[i]
		ws.append(head)
		lst = deal2save_Excel(path,dirs,stu[ID])
		ID = ID+1
		#print("[classifyasname_single函数]:\n",lst)
		tmp = writedata(ws,lst,tmp)
		tmp = 2
		ws.delete_cols(idx=1,amount=1)	
		ws.insert_cols(idx=1,amount=1)
		for h in range(1,ws.max_row):
			ws.cell(h+1,1).value = str(h)+"月"
		ws.cell(1,1).value = "月份"
	wb.save("./学生情况2/"+"学生情况.xlsx")
	wb.close()


#保存数据到Excel表的a行b列
def writesingleval(sheet,val,a,b):
	sheet.cell(row=a,column=b).value = val

#求单科平均分
def getavgscore(wb,ws):
	rows = ws.max_row
	cols = ws.max_column
	l_cols = list(np.arange(2,cols+1,1))
	x = 0
	for col in ws.iter_cols(min_row=2,min_col=2):
		for v in col:
			column_data = [v.value for v in col]
		avg = int(np.average(column_data))
		writesingleval(ws,avg,rows+1,l_cols[x])
		x = x+1
		#print("[countingscore函数求平均分]:\n",column_data,avg,l_cols[x-1])

#求每月总成绩
def getsumscore(wb,ws):
	rows = ws.max_row
	cols = ws.max_column
	l_rows = list(np.arange(2,rows+1,1))
	x = 0
	for row in ws.iter_rows(min_row=2,min_col=2):
		for v in row:
			row_data = [v.value for v in row]
		fsum = int(np.sum(row_data))
		writesingleval(ws,fsum,l_rows[x],cols+1)
		x = x+1
		#print(column_data,avg,l_cols[x-1])
	

#一个文件多个sheet计算平均分及总分
def countingscore_single():
	dirs2 = os.listdir(filepath2)
	for d in dirs2:
		if d.split(".")[1] in ["xlsx","xls"]:
			wb = load_workbook(filepath2+d)
			ws = wb.active
			ws.cell(1,1).value = "月份"
			for i in wb.sheetnames:
				ws = wb[i]
				print(ws)
				getavgscore(wb,ws)
				getsumscore(wb,ws)
				ws.cell(row=ws.max_row,column=1).value = "平均分"
				ws.cell(row=1,column=ws.max_column).value = "月考总分"
				wb.save("./学生成绩/学生成绩总表.xlsx")
			wb.close()
		elif d in [".DS_Store"]:
				print("loading... ",d.split(".")[1] in ["xlsx","xls"])
				os.remove("./学生情况2/.DS_Store")
	

#读取键盘输入


#画图
def studentcase_plot(name,course):
	print ("下面显示"+name+"所学科目"+course+"成绩的年变化曲线 〉〉〉")
	wb = load_workbook(filepath2+"学生情况.xlsx")
	ws = wb.active
	for i in wb.sheetnames:
		if i.split(".")[0] == name:
			ws = wb[i]
			rows = ws.max_row
			cols = ws.max_column
			m_score = getsamecolumninfo(ws,course,rows,cols)
			m_time = getsamecolumninfo(ws,"月份",rows,cols)
			print(name)
			print(m_score)
			print(m_time)
			plt.title(name+course+"成绩年变化曲线",fontsize=24)
			plt.xlabel("月份",fontsize=14)
			plt.ylabel("分数",fontsize=14)
			plt.tick_params(axis='both',labelsize=14)
			plt.bar(m_time,m_score)
			plt.savefig(name+course+"成绩.jpg")
			plt.show()
			plt.close()
		wb.close()

def  classcase_plot(course):
	print ("下面显示所有学生"+course+"年变化曲线 〉〉〉")
	wb = load_workbook(filepath2+"学生情况.xlsx")
	ws = wb.active
	for i in wb.sheetnames:
		ws = wb[i]
		rows = ws.max_row
		cols = ws.max_column
		m_score = getsamecolumninfo(ws,course,rows,cols)
		m_time = getsamecolumninfo(ws,"月份",rows,cols)
		plt.title("全班"+course+"成绩年变化图",fontsize=24)
		plt.xlabel("月份",fontsize=14)
		plt.ylabel("分数",fontsize=14)
		y_ticks = np.arange(-10,110,5)
		plt.yticks(y_ticks)
		plt.scatter(m_time,m_score)
		#plt.plot(m_time,m_score)
		print(ws)
		wb.close()
	plt.savefig(course+"班级成绩.jpg")
	plt.show()
	plt.close()

def monthly_score(monthly):
	wb = load_workbook(filepath+monthly+"成绩表.xlsx")
	ws = wb.active
	rows = ws.max_row
	cols = ws.max_column
	lst = []
	getavgscore(wb,ws)
	ws.cell(row=ws.max_row,column=1).value = "平均分"
	for i in range(2,cols+1):
		cel = ws.cell(row=ws.max_row,column=i).value
		lst.append(cel)
	dic = dict(zip(pie_head,lst))
	print(dic)
	dic_course = [key for key in dic]
	dic_averge = [value for value in dic.values()]
	plt.pie(dic_averge, labels=dic_course, autopct="%1.2f%%")
	plt.title(monthly+"各科成绩平均分占比", fontsize=24)
	plt.savefig(monthly+"各科成绩平均分占比.jpg")
	plt.show()
	wb.close()

def plotpicture(student_name,course_name):
	print("输出学生科目成绩...")
	studentcase_plot(student_name,course_name)
	print("输出班级科目成绩...")
	classcase_plot(course_name)
	print("输出月考总分...")
	monthly_score("1月份")

def countrate(month,course):
	wb = load_workbook(filepath+month+"成绩表.xlsx")
	ws = wb.active
	rows = ws.max_row
	cols = ws.max_column
	lst = getsamecolumninfo(ws,course,rows,cols)
	passnum = 0
	excellencenum = 0
	for j in lst:
		if j >= 60:
			passnum = passnum+1
		if j >= 90:
			excellencenum = excellencenum+1
	passrate = passnum/(rows-1)*100
	excellencerate = excellencenum/(rows-1)*100
	passnum = 0
	excellencenum = 0
	#print("passrate is:",passrate,"%")
	#print("excellencenum is:",excellencerate,"%")
	return [passrate,excellencerate]
		

def writeinfotodoc(month,course,sname):
	from docx import Document
	from docx.shared import Inches
	document = Document()
	document.add_heading('2022年度成绩分析',0)
	document.add_heading('一、全班整体情况分析')
	paragraph = document.add_paragraph('我校初三四班共有学生10人,本年度共进行12次月考,整体情况如下:')
	
	paragraph = document.add_paragraph()
	guide = paragraph.add_run("1、全班各科成绩年变化图")
	guide.style = 'Strong'
	paragraph = document.add_paragraph("显示了全班所有同学所有科目全年的分布图像,可以看出同学成绩主要集中分布的范围。")
	print("输出班级科目成绩...")
	classcase_plot(course)
	pic_shape = document.add_picture(course+'班级成绩.jpg',width=Inches(5.5))
	print("班级科目成绩输出完毕!!!")

	print("输出月考总分...")
	paragraph = document.add_paragraph()
	guide = paragraph.add_run("2、月考总分各科占比")
	guide.style = 'Strong'
	paragraph = document.add_paragraph("显示了各科在月考总分中所占比重,可以看出班级的优势和薄弱科目。")
	print("输出"+month+"各科分数占比...")
	monthly_score(month)
	pic_shape = document.add_picture(month+'各科成绩平均分占比.jpg',width=Inches(5.5))
	print("各科分数占比输出完毕!!!")

	passrate_lst = []
	excellentrate_lst = []	
	paragraph = document.add_paragraph()
	guide = paragraph.add_run("3、"+month+"各科成绩及格率及优秀率情况")
	guide.style = 'Strong'
	for cs in pie_head:
		value1 = float(countrate(month,cs)[0])
		passrate_lst.append(value1)
		value2 = float(countrate(month,cs)[1])
		excellentrate_lst.append(value2)
		paragraph = document.add_paragraph(str(cs)+'及格率(成绩大于60分):'+str(value1)+'%'+'		'+'优秀率(成绩大于90分):'+str(value2)+'%')


	document.add_heading('二、学生个人情况分析')
	paragraph = document.add_paragraph("以下为"+sname+"同学各科成绩年度统计数据")
	print("输出"+sname+"同学科目成绩...")
	for cs in pie_head:
		studentcase_plot(sname,cs)
		pic_shape = document.add_picture(sname+cs+'成绩.jpg',width=Inches(5.5))
	print("学生科目成绩输出完毕!!!")
	#导出Excel中的数据到word

	document.save("班级2022年度成绩分析报告.docx")
	
#主程序
stu = getstudentname(filepath,dirs)
print("create an excel file...saved in multi-sheet")
classifyasname_single(filepath,dirs,stu)
print("begin counting score...status is ok")
countingscore_single() 
#writeinfotodoc("1月份")


print("===========画图===========")
student_name = input("请输入待查询学生姓名:\n");
print ("你输入的内容是: ",student_name)
course_name = input("请输入待查询科目名称:\n");
print ("你输入的内容是: ",course_name)
month_value = input("请输入待查询月份,例如(1月份):\n");
print ("你输入的内容是: ",month_value)

#plotpicture(student_name,course_name)
writeinfotodoc(month_value,course_name,student_name)




;