何文廣, 周 珂, 熊剛強(qiáng), 王耀民
(廣東醫(yī)科大學(xué) 信息工程學(xué)院,廣東 湛江 524023)
VB.NET程序設(shè)計(jì)題動(dòng)態(tài)評(píng)閱技術(shù)研究
何文廣, 周 珂, 熊剛強(qiáng), 王耀民
(廣東醫(yī)科大學(xué) 信息工程學(xué)院,廣東 湛江 524023)
程序設(shè)計(jì)題的自動(dòng)評(píng)閱能有效地輔助教師靈活開(kāi)展實(shí)驗(yàn)教學(xué),進(jìn)而提升教學(xué)質(zhì)量。針對(duì)傳統(tǒng)動(dòng)態(tài)評(píng)閱方法在處理人機(jī)交互和獲取控件句柄方面存在的不足,設(shè)計(jì)和實(shí)現(xiàn)了一種基于代碼預(yù)處理和代碼嵌入式的新型動(dòng)態(tài)評(píng)閱方法。該方法包含代碼預(yù)處理、代碼嵌入、編譯運(yùn)行和結(jié)果評(píng)閱等4個(gè)環(huán)節(jié),首先在代碼預(yù)處理環(huán)節(jié)對(duì)學(xué)生程序進(jìn)行功能替換,然后通過(guò)植入輔助代碼和功能測(cè)試代碼驅(qū)動(dòng)程序運(yùn)行并產(chǎn)生結(jié)果數(shù)據(jù),最后根據(jù)保存在臨時(shí)文件中的結(jié)果數(shù)據(jù)進(jìn)行評(píng)定。實(shí)施結(jié)果表明,該方法很好地實(shí)現(xiàn)了程序的功能檢測(cè),能準(zhǔn)確識(shí)別和處理編譯失敗以及運(yùn)行出錯(cuò)或超時(shí)等問(wèn)題,體現(xiàn)出良好的健壯性和正確性。
程序設(shè)計(jì); 動(dòng)態(tài)評(píng)閱; 代碼預(yù)處理; 代碼嵌入功能檢測(cè)
程序設(shè)計(jì)是國(guó)內(nèi)高等院校計(jì)算機(jī)基礎(chǔ)教學(xué)的核心課程,其教學(xué)目標(biāo)是培養(yǎng)學(xué)生使用計(jì)算機(jī)分析問(wèn)題和解決問(wèn)題的思維能力。在日常教學(xué)和考核中,程序設(shè)計(jì)題是必不可少的[1],其求解過(guò)程囊括了問(wèn)題分析、模型構(gòu)造、算法設(shè)計(jì)和編碼調(diào)試等環(huán)節(jié),對(duì)強(qiáng)化訓(xùn)練學(xué)生的計(jì)算思維具有重要意義。然而,作為一種主觀題型,程序設(shè)計(jì)題的評(píng)閱往往只能由教師人工閱卷完成,這不僅不利于減輕教師工作壓力,并且無(wú)法形成快速的反饋,嚴(yán)重影響教學(xué)質(zhì)量的提升。
程序設(shè)計(jì)題的自動(dòng)評(píng)閱方法主要分靜態(tài)評(píng)閱和動(dòng)態(tài)評(píng)閱。靜態(tài)評(píng)閱通過(guò)各種匹配方法將源程序與模板程序進(jìn)行相似度匹配得出評(píng)分[2]。因此,靜態(tài)評(píng)閱的準(zhǔn)確率完全依賴(lài)于模板程序的完備程度,常見(jiàn)方法主要有語(yǔ)義相似度匹配[3-6]和得分點(diǎn)匹配[7-9]。動(dòng)態(tài)評(píng)閱則完全不依賴(lài)模板程序,它直接編譯和運(yùn)行程序,然后根據(jù)程序運(yùn)行結(jié)果進(jìn)行評(píng)分。目前,主流的解決方案是結(jié)合動(dòng)、靜態(tài)評(píng)閱[10-15],即借助動(dòng)態(tài)評(píng)閱忽略程序代碼的各異性;只有在程序編譯失敗或運(yùn)行出錯(cuò)時(shí),才通過(guò)靜態(tài)評(píng)閱對(duì)關(guān)鍵知識(shí)點(diǎn)進(jìn)行匹配產(chǎn)生得分補(bǔ)充,最終實(shí)現(xiàn)近似于人工閱卷的效果。
已有動(dòng)態(tài)評(píng)閱方法主要利用了Windows消息機(jī)制[12-15],其原理可描述如下:首先,借助VB集成開(kāi)發(fā)環(huán)境打開(kāi)學(xué)生程序,然后模擬啟動(dòng)按鈕F5[14]編譯和運(yùn)行學(xué)生程序;其次,獲取程序子窗口句柄,并進(jìn)一步獲取窗體中所有控件的句柄[15];最后,借助各句柄發(fā)送一系列Windows消息,模擬事件的發(fā)生驅(qū)動(dòng)程序運(yùn)行并獲取程序運(yùn)行結(jié)果。上述方法的不足之處主要在于難以預(yù)先獲取所有控件的句柄,尤其是動(dòng)態(tài)生成的控件。本文通過(guò)代碼預(yù)處理和代碼嵌入的方法得到了新的動(dòng)態(tài)評(píng)閱實(shí)現(xiàn)方案。
新的動(dòng)態(tài)評(píng)閱方法可劃分為代碼預(yù)處理、代碼嵌入、編譯運(yùn)行和結(jié)果評(píng)閱四大部分,其工作流程如圖1所示。

