一种程序作业自动批改的方法和装置与流程

文档序号:12596984阅读:380来源:国知局
本发明涉及程序作业批改的自动化。
背景技术
:计算机教学中,经常会有程序作业。教师批改程序作业时往往会消耗比较长的时间,特别是,当程序作业比较大时,由于程序本身涉及各种逻辑,而且各个学生的编程中变量命名方式不同,函数定义方式不同,教师看懂学生的程序就往往要耗费比较长的时间。特别是当该程序作业涉及某种复杂算法时,教师批改程序作业更为耗时。而且教师手工批改程序作业往往有主观性,而程序中细微的不同就可能导致功能、性能的较大差异,教师手工批改难以观察到这些不同。技术实现要素:本发明所要解决的问题:设计一种程序作业自动批改的方法和模块。为解决上述问题,本发明采用的方案如下:根据本发明的一种程序作业自动批改的方法,包括如下步骤:S1:获取教师的作业题集和各个学生的作业程序数据;S2:根据所述作业题集的作业题描述,对所述作业程序数据的程序代码进行批改评分;S3:以表格的形式输出各个学生的作业评分数据;其中,所述作业题集是作业题描述的集合;所述作业题描述包含有作业主题和测试用例集;所述测试用例集是测试用例数据的集合;所述测试用例数据包括测试输入数据、测试输出数据和测试通过分值;所述作业程序数据包含有学生名称和程序代码;所述学生作业评分数据包含有学生名称和作业评分值;所述步骤S2包括:S21:初始化该学生的作业评分值为0;S22:对该学生的程序代码进行编译,形成可执行代码;如果编译失败,则完成对该学生的批改评分;如果编译成功,则该学生的作业评分值加编译成功分值;S23:加载编译后的可执行代码;如果加载失败,则完成对该学生的批改评分;如果加载成功,则作业评分值加加载成功分值;S24:找出程序代码所对应的作业题描述,然后根据作业题描述中的测试用例集中各个测试用例数据,通过执行所加载的可执行代码对各个测试用例数据进行测试,再通过测试用例的测试是否通过得到测试通过分值,将相应的测试通过分值加入至作业评分值。进一步,根据本发明的程序作业自动批改的方法,所述作业题描述还包含有程序执行时间限制;所述步骤S24中当执行可执行代码时,监控可执行代码的执行时间;如果执行时间超过所述程序执行时间限制,则停止执行可执行代码,并设定该测试用例的测试不通过。进一步,根据本发明的程序作业自动批改的方法,所述作业题描述还包含有程序内存占用限制;所述步骤S24中当执行可执行代码时,监控可执行代码执行的内存占用;如果内存占用超过所述程序内存占用限制,则停止执行可执行代码,并设定该测试用例的测试不通过。进一步,根据本发明的程序作业自动批改的方法,所述测试用例数据还包含有标准执行时间;所述步骤S24中当执行可执行代码时,监控可执行代码的执行时间;当测试通过分值加入至作业评分值时,按执行时间超出标准执行时间的多少将测试通过分值加入至作业评分值。进一步,根据本发明的程序作业自动批改的方法,所述测试用例数据还包含有标准内存占用;所述步骤S24中当执行可执行代码时,监控可执行代码执行的内存占用;当测试通过分值加入至作业评分值时,按内存占用超出标准内存占用的多少将测试通过分值加入至作业评分值。根据本发明的一种程序作业自动批改的装置,包括:作业题集输入模块,用于获取教师的作业题集;作业程序输入模块,用于获取各个学生的作业程序数据;作业批改评分模块,用于根据所述作业题集的作业题描述,对所述作业程序数据的程序代码进行批改评分;批改结果输出模块,用于以表格的形式输出各个学生的作业评分数据;其中,所述作业题集是作业题描述的集合;所述作业题描述包含有作业主题和测试用例集;所述测试用例集是测试用例数据的集合;所述测试用例数据包括测试输入数据、测试输出数据和测试通过分值;所述作业程序数据包含有学生名称和程序代码;所述学生作业评分数据包含有学生名称和作业评分值;所述作业批改评分模块包括:评分初始化模块,用于初始化该学生的作业评分值为0;代码编译模块,用于对该学生的程序代码进行编译,形成可执行代码;如果编译失败,则完成对该学生的批改评分;如果编译成功,则该学生的作业评分值加编译成功分值;代码加载模块,用于加载编译后的可执行代码;如果加载失败,则完成对该学生的批改评分;如果加载成功,则作业评分值加加载成功分值;用例执行模块,用于找出程序代码所对应的作业题描述,然后根据作业题描述中的测试用例集中各个测试用例数据,通过执行所加载的可执行代码对各个测试用例数据进行测试,再通过测试用例的测试是否通过得到测试通过分值,将相应的测试通过分值加入至作业评分值。进一步,根据本发明的程序作业自动批改的装置,所述作业题描述还包含有程序执行时间限制;用例执行模块还包括有超时判断模块;所述超时判断模块,用于当执行可执行代码时,监控可执行代码的执行时间;如果执行时间超过所述程序执行时间限制,则停止执行可执行代码,并设定该测试用例的测试不通过。进一步,根据本发明的程序作业自动批改的装置,所述作业题描述还包含有程序内存占用限制;用例执行模块还包括有内存超限判断模块;所述内存超限判断模块,用于当执行可执行代码时,监控可执行代码执行的内存占用;如果内存占用超过所述程序内存占用限制,则停止执行可执行代码,并设定该测试用例的测试不通过。进一步,根据本发明的程序作业自动批改的装置,所述测试用例数据还包含有标准执行时间;用例执行模块还包括有测试时间加权评分模块;所述测试时间加权评分模块,用于当执行可执行代码时,监控可执行代码的执行时间;当测试通过分值加入至作业评分值时,按执行时间超出标准执行时间的多少将测试通过分值加入至作业评分值。进一步,根据本发明的程序作业自动批改的装置,所述测试用例数据还包含有标准内存占用;用例执行模块还包括有内存占用加权评分模块;所述内存占用加权评分模块,用于当执行可执行代码时,监控可执行代码执行的内存占用;当测试通过分值加入至作业评分值时,按内存占用超出标准内存占用的多少将测试通过分值加入至作业评分值。本发明的技术效果如下:批量自动化批改程序作业,大大减少了教师批改程序作业的时间,并同时提高了教师批改程序作业的准确性。附图说明图1是作业程序数据文件夹结构。具体实施方式下面结合附图对本发明做进一步详细说明。本实施例是一个针对Java程序作业自动批改的,通过Java语言实现的实施例。一、作业题集的输入作业题集采用XML文件方式,教师将作业题的内容编辑成一个XML文件。下述XML文件是一个作业题集的实施例:<?xmlversion="1.0"encoding="UTF-8"?><tcversion="1.0"url="http://code.google.com/p/java-assign-judge/"><generatorname="fanghong"url="http://code.google.com/p/java-assign-judge/"/><item><!--作业1Hello--><title><![CDATA[Hello]]></title><!--作业主题--><time_limit><![CDATA[10]]></time_limit><!--程序执行时间限制--><memory_limit><![CDATA[10]]></memory_limit><!--程序内存占用限制--><testcasetcid=1><!--测试用例--><input><![CDATA[]]></input><!--测试输入数据--><output><![CDATA[hello]]></output><!--测试输出数据--><bexitcmd><![CDATA[true]]></bexitcmd><!--是否退出--><time_base><![CDATA[5]]></time_base><!--标准执行时间--><memory_base><![CDATA[5]]></memory_base><!--标准内存占用--><score><![CDATA[100]]></score><!--测试通过分值--></testcase></item><item><!--作业2猜数游戏--><title><![CDATA[GuessNumber]]></title><!--作业主题--><time_limit><![CDATA[15]]></time_limit><!--程序执行时间限制--><memory_limit><![CDATA[10]]></memory_limit><!--程序内存占用限制--><testcasetcid=1><input><![CDATA[]]></input><output><![CDATA[开始]]></output><time_base><![CDATA[5]]></time_base><memory_base><![CDATA[5]]></memory_base><score><![CDATA[10]]></score><bexitcmd><![CDATA[false]]></bexitcmd></testcase><!--猜数--><testcasetcid=2><input><![CDATA[1]]></input><output><![CDATA[dyn]]></output><time_base><![CDATA[5]]></time_base><memory_base><![CDATA[5]]></memory_base><score><![CDATA[20]]></score><bexitcmd><![CDATA[false]]></bexitcmd></testcase><!--设置难度参数--><testcasetcid=3><input><![CDATA[2]]></input><output><![CDATA[]]></output><time_base><![CDATA[5]]></time_base><memory_base><![CDATA[5]]></memory_base><score><![CDATA[20]]></score><bexitcmd><![CDATA[false]]></bexitcmd></testcase><testcasetcid=4><input><![CDATA[1]]></input><output><![CDATA[开始]]></output><time_base><![CDATA[5]]></time_base><memory_base><![CDATA[5]]></memory_base><score><![CDATA[20]]></score><bexitcmd><![CDATA[false]]></bexitcmd></testcase><!--再次猜数--><testcasetcid=5><input><![CDATA[1]]></input><output><![CDATA[dyn]]></output><time_base><![CDATA[5]]></time_base><memory_base><![CDATA[5]]></memory_base><score><![CDATA[20]]></score><bexitcmd><![CDATA[false]]></bexitcmd></testcase><!--退出--><testcasetcid=6><input><![CDATA[3]]></input><output><![CDATA[]]></output><time_base><![CDATA[5]]></time_base><memory_base><![CDATA[5]]></memory_base><score><![CDATA[20]]></score><bexitcmd><![CDATA[true]]></bexitcmd></testcase></item></tc>上述XML格式文件定义了Hello和猜数游戏两个作业题描述。每个作业题描述包含了作业主题,由title标记定义;程序执行时间限制,由time_limit标记定义;程序内存占用限制,由memory_limit标记定义;测试用例数据,由testcase标记定义。其中Hello作业题只有一个测试用例数据,而猜数游戏由5个测试用例数据组成测试用例集。测试用例数据包含了测试输入数据,由input标记定义;测试输出数据,由output标记定义;标准执行时间,由time_base标记定义;标准内存占用,由memory_base标记定义;测试通过分值,由score标记定义。本实施例XML格式文件定义的作业题集由专用工具编辑而成。由于作业题集作为本发明的输入,因此,该专用工具如何实现并不是本发明所讨论的范畴,不再赘述。二、作业程序数据的输入本实施例作业程序数据通过文件夹的方式实现,当作业程序数据导入本系统时,以文件夹为单位。如图1所示,该文件夹包含有各个学生的子文件夹,每个子文件夹的名称与对应的学生名称相同。每个学生的子文件夹中包含了该学生的程序代码。每个学生的程序代码可能有多个,每个程序代码的文件名与作业题描述中的作业主题相同。由此,可以根据程序代码的文件名找到对应的作业题描述。需要指出的是,本实施例所针对的学生的程序代码是文本界面的程序。也即学生的程序代码是以文本方式进行输入输出的程序,输入采用键盘键入或文本文件的方式,输出则以屏幕文本或文本文件的方式呈现。批改程序与被批改程序交互的基本原理是:批改程序加载被批改的程序后,会截取被批改程序的标准输入stdin、输出流stdout、错误输出流stderr;从测试用例中提取出输入数据,注入被截取的输入流;输出流和错误输出流会被分别重定向到不同的文本文件,然后通过读取文本文件内容获取被测程序实际输出,并与测试用例中的预期输出比较。这说明该批改程序也能批改其它语言的文本终端程序,只要该语言支持标准输入、输出。三、批改评分批改评分的过程总体上分成三个步骤:编译,加载和执行。本实施例通过Java语言实现,是针对Java程序作业的处理。因此,java程序的编译,加载以及执行都可以通过org.apache.tools.ant程序包实现。其中,java程序的编译可以通过调用org.apache.tools.ant.taskdefs.javac中的java程序编译器实现,java程序的加载和执行可以通过调用org.apache.tools.ant.taskdefs.java中方法实现。org.apache.tools.ant程序包可通过网络下载获得。由此,上述java程序的编译、加载和执行均属于现有技术,本说明书不再赘述。当学生的程序代码被加载后,通过程序注入的方式截取学生的程序代码中的标准输入输出函数。执行测试用例时,从测试用例中提取输入数据,将输入数据注入被截取的标准输入函数,而学生的程序代码执行后的输出通过被截取的标准输出函数被重新定向至文本文件中,然后通过读取该输出的文本文件获取测试结果,并与测试用例中的预期输出比较。这种程序注入的方式为本领域技术人员所熟悉的技术,本说明书不再赘述。本实施例的作业评分值由编译成功分值、加载成功分值和测试用例执行分值组成。具体来说,作业评分值的满分为100分时,编译成功分值为10分,加载成功分值为10分,测试用例执行总分值为80分。假如编译失败,后面的加载和执行都失去了基础,可以直接返回,作业评分值也就为0。假如编译成功,而加载失败,则后面的测试用例执行失去基础,可以直接返回,作业评分值为编译成功分值为10分。假如编译成功和加载成功,作业评分值至少有20分的基础分。本实施例的测试用例执行分值由测试用例执行时,执行时间和内存占用的加权获得。具体来说,其中,Ti为第i个测试用例执行获得的评分值;Si为第i个测试用例的测试通过分值,对应于前述作业题描述中由score标记定义的分值。第i个测试用例执行获得的评分值其中,t为时间效率加权系数,m为内存占用加权系数。时间效率加权系数t通过以下方式确定:当测试用例执行时间小于标准执行时间时,t=1;当测试用例执行时间超过标准执行时间10%以内时,t=0.9;当测试用例执行时间超过标准执行时间20%以内时,t=0.8;当测试用例执行时间超过标准执行时间50%以内时,t=0.7;当测试用例执行时间超过标准执行时间100%以内时,t=0.6;否则为t=0.5,如果测试用例执行时间超过程序执行时间限制时,t=0。这里标准执行时间是前述测试用例数据中的数据,由time_base标记定义。程序执行时间限制,由前述time_limit标记定义。测试用例执行时间通过在前述执行代码时加入监控代码执行时间获得。m为内存占用加权系数通过以下方式确定:当测试用例执行时最大的内存占用小于标准内存占用时,m=1;当测试用例执行时最大的内存占用超过标准内存占用10%以内时,m=0.9;当测试用例执行时最大的内存占用超过标准内存占用20%以内时,m=0.8;当测试用例执行时最大的内存占用超过标准内存占用50%以内时,m=0.7;当测试用例执行时最大的内存占用超过标准内存占用100%以内时,m=0.6;否则为m=0.5,如果当测试用例执行时最大的内存占用超过程序内存占用限制时,m=0。这里标准内存占用是前述测试用例数据中的数据,由memory_base标记定义。程序内存占用限制,由前述memory_limit标记定义。测试用例执行时最大的内存占用通过在前述执行代码时加入监控代码执行的内存占用情况获得。此外,本实施例通过设置各种异常处理过程保证批改评分过程的鲁棒性。比如为避免被评分程序代码出现死循环的可能性,通过在作业题描述中设置程序执行时间限制,然后在执行测试用例时,监控代码执行时间,当执行时间超过程序执行时间限制,则停止执行该测试用例,并设定该测试用例的测试不通过,由此该测试用例执行获得的评分值Ti=0。为避免被评分程序代码内存分配出现的问题,通过在作业题描述中设置程序内存占用限制,然后在执行测试用例时,监控可执行代码执行的内存占用情况;当内存占用超过程序内存占用限制,则停止执行该测试用例,并设定该测试用例的测试不通过,由此该测试用例执行获得的评分值Ti=0。除上述之外,当测试用例执行时,出现其他任何可能的异常均设定该测试用例的测试不通过。由此该测试用例执行获得的评分值Ti=0。四、评分结果的输出本实施例以CSV表格文件的形式输出评分结果。评分结果也即各个学生的作业评分数据。作业评分数据包括学生名称、作业评分值。下述表格是最终评分结果输出的实施例。HelloGuessNumber学生A10060学生B10070学生C100100上述实施例中,Hello和GuessNumber为作业题的主题。需要说明的是,上述实施例是针对Java语言程序作业的批改评分的实施例,通过上述方法,也可以实现对其他语言程序作业的批改。此外,需要说明的是,本实施例所针对的Java语言程序作业是文本界面的程序。由上述可知,本实施例通过对文本界面程序用测试用例进行自动化测试后分析结果数据实现对文本界面程序的批改评分。本领域技术人员理解,通过程序注入的方式,也可以对图形界面的程序代码或网页程序代码进行自动化测试,由此也意味着,上述对程序的批改评分也可以应用于图形界面的程序代码或网页程序代码。当前第1页1 2 3 
当前第1页1 2 3 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1