00問題提出
2020年,由於新冠疫情(Coronavirus-19)的影響, 2020年春季學期各班信號與系統期末考試 採用了網絡考試的方式,同學將試卷上載的清華網絡學堂之後。然後在統一下載。
信號與系統試卷 總共有八道試題,總分100分,考試過程進行了兩小時15分鐘。
批改試卷的過程就是通過閱讀上載的電子文檔,然後將八道題的題目給出分數,然後登錄到學生成績EXCEL中。隨着批改試卷過程,判定分數的過程會越來熟練,但是將分數登錄到EXCEL格過程則會出現一定的困難:
- 在EXCEL表各種找到對應的學生條目困難
- 在八個分數格內錄入八個數字比較繁瑣
下面通過PYTHON命令完成自動程序錄入過程,PYTHON 程序完成以下功能:
- 根據當前WINDOW下各窗口是否包含有學生ID字符串,自動獲取當前批改學生的ID;
- 等待輸入八個小題分數;
- 根據ID,將對應EXCEL表格中學生ID相同的一欄輸入八個小題分值。
01信息的前處理
對於學生的信息進行一下處理:
1. 生成學生學號與姓名TEXT文件
具體過程參照: 2020信號與系統課程學生信息轉換。
2. 下載學生答案答辯文件並加壓縮
將加壓縮後的文件進行名稱轉換。
具體過程參照: 2020信號與系統課程學生信息轉換。
▲ 將解壓文件進行名稱轉換
文件名稱轉換PYTHON程序:
#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# FILENAMECHANGE.PY -- by Dr. ZhuoQing 2020-06-19
#
# Note:
#============================================================
from headm import *
from inforsub import *
#------------------------------------------------------------
siau = text2infor(ssau)
sixy = text2infor(ssxy)
#------------------------------------------------------------
filedir = tspstring2text('ssxy')
printf(filedir)
filedim = os.listdir(filedir)
filenew = [(f.split('_')[0], os.path.splitext(f)[-1]) for f in filedim]
fileout = []
changecount = 0
for id,f in enumerate(filenew):
name = sixy[f[0]]
fo = '%s_%s%s'%(f[0],name,f[1])
fold = os.path.join(filedir, filedim[id])
fnew = os.path.join(filedir, fo)
if os.path.isfile(fold):
os.rename(fold, fnew)
changecount = changecount + 1
printf('Change:%d\a'%changecount)
#------------------------------------------------------------
# END OF FILE : FILENAMECHANGE.PY
#============================================================
3. 創建學生成績EXCEL文件
這部分根據網絡學堂下載所有學生的信息,並生成對應的EXCEL文件。
在EXCEL文件中重新生成一個表單“Exam”:
表單第一行爲表頭;表單前兩列分別是ID和姓名。格式如下:
▲ 記錄成績的EXCEL表單結構
爲了能夠適應PYTHON對EXCEL處理,EXCEL表格的格式需要通過EXCEL另存爲修改成.XLSX的格式。
02自動成績錄入PYTHON程序
1. 功能介紹
在此過程中需要對程序中的前面的變量進行正確的設置:
xyinfor = text2infor(ssxy)
auinfor = text2infor(ssau)
xyexcel = r'D:\Teaching\SignalsSystems\SS2020S\Examination\Excel\SSXY-SCORE.xlsx'
auexcel = r'D:\Teaching\SignalsSystems\SS2020S\Examination\Excel\SSAU-SCORE.xlsx'
這個程序可以自動根據學生ID號在判斷對哪一個EXCEL文件進行修改。
在運行程序之前,先打開一個學生答案文件,可以是PDF,WORD,ZIP文件
(1) score (無參數): 顯示當前學生的成績信息
(2) score n1 n2: 對當前學生的第n1道題目的分數修改成n2
(3) score n1 n2 n3 n4 n5 n6 n7 n8 :
將當前評閱學生的八道題目的成績錄入。
2. 程序實現
#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# SCORE.PY -- by Dr. ZhuoQing 2020-06-19
#
# Note:
#============================================================
from head import *
from inforsub import *
#------------------------------------------------------------
xyinfor = text2infor(ssxy)
auinfor = text2infor(ssau)
xyexcel = r'D:\Teaching\SignalsSystems\SS2020S\Examination\Excel\SSXY-SCORE.xlsx'
auexcel = r'D:\Teaching\SignalsSystems\SS2020S\Examination\Excel\SSAU-SCORE.xlsx'
if len(xyinfor) == 0:
printf("No student infor.\a")
exit()
if len(auinfor) == 0:
printf("No student infor.\a")
exit()
if os.path.isfile(xyexcel) == False:
printf("No output excel file.%s"%excelfile)
exit()
if os.path.isfile(auexcel) == False:
printf("No output excel file.%s"%excelfile)
exit()
#------------------------------------------------------------
printf('')
#------------------------------------------------------------
idstr = ''
namestr = ''
excelfile = ''
idsamecount = 0
title = tspgetwindowtitle()
for t in title:
ts = t.split('_')
if len(ts) < 2: continue
if ts[0] in xyinfor:
idstr = ts[0]
namestr = xyinfor[idstr]
excelfile = xyexcel
idsamecount = idsamecount + 1
printf('%s_%s:%s\a'%(idstr, namestr, excelfile))
# break
if ts[0] in auinfor:
idstr = ts[0]
namestr = auinfor[idstr]
excelfile = auexcel
idsamecount = idsamecount + 1
printf('%s_%s:%s\a'%(idstr, namestr, excelfile))
# break
if idsamecount != 1:
printf("ERROR: idsame count : %d.\a"%idsamecount)
exit()
#if len(idstr) == 0:
# printf("ERROR: No find id string.\a")
# exit()
#printf('%s_%s:%s\a'%(idstr, namestr, excelfile))
#------------------------------------------------------------
if len(sys.argv) < 3:
# printf("Usage: score s1 s2 s3....")
showexcelcell(excelfile, int(idstr))
exit()
if len(sys.argv) == 3:
scoreid = int(sys.argv[1])
score = float(sys.argv[2])
if scoreid < 1 or scoreid > 8:
printf("Score id ERROR.\a")
exit()
setexcelcell(excelfile, int(idstr), scoreid, score)
printf('\a')
exit()
#------------------------------------------------------------
if len(sys.argv) != 9:
printf("Usage: score s1 s2 ...s8\a")
exit()
scoredim = []
for s in sys.argv[1:]:
scoredim.append(float(s))
printf(scoredim)
setexcelcells(excelfile, int(idstr), scoredim)
printf('Total:%5.2f\a'%sum(scoredim))
#------------------------------------------------------------
# END OF FILE : SCORE.PY
#============================================================
#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# INFORSUB.PY -- by Dr. ZhuoQing 2020-06-18
#
# Note:
#============================================================
from headm import *
import pandas as pd
#------------------------------------------------------------
ssau = 2
ssxy = 3
#------------------------------------------------------------
def text2infor(fileid):
filename = tspgetdopfile(fileid)
# printf(filename)
studentdict = {}
with open(filename, 'r', encoding='gbk') as f:
for l in (f.readlines()):
l.rstrip('\n')
lsect = l.split()
if lsect[0] == '學號':
continue
studentdict[lsect[0]] = lsect[1]
return studentdict
#------------------------------------------------------------
def setexcelcell(filename, sid, col, num):
excelfile = pd.read_excel(filename, sheet_name='Exam')
listdata = excelfile.values.tolist()
rowid = -1
for id,l in enumerate(listdata):
if l[0] == sid:
rowid = id
printff(id, listdata[id])
break
if rowid < 0:
printf("ERROR: Can not find %d in %s.\a"%(sid, filename))
return
excelfile.iat[rowid, col+1] = num
listdata = excelfile.values.tolist()
printff(rowid, listdata[rowid], sum(listdata[rowid][2:]))
excelfile.to_excel(filename, sheet_name='Exam', index=False)
#------------------------------------------------------------
def showexcelcell(filename, sid):
excelfile = pd.read_excel(filename, sheet_name='Exam')
listdata = excelfile.values.tolist()
if sid == 0:
for l in listdata:
s = '%s %d'%(str(l), sum(l[2:]))
ss = s.replace('\'', '')
ss = ss.replace('[', '')
ss = ss.replace(']', '')
ss = ss.replace(',', '')
printf(ss)
return
#--------------------------------------------------------
rowid = -1
for id,l in enumerate(listdata):
if l[0] == sid:
rowid = id
printff(id, listdata[id],sum(listdata[id][2:]))
break
if rowid < 0:
printf("ERROR: Can not find %d in %s.\a"%(sid, filename))
return
#------------------------------------------------------------
def setexcelcells(filename, sid, num):
excelfile = pd.read_excel(filename, sheet_name='Exam')
listdata = excelfile.values.tolist()
rowid = -1
for id,l in enumerate(listdata):
if l[0] == sid:
rowid = id
printff(id, listdata[id])
break
if rowid < 0:
printf("ERROR: Can not find %d in %s.\a"%(sid, filename))
return
for id, n in enumerate(num):
excelfile.iat[rowid, id+2] = n
listdata = excelfile.values.tolist()
printff(rowid, listdata[rowid], sum(listdata[rowid][2:]))
excelfile.to_excel(filename, sheet_name='Exam', index=False)
#------------------------------------------------------------
if __name__ == "__main__":
filename = r'D:\Teaching\SignalsSystems\SS2020S\Examination\Excel\SSXY-SCORE.xlsx'
setexcelcell(filename, 2017013661, 1, 10)
'''
si = text2infor(ssau)
printff(len(si), si)
si = text2infor(ssxy)
printff(len(si), si)
'''
#------------------------------------------------------------
# END OF FILE : INFORSUB.PY
#============================================================
■ 結論
通過該程序,可提高試卷批改的速度,減少成績錄入過程中的錯誤。