圖1 動(dòng)態(tài)評(píng)閱流程
代碼預(yù)處理的目的是處理人機(jī)交互行為以及程序自動(dòng)行為,確保處理后的學(xué)生程序能被正確引導(dǎo)完成自動(dòng)化功能測(cè)試。
常規(guī)人機(jī)交互包括輸入、輸出和選擇交互,對(duì)應(yīng)VB.NET的InputBox函數(shù)、MsgBox函數(shù)和MessageBox對(duì)話框。在確保不改變程序正確性或錯(cuò)誤性的前提下,本文采用了正則表達(dá)式匹配替換的方法,用常量或全局變量實(shí)現(xiàn)功能替代。例如,下述代碼實(shí)現(xiàn)了圖2所示的輸入功能替換。
pat="(For )([wW]+?)( =[wW]+?To[wW]+?=[wW]+?)InputBox([wW]+?)([wW]+?Next)"

(a) 替換前 (b) 替換后
圖2 InputBox輸入替換
rep = "123"&"{4, 5, 6, 1}(2)"&"4"
Fvb= Regex.Replace(Fvb, pat, rep)
類(lèi)似地,圖3和圖4顯示了使用全局變量實(shí)現(xiàn)輸出功能替換和選擇功能替換的結(jié)果。在圖3中,MsgBox函數(shù)的輸出將轉(zhuǎn)向存儲(chǔ)到全局變量glo。圖4中全局變量glo則替代了人工選擇,進(jìn)而通過(guò)改變glo的值來(lái)模擬不同的選擇。

(a) 替換前 (b) 替換后
圖3 MsgBox輸出替換

