zoukankan      html  css  js  c++  java
  • 成绩单生成软件使用教程

    前言

    太困了,索性写一个朴实无华的教程

    介绍

    功能

    • 提取专业课程列表,以选择要生成的所有专业课
    • 根据已选的专业课计算出每个学生的平均成绩,进行排序
    • 英语快班成绩*1.1
    • 对等级评定(优、良、中、及格)能够转换成分数(90、80、70、60)
    • 只能根据单个专业原始成绩表生成该专业的成绩排名
    • 生成的排名表含有各个课程的学分,方便用Excel进行人工核算

    开发工具

    使用python开发,主要使用xlrd、xlwt、tkinter等模块进行开发,代码简单,逻辑较清楚。

    作者

    一个名不见经传、心怀恪尽职守、疼爱助理(自己)的颇享受成就感的辅导员助理。

    使用

    用前须知

    开发过程中处理的原始文件格式如下:

    生成的成绩排名如下:

    空白处的地方是该学生没有这门课程,在计算平均成绩时也不会算入
    (可能的原因就是这门课是其他同学补修或重修来的,在选择课程时选中了它,而其他同学这门课程已经学过了。但该补修或重修同学的总成绩需要计入该课程)

    开始使用

    打开软件:

    1. 点击1处按钮,弹出对话框
    2. 在对话框选择原始excel文件,确认打开,完成第2步
    3. 点击3处按钮载入excel文件
    4. 在“选择要生成的科目”一栏中选择课程 公选课不计入成绩排名中,所以要筛选出必修课
    5. 在“选择英语快班所学的课程”一栏中选择快班学的大英课程 快班英语成绩要乘1.1
    6. 点击6处按钮,在同文件夹下生成专业成绩排名表,成功后会弹出成功对话框

    代码

    附上代码,希望给帮助到命中注定的人,如有问题可以联系博主哦!
    UI.py

    # -*- coding: utf-8 -*-
    """
    Created on Fri Aug 28 16:23:58 2020
    
    @author: DragonBean
    
    description:整个排版用固定像素值来排,通过设置width保证课程名称长的课只显示一部分,保证不打乱布局
    """
    
    import tkinter as tk
    from tkinter import ttk
    
    def openFile():
        import tkinter.filedialog    #必须有
        
        global filename
        filename = tk.filedialog.askopenfilename()
        if filename != '':
            filePath.set(filename)
            frame1.config(text="选择的Excel文件是:")
        else:
            filePath.set('没有选择任何文件')
    
    def loadFile():
        global filename,major
        import getExcel as get
        if not filename:
            filePath.set('请先选择文件')
        else :
            try:
                raw_titleList,raw_lessonList,major = get.getPreData(filename)
                frame1.config(text="文件导入成功")
                set_checkbox(raw_titleList, raw_lessonList)
            except:
                filePath.set('文件有误,请重新选择或联系开发人员')
    
    def set_checkbox(raw_titleList, raw_lessonList):
        for widget in frame2.winfo_children():
            widget.destroy()
        for widget in frame3.winfo_children():
            widget.destroy()
        
        for i in range(len(raw_titleList)):
            tmpVar = tk.IntVar()
            title = raw_titleList[i]
            ttk.Checkbutton(frame2, text=title, width=10, variable=tmpVar, onvalue=1, offvalue=0).grid(row=i//8, column=i%8, padx=5, pady=5)
            
            titleList.append(tmpVar)
        for i in range(len(raw_lessonList)):
            tmpVar = tk.StringVar()
            text = raw_lessonList[i]
            ttk.Checkbutton(frame3, text=text, width=35, variable=tmpVar, onvalue=text, offvalue="").grid(row=i//6, column=i%6, padx=5, pady=5)
            
            #把变量加进去 (带顺序)
            lessonValue.append(tmpVar)
    
    def doExcel():
        def close():
            successwin.destroy()
        global filename, major, english, lessonValue
        import getExcel as get
        import setExcel as write
        import os
        print(os.path.split(filename)[0])
        new_filename = os.path.split(filename)[0] + "/" + major + "成绩单.xls"
        if english.get() == 2:
            specialLesson = "大学英语(2)"
        elif english.get() == 3:
            specialLesson = "大学英语(3)"
        elif english.get() == 4:
            specialLesson = "大学英语(4)"
        else: specialLesson = None
        lessons = []
        for each in lessonValue:
            if each.get() != "":
                lessons.append(each.get())
        try:
            data = get.getAllData(filename, lessons)
            write.writeData(new_filename, major, lessons, data, specialLesson)
            successwin = tk.Toplevel()
            successwin.title("生成成功")
            successwin.geometry("%dx%d+%d+%d" %(400, 150, (width-400)/2, (height-150)/2))
            ttk.Label(successwin, text='成绩排名生成成功 
    
    文件路径为:
       ' + new_filename ).grid(row=0, padx=30, pady=10)
            ttk.Button(successwin, text="确定", command=close).grid(row=1, padx=30, pady=10)
        except:
            falsewin = tk.Toplevel()
            falsewin.title("错误")
            falsewin.geometry("%dx%d+%d+%d" %(350, 130, (width-350)/2, (height-130)/2))
            ttk.Label(falsewin, text='程序执行有误 
     建议重新启动程序 
     如果还不行,请联系作者QQ:509931598 注明来由').grid(row=0, padx=30, pady=30)
        
    def showHelp():
        helpwin = tk.Toplevel()
        helpwin.title("Help")
        helpwin.geometry("%dx%d+%d+%d" %(450, 150, (width-450)/2, (height-150)/2))
        ttk.Label(helpwin, text='详细使用教程请查看博客:').grid(row=0, padx=30, pady=10)
        url = ttk.Entry(helpwin, width=50)
        url.grid(row=1, padx=30, pady=10)
        url.insert(tk.END,'https://www.cnblogs.com/dragonbean/p/13611488.html')
        ttk.Label(helpwin, text='密码:123456 
     by DragonBean').grid(row=3, padx=30, pady=10)
    
    global filename,lessonValue,major
    filename = ''
    lessonValue = []
    titleList = [] #IntVar序列 0,1
    
    window = tk.Tk()
    window.title("成绩表单生成系统")
    width, height = window.maxsize()
    window.geometry("%dx%d+%d+%d" %(width*0.9, height*0.9, width*0.05, height*0.01))
    #window.resizable(width=False,height=False)
    window.rowconfigure(0,weight=1)
    window.rowconfigure(1,weight=2)
    window.rowconfigure(2,weight=3)
    window.rowconfigure(3,weight=1)
    window.columnconfigure(0,weight=1)
    
    frame1 = ttk.LabelFrame(window, text="选择Excel文件")
    frame2 = ttk.LabelFrame(window, text="选择要生成的内容")
    frame3 = ttk.LabelFrame(window, text="选择要生成的科目")
    frame4 = tk.Frame(window, padx=5,pady=5)
    
    frame1.columnconfigure(0,weight=1)
    frame4.rowconfigure(0, weight=1)
    frame4.columnconfigure(0, weight=1)
    
    frame1.grid(row=0,column=0, sticky=tk.EW, padx=5, pady=5)
    frame3.grid(row=2,column=0, sticky=tk.NSEW, padx=5, pady=5)
    frame4.grid(row=3,column=0, sticky=tk.EW, padx=5, pady=5)
    
    #frmae1
    filePath = tk.StringVar()
    text = ttk.Entry(frame1, textvariable=filePath, state="readonly")
    text.grid(row=0,sticky=tk.EW, padx=5, pady=5)
    selectButton = ttk.Button(frame1, text='···', command=openFile)
    importButton = ttk.Button(frame1, text='载入', command=loadFile)
    selectButton.grid(row=0, column=1, padx=2, pady=2)
    importButton.grid(row=0, column=2, padx=2, pady=2)
    
    #frame2
    #frame3
    #frame4
    frame4_4 = ttk.LabelFrame(frame4, text="选择英语快班所学的课程")
    frame4_4.grid(row=0,column=0, sticky=tk.EW, padx=5, pady=5)
    english = tk.IntVar()
    ttk.Radiobutton(frame4_4, text="大学英语2", variable=english, value=2).grid(row=0,column=0,padx=10,pady=2)
    ttk.Radiobutton(frame4_4, text="大学英语3", variable=english, value=3).grid(row=0,column=1,padx=10,pady=2)
    ttk.Radiobutton(frame4_4, text="大学英语4", variable=english, value=4).grid(row=0,column=2,padx=10,pady=2)
    
    ttk.Button(frame4, text="生成表单", command=doExcel).grid(row=0, column=1, padx=5, pady=10)
    ttk.Button(frame4, text="帮助", command=showHelp).grid(row=0, column=2, padx=5, pady=10)
    
    window.mainloop()
    

    getExcel.py

    # -*- coding: utf-8 -*-
    """
    Created on Wed Sep  2 10:50:07 2020
    
    @author: DragonBean
    
    description: 接收excel文件,
                    传出表头title                   [表头1,表头2,....]
                    传出专业和课程列表               专业&[课程1,课程2,课程3,...]
                传入筛选后的表头和课程,读取excel数据,
    #                传出整个数据(新的数据格式:
    #                    {20182*****:{学号:'20182*****',
    #                                  姓名:'***',
    #                                  班级:**班,
    #                                  课程1:[成绩,学分],
    #                                  课程2:[成绩,学分],
    #                                  ...},
    #                     20182*****:{学号:}}},...}
    """
    
    import xlrd
    
    def open_file(filename):
        book = xlrd.open_workbook(filename)
        sheet = book.sheet_by_index(0)
        return sheet
    
    def getPreData(filename):
        titleList = []
        lessonSet = set()
        sheet = open_file(filename)
        row = sheet.row(0)                      #获取表头所在行
        for each in row:
            titleList.append(each.value)
        
        column = sheet.col(4)                   #获取课程所在列
        x = 1
        for each in column:
            #去除第一行的表头
            if x == 1:
                x += 1
                continue
            lessonSet.add(each.value)
        
        major = sheet.row(1)[9].value
        
        data = [titleList,list(lessonSet),major]
        return data
    
    def getAllData(filename, lessons):
        data = dict(dict())
        studentIDSet = set()
        sheet = open_file(filename)
        for i in range(1, sheet.nrows):
            row = sheet.row(i)
            
            studentID = row[0].value            #学号
            studentName = row[1].value          #名字
            lesson = row[4].value               #课程
            classes = row[10].value             #班级
            grade = row[16].value               #成绩
            credit = row[13].value              #学分
            if studentID not in studentIDSet:
                studentIDSet.add(studentID)
                data[studentID] = {'学号':studentID,'姓名':studentName,'班级':classes}
            if lesson in lessons:
                data[studentID][lesson] = [grade, credit]
    
        return data
    

    setExcel.py

    # -*- coding: utf-8 -*-
    """
    Created on Thu Sep  3 10:26:43 2020
    
    @author: DragonBean
    
    description: 传入数据 data                  
                        {20182*****:{学号:'20182*****',
                                      姓名:'***',
                                      班级:**班,
                                      课程1:[成绩,学分],
                                      课程2:[成绩,学分],
                                      ...},
                         20182*****:{学号:}}},...}
                把数据按顺序写到一个列表里,根据平均成绩排序,然后写入表格
                输出一个excel表格
    """
    import xlwt
    
    def open_file(filename, major):
        book = xlwt.Workbook()
        sheet = book.add_sheet(major)
        
        al = xlwt.Alignment()
        al.horz = xlwt.Alignment.HORZ_CENTER
        al.vert = xlwt.Alignment.VERT_CENTER
        borders = xlwt.Borders()
        borders.top = borders.THIN
        borders.right = borders.THIN
        borders.bottom = borders.THIN
        borders.left = borders.THIN
        style = xlwt.XFStyle()
        style.borders = borders
        style.alignment = al
        
        return(book, sheet, style)
        
    def is_num(string):
        try:
            float(string)
            return True
        except:
            return False
    
    def generate_list(titleList, lessons, data, specialLesson):
        allDataList = []
        #creditList : [["课程1",2.0],["课程2",3.0],["课程3",2.5],......]
        creditList = [[lesson,0] for lesson in lessons]
        studentList = list(data.values())
        for i in range(len(studentList)):
            dataList = []
            student = studentList[i]            #获取单个学生的数据 :字典
            
            studentGrade = 0.0
            studentCredit = 0.0
            for j in range(len(titleList)):
                key = titleList[j]              #课程名称
                if key in ['学号','姓名','班级']:
                    dataList.append(student[key])
                elif key in lessons :
                    value = student.get(key)
                    #处理没有该该学生没有该课程的情况
                    if value == None:
                        grade = ""
                        credit = 0
                    else :
                        grade,credit = value
                    dataList.append(grade)
                    
                    #将成绩的字符串转换成成绩数值,同时处理未考情况
                    if is_num(grade):
                        grade = float(grade)
                    elif grade == '优':
                        grade = 90
                    elif grade == '良':
                        grade = 80
                    elif grade == '中':
                        grade =70
                    elif grade == '及格':
                        grade = 60
                    else :
                        grade = 0;
                    
                    #特殊的课程(英语快班*1.1) 处理了快班英语上完的情况
                    if specialLesson!=None and key==specialLesson:
                        grade = grade*1.1
                    
                    #计算总成绩 和 总学分
                    studentGrade += grade*float(credit)
                    studentCredit += float(credit)
                    creditList[lessons.index(key)][1] = credit
                    
                elif key == '平均成绩':
                    dataList.append(studentGrade/studentCredit if studentCredit!=0 else 0)      #排除一种异常:该学生一门课都没有上过
            allDataList.append(dataList)
        creditData = [each[1] for each in creditList]
        return [creditData,allDataList]
    
    def save_excel(filename, book):
        book.save(filename)
    
    def writeData(filename, major, lessons, data, specialLesson):
        book,sheet,style = open_file(filename, major)
        titleList = ['学号','姓名','班级'] + lessons + ['平均成绩','排名']
        
        #写表头
        sheet.write_merge(0, 0, 0, len(titleList)-1, '管理学院' + major + '成绩', style=style)
        for i in range(len(titleList)):
            sheet.write_merge(1, 3, i, i, titleList[i], style=style)
        
        #获取数据:学分列表 和 每个学生的表格数据
        creditList,raw_dataList = generate_list(titleList, lessons, data, specialLesson)
        
        for i in range(len(creditList)):
            sheet.write_merge(4, 4, i+3, i+3, creditList[i], style=style)
    
        raw_dataList.sort(key = lambda x:x[-1], reverse=True)                       #根据平均成绩 进行降序排序
        new_dataList = [each+[index+1] for index,each in enumerate(raw_dataList)]   #添加排名
        
        #写入数据进表格
        for i in range(len(new_dataList)):
            row = sheet.row(i + 5)
            row_data = new_dataList[i]
            for j in range(len(row_data)):
                row.write(j, row_data[j], style=style)
        
        save_excel(filename, book)
    

    文章转自Dragonbean
    https://www.cnblogs.com/dragonbean/p/13611488.html

  • 相关阅读:
    Handsontable添加超链接
    Handsontable 筛选事件
    handsontable自定义渲染
    M1 Mac安装 Homebrew
    Pypi官网怎么找历史依赖包
    在 CentOS7 中我们在安装 MySQL
    Ansible使用yum安装
    Ansible集群自动化运维操作
    java对list中map集合中某个字段排序
    使用hive的orcfiledump命令查看orc文件
  • 原文地址:https://www.cnblogs.com/dragonbean/p/13611488.html
Copyright © 2011-2022 走看看