歐建榮
摘要:作者提出了一種批量檢查中小學(xué)Python程序作業(yè)文件的算法并將其編寫成應(yīng)用軟件,在實(shí)現(xiàn)對(duì)Python程序作業(yè)文件高效檢查的同時(shí),將作業(yè)自動(dòng)評(píng)價(jià)分類。該方法檢查Python程序作業(yè)文件準(zhǔn)確率高達(dá)99%,能夠?qū)π畔⒓夹g(shù)教師批量檢查Python作業(yè)文件起到一定的幫助作用。
關(guān)鍵詞:檢查作業(yè);Python;mypy;最長(zhǎng)公共子序列
中圖分類號(hào):G434? 文獻(xiàn)標(biāo)識(shí)碼:A? 論文編號(hào):1674-2117(2023)15-0073-04
引言
學(xué)習(xí)Python程序設(shè)計(jì)能很好地鍛煉學(xué)生的邏輯能力和思維能力,但面對(duì)大量的Python程序作業(yè)文件,教師要花費(fèi)大量的時(shí)間去批改。在批改Python程序作業(yè)時(shí),教師要手動(dòng)打開Python程序并運(yùn)行,觀察是否有語法錯(cuò)誤、運(yùn)行結(jié)果是否正確,并與正確的程序?qū)Ρ鹊?。如果教師能利用程序編譯Python程序文件以自動(dòng)檢查程序是否有誤,并自動(dòng)檢查程序與正確程序的相似度,然后對(duì)其進(jìn)行評(píng)價(jià)分類,大致得出Python程序作業(yè)是屬于優(yōu)秀作業(yè)還是亂做作業(yè)等,則能高效且及時(shí)地掌握學(xué)生的學(xué)習(xí)情況。因此,筆者結(jié)合Python程序的特點(diǎn),提出了一種批量自動(dòng)檢查Python程序文件的方法,旨在提高教師檢查作業(yè)的效率,并使學(xué)生得到及時(shí)反饋,提高教學(xué)效率。
技術(shù)簡(jiǎn)介
1.mypy
mypy是Python靜態(tài)類型檢查工具,可以檢查Python程序文件在編寫內(nèi)容和邏輯上是否有誤。mypy工具的安裝極為簡(jiǎn)單,安裝命令為:python -m pip install mypy。筆者利用QProcess啟動(dòng)外部程序的方式啟動(dòng)mypy并從其標(biāo)準(zhǔn)輸出通道中讀取全部的輸出信息,通過輸出信息去判斷Python程序是否有誤。
2.最長(zhǎng)公共子序列算法
給定一個(gè)長(zhǎng)度為n的序列A和一個(gè)長(zhǎng)度為m的序列B,求出一個(gè)最長(zhǎng)的序列,使得該序列既是A的子序列,也是B的子序列,這就是最長(zhǎng)公共子序列問題。最長(zhǎng)公共子序列算法是一個(gè)非常實(shí)用且被廣泛應(yīng)用的算法,適合于求解兩個(gè)文本之間的相似度。
筆者利用動(dòng)態(tài)規(guī)劃的方法實(shí)現(xiàn)求解最長(zhǎng)公共子序列,首先將原問題分割成一些子問題,用L[i][j]表示A的前i個(gè)元素、B的前j個(gè)元素的最長(zhǎng)公共子序列的長(zhǎng)度,這時(shí)的最長(zhǎng)公共子序列的長(zhǎng)度就是子問題。L[i][j]就是狀態(tài),L[n,m]則是最終要達(dá)到的狀態(tài),即為所求結(jié)果。其中Ai代表序列A的前i個(gè)字符組成的序列,Bj代表序列B的前j個(gè)字符組成的序列。A[x]代表序列A的第x個(gè)字符,i>0;B[y]代表序列B的第y個(gè)字符,j>0。L[i][j]代表序列Ai與序列Bj的最長(zhǎng)公共子序列的長(zhǎng)度,其公式如下頁圖1所示。
依據(jù)最長(zhǎng)公共子序列,求序列A和序列B的相似度,其公式如下頁圖2所示。
實(shí)驗(yàn)數(shù)據(jù)
筆者采用的實(shí)驗(yàn)數(shù)據(jù)為所在學(xué)校八年級(jí)學(xué)生的2565份Python程序作業(yè)文件,這些文件均為學(xué)生課堂上即時(shí)完成的作業(yè)。
實(shí)驗(yàn)過程
批量檢查Python作業(yè)系統(tǒng)界面設(shè)計(jì)如圖3所示,首先選擇需要檢查作業(yè)的班級(jí),其次選擇該班級(jí)所對(duì)應(yīng)的作業(yè)目錄和作業(yè)答案目錄,然后點(diǎn)擊“全部作業(yè)”按鈕,即可批量自動(dòng)檢查作業(yè),檢查的結(jié)果記錄顯示在中間列表處,其信息包括文件名、時(shí)間、大小、相似度,雙擊列表中的文件可以打開對(duì)應(yīng)的文件。除了對(duì)Python作業(yè)進(jìn)行評(píng)價(jià)分類外,該系統(tǒng)還具備按作業(yè)文件名稱或按作業(yè)文件內(nèi)容去查找某個(gè)作業(yè)文件及語音播報(bào)等功能,方便教師對(duì)作業(yè)的查看。
批量檢查Python作業(yè)系統(tǒng)是在Qt Creator集成開發(fā)環(huán)境下開發(fā)實(shí)現(xiàn),實(shí)驗(yàn)中利用到Qt Creator的內(nèi)部庫texttospeech,以實(shí)現(xiàn)語音播報(bào)功能。另外,實(shí)驗(yàn)中需要借助非Qt Creator內(nèi)部庫,因此需要編譯并加載第三方庫QXlsx,以實(shí)現(xiàn)將Excel表中的學(xué)生信息批量寫入數(shù)據(jù)庫中以及將系統(tǒng)檢查作業(yè)的結(jié)果自動(dòng)記錄到Excel表中。批量檢查Python作業(yè)系統(tǒng)主要過程如下:
①將學(xué)生信息通過編程批量錄入SQLite數(shù)據(jù)庫;
②利用紅蜘蛛多媒體教學(xué)軟件收集學(xué)生的作業(yè)文件;
③使用迭代的方式獲取學(xué)生的作業(yè)文件;
④利用mypy對(duì)文件進(jìn)行編譯,并結(jié)合最長(zhǎng)公共子序列算法將作業(yè)文件與正確的答案文件進(jìn)行相似度計(jì)算,從而將作業(yè)文件進(jìn)行評(píng)價(jià)分類并通過語音播報(bào)出來;
⑤自動(dòng)生成評(píng)價(jià)分類結(jié)果并保存到Excel表格。
具體流程如下頁圖4所示。
1.錄入學(xué)生信息
將全年級(jí)學(xué)生的信息匯總到Excel表格中,學(xué)生的信息包括學(xué)號(hào)和姓名,其中學(xué)號(hào)由兩位數(shù)的班級(jí)和兩位數(shù)的座位號(hào)組成,如11班1號(hào),則學(xué)號(hào)為1101。編寫程序?qū)xcel表格中全部的學(xué)生信息導(dǎo)入并保存到SQLite數(shù)據(jù)庫。
2.收集學(xué)生作業(yè)
首先,對(duì)計(jì)算機(jī)室的計(jì)算機(jī)按順序進(jìn)行名稱修改,如第一臺(tái)計(jì)算機(jī)名稱為“xs01”,第二臺(tái)計(jì)算機(jī)名稱為“xs02”,依此類推。學(xué)生根據(jù)自己的座位號(hào)就座相應(yīng)的位置。課堂上學(xué)生通過紅蜘蛛多媒體教學(xué)軟件提交作業(yè)后,紅蜘蛛多媒體教學(xué)軟件會(huì)為每位學(xué)生在教師機(jī)端自動(dòng)生成一個(gè)文件夾以存放學(xué)生的作業(yè),文件夾命名為對(duì)應(yīng)的學(xué)生機(jī)的名稱。學(xué)生所提交的作業(yè)文件統(tǒng)一以“班級(jí)+學(xué)號(hào)+姓名”的形式命名,如11班1號(hào)張三,則命名為“1101張三”。
3.獲取學(xué)生作業(yè)
通過編寫程序以迭代的方式獲取每位學(xué)生所提交的作業(yè)所對(duì)應(yīng)的文件夾的路徑。
4.檢查學(xué)生作業(yè)
(1)算法設(shè)計(jì)
①統(tǒng)計(jì)每個(gè)學(xué)生文件夾里提交的Python程序作業(yè)文件的數(shù)量。
②正常情況下,每個(gè)學(xué)生的文件夾里只有一個(gè)Python程序作業(yè)文件,如果多于一個(gè)則認(rèn)為該生為他人提交作業(yè)。從數(shù)據(jù)庫中查找是否有這些人,如有則將文件夾里的所有作業(yè)對(duì)應(yīng)的學(xué)生均記錄為“抄襲作業(yè)”,同時(shí)標(biāo)記為“已交作業(yè)”。
③在文件夾里只有一個(gè)Python程序作業(yè)文件的情況下,先從數(shù)據(jù)庫中查找是否有此人,如有則獲取該文件的路徑、名稱、時(shí)間、大小、學(xué)生學(xué)號(hào)和姓名等信息,同時(shí)標(biāo)記為“已交作業(yè)”。然后檢查文件的大?。何募笮?KB,則記錄該生所提交作業(yè)為“空白作業(yè)”。文件大小大于0KB,則對(duì)文件進(jìn)行編譯處理以及將作業(yè)文件與答案文件進(jìn)行相似度計(jì)算。編譯通過且相似度大于0.8,則記錄為“優(yōu)秀作業(yè)”;編譯不通過且相似度小于0.15,則記錄為“亂做作業(yè)”。
④以班級(jí)為單位從數(shù)據(jù)庫中查找出該班所有的學(xué)生,“減去”標(biāo)記為“已交作業(yè)”的學(xué)生,從而得到“未交作業(yè)”的學(xué)生。
(2)具體實(shí)現(xiàn)
①統(tǒng)計(jì)每個(gè)學(xué)生所提交作業(yè)對(duì)應(yīng)的文件夾里后綴名為“.py”的文件的數(shù)量。如果數(shù)量大于1,為防止學(xué)生在文件命名時(shí),將學(xué)號(hào)和姓名顛倒或在命名中誤加入空格或其他特殊符號(hào),本文采用正則表達(dá)的方法而非字符串分割截取的方法去提取文件名稱中的學(xué)號(hào)和姓名,其中利用正則表達(dá)式“[^0-9]+”提取文件名稱中的學(xué)號(hào)以及利用正則表達(dá)式“[^\u4e00-\u9fa5]”提取文件名稱中的姓名。由于學(xué)號(hào)是唯一的,因此利用學(xué)號(hào)與數(shù)據(jù)庫中該班級(jí)的所有學(xué)生學(xué)號(hào)進(jìn)行對(duì)比,如數(shù)據(jù)庫中存在這些學(xué)生,則將這些學(xué)生均記錄為“抄襲作業(yè)”,并標(biāo)記為“已交作業(yè)”。
②如果文件夾里后綴名為“.py”的文件的數(shù)量為1,則獲取該文件的路徑、名稱、時(shí)間、大小等信息以及利用正則表達(dá)式“[^0-9]+”和“[^\u4e00-\u9fa5]”分別提取名稱中的學(xué)號(hào)和姓名,接著查找學(xué)生信息數(shù)據(jù)庫中是否有此人,如有則標(biāo)記為“已交作業(yè)”。
如果該文件的大小為0KB,則將該生記錄為“空白作業(yè)”,如果大于0KB,那么:
a.編程調(diào)用mypy工具對(duì)文件進(jìn)行靜態(tài)編譯,如果編譯通過則其標(biāo)準(zhǔn)輸出通道中會(huì)含有“Success”關(guān)鍵字,否則含有“error”關(guān)鍵字,從而根據(jù)關(guān)鍵字去判斷Python程序作業(yè)文件是否編譯通過,也就是是否有誤;
b.打開Python作業(yè)文件及其對(duì)應(yīng)的答案文件并分別讀取里面的全部?jī)?nèi)容。為使算法更合理準(zhǔn)確,對(duì)所讀取到的內(nèi)容進(jìn)行預(yù)處理,Python程序中英文雙引號(hào)里面的內(nèi)容以及程序注釋內(nèi)容均為主觀定義的內(nèi)容,內(nèi)容可能相差較大,而且這些內(nèi)容并不需要作為求最長(zhǎng)公共子序列的內(nèi)容,因此先用正則表達(dá)式“\”[^\”]*\”|#.*”去掉文件內(nèi)容中的雙引號(hào)里面的內(nèi)容和#號(hào)后面的內(nèi)容。另外,去掉文件內(nèi)容中的回車換行符和空格等。
③求出預(yù)處理好后的Python作業(yè)文件和其對(duì)應(yīng)的答案文件的最長(zhǎng)公共子序列,并求出它們的相似度。結(jié)合a和b,如果Python程序作業(yè)文件編譯通過且相似度大于0.8,則記錄為“優(yōu)秀作業(yè)”;如果編譯不通過且相似度小于0.15,則記錄為“亂做作業(yè)”。
④以所選擇的班級(jí)為單位從數(shù)據(jù)庫中查找出該班所有的學(xué)生,“減去”標(biāo)記為“已交作業(yè)”的學(xué)生而得到“未交作業(yè)”的學(xué)生。
實(shí)驗(yàn)結(jié)果
批量檢查Python作業(yè)系統(tǒng)能在短時(shí)間內(nèi)高效完成對(duì)全班作業(yè)的檢查,檢查結(jié)果將作業(yè)評(píng)價(jià)分類為“優(yōu)秀作業(yè)”“未交作業(yè)”“抄襲作業(yè)”“亂做作業(yè)”和“空白作業(yè)”。在對(duì)2565份Python程序作業(yè)文件進(jìn)行檢查后,得到的準(zhǔn)確率較高。
討論
作為初學(xué)者,在極短時(shí)間的課堂里,學(xué)生基本都是按照課本上的程序代碼和教師的教學(xué)指導(dǎo)去編寫,加上初學(xué)的程序較為簡(jiǎn)單且基本沒有第二種寫法,因此學(xué)生課堂上完成的Python程序基本與課本里的程序或教師要求完成的程序完全相同或者類似,從而非常適用于批量檢查Python作業(yè)系統(tǒng)。但該系統(tǒng)也存在一些不足之處:
①有些學(xué)生可能會(huì)按自己的想法去寫出正確的程序,造成所編寫的Python程序與答案程序較為不同,導(dǎo)致系統(tǒng)所檢測(cè)出的相似度偏低,從而可能不被系統(tǒng)判斷為“優(yōu)秀作業(yè)”,但至少會(huì)被判斷為“已交作業(yè)”。根據(jù)實(shí)驗(yàn)結(jié)果統(tǒng)計(jì),在2565份作業(yè)中,只有2份作業(yè)出現(xiàn)這種情況,因此這種情況屬于極少數(shù),對(duì)批量檢查Python作業(yè)系統(tǒng)的準(zhǔn)確率的影響微乎其微。
②不適合較為復(fù)雜的或具有多種寫法的程序,因?yàn)檫@樣會(huì)造成與答案程序較為不同,導(dǎo)致系統(tǒng)所檢測(cè)出的相似度偏低。
總的來說,中小學(xué)信息技術(shù)課程中的編程內(nèi)容對(duì)中小學(xué)的學(xué)習(xí)要求較低,基本是處于基礎(chǔ)的層面,程序較為簡(jiǎn)單,且學(xué)生為初學(xué)者,因此批量檢查Python作業(yè)系統(tǒng)非常適合對(duì)中小學(xué)課堂Python程序作業(yè)的檢查。
參考文獻(xiàn):
鄭翠玲.最長(zhǎng)公共子序列算法的分析與實(shí)現(xiàn)[J].武夷學(xué)院學(xué)報(bào),2010,29(02):44-48.