(a) 替換前 (b) 替換后
圖4 MsgBox選擇交互替換
程序自動(dòng)行為主要是指計(jì)時(shí)器Timer。計(jì)時(shí)器能按某頻率反復(fù)觸發(fā)Tick事件,過(guò)程耗時(shí)較長(zhǎng)不利于控制。為了模擬計(jì)時(shí)器行為,本文采用正則表達(dá)式匹配替換的方法識(shí)別、替代計(jì)時(shí)器啟動(dòng)和停止行為,然后人工反復(fù)觸發(fā)Tick事件。后續(xù)“案例分析”小節(jié)將給出具體實(shí)現(xiàn)案例。
代碼嵌入是指在程序源代碼的指定位置插入自定義的代碼段,以實(shí)現(xiàn)以下目的:植入功能輔助代碼、植入功能測(cè)試代碼、驅(qū)動(dòng)程序運(yùn)行、記錄程序運(yùn)行結(jié)果以及發(fā)送通知消息。
功能輔助代碼為動(dòng)態(tài)評(píng)閱提供支持,包括聲明輔助全局變量、聲明Windows API函數(shù)、聲明閱卷程序主窗口句柄變量和導(dǎo)入命名空間。其中,Windows API函數(shù)主要指PostMessage函數(shù),它用于支持學(xué)生程序運(yùn)行結(jié)束后向閱卷程序發(fā)生通知消息;此外,學(xué)生程序向閱卷程序發(fā)生通知消息還依賴(lài)閱卷程序主窗口句柄,因此需要聲明一個(gè)全局變量并寫(xiě)入閱卷程序主窗口句柄;命名空間主要指System.IO,用于支持將程序運(yùn)行結(jié)果保存到指定臨時(shí)文件。
廣義的功能測(cè)試代碼包括程序驅(qū)動(dòng)代碼,是驗(yàn)證學(xué)生程序正確性的關(guān)鍵代碼。本文將功能測(cè)試代碼嵌入到Form1_Load事件過(guò)程的最后,以確保程序在內(nèi)存中加載完成后自動(dòng)執(zhí)行功能測(cè)試代碼。嵌入前如果檢測(cè)到學(xué)生程序尚未存在Form1_Load事件過(guò)程,則先嵌入Form1_Load事件過(guò)程,然后在其中嵌入功能測(cè)試代碼。
本文將學(xué)生程序運(yùn)行過(guò)程中的重要數(shù)據(jù)保存到臨時(shí)文件中,以作為程序運(yùn)行的結(jié)果。數(shù)據(jù)主要來(lái)自各控件和輔助全局變量,數(shù)據(jù)記錄使用了StreamWriter類(lèi)將結(jié)果數(shù)據(jù)寫(xiě)入指定臨時(shí)文件。寫(xiě)入前如果檢查到文件已存在,則先刪除文件,然后重新建立文件并寫(xiě)入。
完成所有功能測(cè)試和記錄運(yùn)行結(jié)果數(shù)據(jù)后,學(xué)生程序必須主動(dòng)向閱卷程序發(fā)送消息,通知程序運(yùn)行結(jié)束。因此,最后嵌入一條發(fā)送消息的命令語(yǔ)句。
在依次經(jīng)歷代碼預(yù)處理和代碼嵌入之后,閱卷程序?qū)㈤_(kāi)始編譯和運(yùn)行學(xué)生程序,以獲得運(yùn)行結(jié)果。因此,必須確保學(xué)生程序在功能測(cè)試代碼的引導(dǎo)下自動(dòng)完成所有測(cè)試,并準(zhǔn)確處理學(xué)生程序語(yǔ)法錯(cuò)誤、運(yùn)行出錯(cuò)或超時(shí)等問(wèn)題。
VB.NET集成開(kāi)發(fā)環(huán)境(IDE)提供了從命令行編譯并運(yùn)行項(xiàng)目或解決方案的命令:Devenv,并且配合使用命令行開(kāi)關(guān)/Runexit可以實(shí)現(xiàn)在編譯時(shí)最小化IDE,編譯完成后自動(dòng)關(guān)閉IDE。本文使用的IDE為Visual Studio2010,在該環(huán)境下編譯命令為“Devenv project.sln /Runexit”。同時(shí),為了更好地實(shí)現(xiàn)對(duì)學(xué)生程序的控制,本文結(jié)合使用了Process類(lèi)來(lái)實(shí)現(xiàn)進(jìn)程的訪問(wèn)和控制,實(shí)現(xiàn)代碼如下:
Dim p As New Process()
p.StartInfo.FileName = "devenv.exe"
p.StartInfo.Arguments = "project.sln /RunExit"
p.Start()
在編譯完成之前,上述Process對(duì)象p指向IDE,編譯通過(guò)后IDE自動(dòng)關(guān)閉,p指向?qū)W生程序。在編譯過(guò)程中,語(yǔ)法錯(cuò)誤往往導(dǎo)致編譯失敗,而通過(guò)編譯的程序則會(huì)在內(nèi)存中加載。因此,可通過(guò)使用FindWindow方法查找學(xué)生程序進(jìn)程進(jìn)行編譯失敗或成功判斷。首先,在調(diào)用p.Start()方法的同時(shí)創(chuàng)建一個(gè)監(jiān)測(cè)子線程,在子線程內(nèi)實(shí)施不間斷查找。如果在限定時(shí)間內(nèi)查找成功,則判定編譯通過(guò)并隱藏學(xué)生程序界面,然后開(kāi)始新的計(jì)時(shí)用于判斷程序運(yùn)行是否失敗。如果編譯失敗,則調(diào)用p.Kill()殺死進(jìn)程。
運(yùn)行超時(shí)和運(yùn)行時(shí)出錯(cuò)都可歸結(jié)為運(yùn)行失敗,常見(jiàn)的如死循環(huán)會(huì)引起運(yùn)行超時(shí),數(shù)組下標(biāo)越界會(huì)引起運(yùn)行時(shí)出錯(cuò)。本文以是否接收到來(lái)自學(xué)生程序的通知消息作為判斷依據(jù)。監(jiān)測(cè)子線程如果在限定時(shí)間內(nèi)接收到通知消息,則判定運(yùn)行成功,否則為失敗。最后,調(diào)用p.Kill()殺死進(jìn)程。
為了更直觀地理解動(dòng)態(tài)評(píng)閱的原理,這里選取一道題目做進(jìn)一步分析講解。題目要求為:?jiǎn)螕簟皢?dòng)”按鈕,按鈕標(biāo)題變?yōu)椤巴V埂保瑫r(shí)Label1的字體顏色開(kāi)始循環(huán)變換:紅、綠、藍(lán)、黃、橙、紫、黑、紅、綠、…。單擊“停止”按鈕,按鈕標(biāo)題變?yōu)椤皢?dòng)”,同時(shí)Label1的字體顏色停止變換。
圖5對(duì)比了原程序以及處理后的程序,處理過(guò)程包括代碼預(yù)處理和代碼嵌入。首先在預(yù)處理環(huán)節(jié),借助全局變量glo替換了計(jì)時(shí)器Time1的啟動(dòng)和停止功能。然后在代碼嵌入環(huán)節(jié),嵌入了4行輔助代碼,依次是命名空間System.IO、全局變量glo、閱卷程序主窗口句柄以及PostMessage函數(shù)。最后嵌入Form1_Load事件過(guò)程和相關(guān)功能測(cè)試代碼。如此,一旦處理后的程序被編譯并運(yùn)行,系統(tǒng)將會(huì)自動(dòng)新建臨時(shí)文件,然后一邊執(zhí)行功能測(cè)試代碼一邊記錄結(jié)果數(shù)據(jù)。

圖5 原程序與處理后的程序?qū)Ρ?/p>
圖6給出了學(xué)生程序運(yùn)行結(jié)束后臨時(shí)文件D: est esult.txt中的內(nèi)容,這是進(jìn)行結(jié)果評(píng)閱的唯一依據(jù)。按照功能測(cè)試代碼的設(shè)計(jì),首行輸出“start”表示學(xué)生程序能正確啟動(dòng)計(jì)時(shí)器,第二行輸出“停止啟動(dòng)”表示學(xué)生程序能正確修改按鈕標(biāo)題,第三行輸出“stop”表示學(xué)生程序能正確停止計(jì)時(shí)器,最后一行用于判斷能否正確循環(huán)變換字體顏色。

圖6 學(xué)生程序運(yùn)行結(jié)果
動(dòng)態(tài)評(píng)閱是程序設(shè)計(jì)題自動(dòng)評(píng)閱中的關(guān)鍵技術(shù),其特點(diǎn)在于能準(zhǔn)確反映學(xué)生程序是否達(dá)到指定的功能要求,不依賴(lài)模板程序且完全忽略程序代碼的各異性。本文通過(guò)結(jié)合代碼預(yù)處理和代碼嵌入,設(shè)計(jì)和實(shí)現(xiàn)了全“代碼化”的新型動(dòng)態(tài)評(píng)閱方法,進(jìn)一步擴(kuò)展了動(dòng)態(tài)評(píng)閱的適用題型范圍,有利于改進(jìn)日常教學(xué)和考核。
[1] 牛永潔,張曉光.關(guān)于程序設(shè)計(jì)題自動(dòng)評(píng)分方法的研究[J].信息技術(shù),2010(11):155-156.
[2] 馮秀梅,張永勝.程序設(shè)計(jì)題自動(dòng)評(píng)分方法研究[J].軟件工程師,2015,18(2):9-11.
[3] 溫湘敏,胡 琳.依據(jù)程序依賴(lài)關(guān)系匹配度的C語(yǔ)言程序設(shè)計(jì)題評(píng)分方法[J]. 南昌大學(xué)學(xué)報(bào),2013,37(5):502-505.
[4] 馬培軍,王甜甜,蘇小紅.基于程序理解的編程題自動(dòng)評(píng)分方法[J]. 計(jì)算機(jī)研究與發(fā)展,2009,46(7):1136-1142.
[5] 王 倩,蘇小紅,馬培軍.有語(yǔ)法錯(cuò)誤的編程題自動(dòng)評(píng)分方法研究__用局部語(yǔ)法分析和采分點(diǎn)匹配實(shí)現(xiàn)[J].計(jì)算機(jī)工程與應(yīng)用,2010,46(17):239-242.
[6] 蘇小紅,王宇穎,王甜甜.面向綜合實(shí)踐能力考核的C語(yǔ)言編程考試自動(dòng)評(píng)分系統(tǒng)[J].實(shí)驗(yàn)技術(shù)與管理,2010,27(10):174-176.
[7] 鄭志明,鄭燕娥.Java語(yǔ)言程序設(shè)計(jì)題自動(dòng)閱卷技術(shù)研究 [J]. 福建工程學(xué)院學(xué)報(bào),2014,12(3):237-240.
[8] 鄭志明,鄭燕娥.利用XML的采分點(diǎn)匹配評(píng)分技術(shù)[J]. 寧夏師范學(xué)院學(xué)報(bào),2014,35(3):95-98.
[9] 宣華鋒. VisualBasic程序設(shè)計(jì)題自動(dòng)評(píng)分算法的研究及實(shí)踐[D].杭州:浙江工業(yè)大學(xué),2011.
[10] 劉瑞軍.VB程序自動(dòng)評(píng)分系統(tǒng)的分析與設(shè)計(jì)[J].宜賓學(xué)院學(xué)報(bào),2016,16(6):46-49.
[11] 趙曉靜.編程題自動(dòng)閱卷系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)[J]. 軟件工程師,2014,17(9):46-47.
[12] 段漢周,凌 捷,鄭衍衡.VB程序設(shè)計(jì)考核自動(dòng)評(píng)閱系統(tǒng)中若干問(wèn)題的研究[J].計(jì)算機(jī)工程,2001,27(4):167-168.
[13] 付亞臣.基于Windows消息機(jī)制的VB編程題評(píng)分系統(tǒng)的研究與應(yīng)用[D].大連:大連海事大學(xué),2012.
[14] 馬青霞.主觀題自動(dòng)閱卷系統(tǒng)的實(shí)現(xiàn)_VB編程題自動(dòng)閱卷[D].南京:南京理工大學(xué),2008.
[15] 賁黎明.VB程序設(shè)計(jì)題自動(dòng)閱卷方法的研究[J]. 計(jì)算機(jī)與現(xiàn)代化,2011(10):175-176.
ResearchontheDynamicMarkingTechnologyforVB.NETProgram
HEWenguang,ZHOUKe,XIONGGangqiang,WANGYaomin
(School of Information Engineering, Guangdong Medical University, Zhanjiang 524023, Guangdong, China)
Automatic marking for VB.NET program is of great significance to liberate teachers’ working and improve teaching quality. To overcome the deficiency of conventional dynamic marking in processing interaction and acquiring control’s window handle, a novel method based on code preprocessing and code embedding is designed and implemented in this paper. Four parts including code preprocessing, code embedding, compiling and running, result reviewing constitute this method. Firstly, function replacement is fulfilled on student’s program during the code preprocessing. Then auxiliary code and function testing code are embedded to run and output result data. Finally, the program is evaluated by the resulting data from temporary file. Practical results indicate that the function detection for specified program can be well achieved by this method. Moreover, it can accurately identify and deal with problems such as compiling failure, runtime error, timeout and so on. This shows that the proposed method is robust and accurate.
program design; dynamic marking; code preprocessing; code embedding function detection

TP 391
A
1006-7167(2017)11-0122-04
2017-02-15
廣東省高等教育教學(xué)改革項(xiàng)目(粵教高函[2016]260);2015年度廣東醫(yī)科大學(xué)教育教學(xué)研究課題(201530)
何文廣(1984-),男,廣東湛江人,碩士,講師,主要研究方向:圖形圖像處理。
Tel.:18718807350; E-mail:56207403@qq.com