- 浏览: 17132 次
文章分类
最新评论
期中考试,如何机考是个难题,就用了半天时间写了这么一个试卷生成系统。基本思路很简单,就是读取题目,然后生成一个html网页,这个网页分发给学生,进行测试。考虑到机房那破电脑,就不搞b/s结构了,所有逻辑都在html中实现。
当然,有几个问题必须考虑。
一是如何自动评分
二是如何尽可能的防止zuobi
第一个问题很简单,但第二个有点头疼。这里,对答案采取base64编码。当然,如果学生懂js的,一行alert即可勘破天机。所以说,这个小系统只能用于随堂检测。
代码如下 SimpleTestGenerator.py:
例如若是生成题库为 题目.txt:
第一行为测试名称,第二行为考试时长(分钟),在这个时间之前不能交卷,也是防止学生通过反复交卷猜答案,之后的几行,是题干、选项、答案的loop;此处选择项必须是4个。
执行SimpleTestGenerator后,读取上述题库,生成的网页如下:
当然,有几个问题必须考虑。
一是如何自动评分
二是如何尽可能的防止zuobi
第一个问题很简单,但第二个有点头疼。这里,对答案采取base64编码。当然,如果学生懂js的,一行alert即可勘破天机。所以说,这个小系统只能用于随堂检测。
代码如下 SimpleTestGenerator.py:
import base64 class Generator: def __init__(self): self.template = '''<html> <head> <title>${testName}</title> </head> <body> ${questions} <input type="button" onclick="submit()" value="交卷" /> <script type="text/javascript"> submitTimes=0; duration = ${duration}; ifTimeup = false; selNum = ${selNum} setTimeout("timeup()",1000*60*duration); function getRadioValue(radioName) { var radios = document.getElementsByName(radioName); if(!radios) return ''; for (var i = 0; i < radios.length; i++) { if (radios[i].checked) return radios[i].value; } return ''; } function submit(){ if(ifTimeup){ submitTimes += 1; a = decodeBase64("${answer}"); score = 0; weight = 100/selNum; for(i = 0 ; i < selNum ; i++){ if(getRadioValue("sel"+(i+1))==a.charAt(i)){ score+=weight; } } alert("成绩:"+score+"分"+" 提交次数:"+submitTimes+"次"); }else{ alert("时间未满"+duration+"分钟"+"不能提交!") } } function timeup(){ ifTimeup = true; } var END_OF_INPUT = -1; var base64Chars = new Array("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "+", "/"); var reverseBase64Chars = new Array(); for (var i = 0; i < base64Chars.length; i++) { reverseBase64Chars[base64Chars[i]] = i } var base64Str; var base64Count; function setBase64Str(a) { base64Str = a; base64Count = 0 } function readReverseBase64() { if (!base64Str) { return END_OF_INPUT } while (true) { if (base64Count >= base64Str.length) { return END_OF_INPUT } var a = base64Str.charAt(base64Count); base64Count++; if (reverseBase64Chars[a]) { return reverseBase64Chars[a] } if (a == "A") { return 0 } } return END_OF_INPUT } function ntos(a) { a = a.toString(16); if (a.length == 1) { a = "0" + a } a = "%" + a; return unescape(a) } function decodeBase64(d) { setBase64Str(d); var a = ""; var c = new Array(4); var b = false; while (!b && (c[0] = readReverseBase64()) != END_OF_INPUT && (c[1] = readReverseBase64()) != END_OF_INPUT) { c[2] = readReverseBase64(); c[3] = readReverseBase64(); a += ntos((((c[0] << 2) & 255) | c[1] >> 4)); if (c[2] != END_OF_INPUT) { a += ntos((((c[1] << 4) & 255) | c[2] >> 2)); if (c[3] != END_OF_INPUT) { a += ntos((((c[2] << 6) & 255) | c[3])) } else { b = true } } else { b = true } } return a } </script> </body> </html>''' def setTestName(self,testName): self.testName = testName self.doReplace("testName",testName) def setDuration(self,duration): self.doReplace("duration",duration) def setQuestions(self,questions): self.doReplace("selNum",str(len(questions))) qStr = '' aStr = '' for (i,q) in enumerate(questions,start=1): qStr+=str(i)+") "+q.query+"<br>\n" for (j,o) in enumerate(q.options,start=1): qStr+='''<input type="radio" name="sel'''+str(i)+'''" value="'''+str(j)+'''">'''+o+'''<br>\n''' aStr+=str(q.answer) self.doReplace("questions",qStr) self.doReplace("answer",base64.encodestring(aStr.encode(encoding="ascii")).decode(encoding="ascii").replace('\n','\\n')) def doReplace(self,key,value): key="${"+key+"}" self.template = self.template.replace(key,value) def generate(self): f=open(self.testName+".html","w") f.write(self.template) f.close() class Question: def __init__(self): self.query = None self.options = [] self.answer = None class Parser: def __init__(self,fName): self.fName = fName self.answerConvertDic = {'A':1,'B':2,'C':3,'D':4} def parse(self): fin = open(self.fName) self.questions = [] q = None for (lno,line) in enumerate(fin.readlines()): line = line.strip() if lno==0: self.testName = line elif lno==1: self.duration = line elif (lno-2)%6==0: q = Question() q.query = line elif (lno-2)%6==5: q.answer=self.answerConvertDic[line] self.questions.append(q) else: q.options.append(line) def main(): parser = Parser("题目.txt") parser.parse() ge = Generator() ge.setTestName(parser.testName) ge.setDuration(parser.duration) ge.setQuestions(parser.questions) ge.generate() main()
例如若是生成题库为 题目.txt:
计算机应用基础期中检测 15 下列关于因特网上收/发电子邮件优点的描述中,错误的是________。 A)不受时间和地域的限制,只要能接入因特网,就能收发电子邮件 B)方便、快速 C)费用低廉 D)收件人必须在原电子邮箱申请地接收电子邮件 D 下列关于电子邮件的说法,正确的是________。 A)收件人必须有E-mail地址,发件人可以没有E-mail地址 B)发件人必须有E-mail地址,收件人可以没有E-mail地址 C)发件人和收件人都必须有E-mail地址 D)发件人必须知道收件人住址的邮政编码 C 假设ISP提供的邮件服务器为bj163.com,用户名为XUEJY的正确电子邮件地址是________。 A)XUEJY @ bj163.com B)XUEJYbj163.com C)XUEJY#bj163.com D)XUEJY@bj163.com D 用高级程序设计语言编写的程序________。 A)计算机能直接执行 B)可读性和可移植性好 C)可读性差但执行效率高 D)依赖于具体机器,不可移植 B
第一行为测试名称,第二行为考试时长(分钟),在这个时间之前不能交卷,也是防止学生通过反复交卷猜答案,之后的几行,是题干、选项、答案的loop;此处选择项必须是4个。
执行SimpleTestGenerator后,读取上述题库,生成的网页如下:
<html> <head> <title>计算机应用基础期中检测</title> </head> <body> 1) 下列关于因特网上收/发电子邮件优点的描述中,错误的是________。<br> <input type="radio" name="sel1" value="1">A)不受时间和地域的限制,只要能接入因特网,就能收发电子邮件<br> <input type="radio" name="sel1" value="2">B)方便、快速<br> <input type="radio" name="sel1" value="3">C)费用低廉<br> <input type="radio" name="sel1" value="4">D)收件人必须在原电子邮箱申请地接收电子邮件<br> 2) 下列关于电子邮件的说法,正确的是________。<br> <input type="radio" name="sel2" value="1">A)收件人必须有E-mail地址,发件人可以没有E-mail地址<br> <input type="radio" name="sel2" value="2">B)发件人必须有E-mail地址,收件人可以没有E-mail地址<br> <input type="radio" name="sel2" value="3">C)发件人和收件人都必须有E-mail地址<br> <input type="radio" name="sel2" value="4">D)发件人必须知道收件人住址的邮政编码<br> 3) 假设ISP提供的邮件服务器为bj163.com,用户名为XUEJY的正确电子邮件地址是________。<br> <input type="radio" name="sel3" value="1">A)XUEJY @ bj163.com<br> <input type="radio" name="sel3" value="2">B)XUEJYbj163.com<br> <input type="radio" name="sel3" value="3">C)XUEJY#bj163.com<br> <input type="radio" name="sel3" value="4">D)XUEJY@bj163.com<br> 4) 用高级程序设计语言编写的程序________。<br> <input type="radio" name="sel4" value="1">A)计算机能直接执行<br> <input type="radio" name="sel4" value="2">B)可读性和可移植性好<br> <input type="radio" name="sel4" value="3">C)可读性差但执行效率高<br> <input type="radio" name="sel4" value="4">D)依赖于具体机器,不可移植<br> <input type="button" onclick="submit()" value="交卷" /> <script type="text/javascript"> submitTimes=0; duration = 15; ifTimeup = false; selNum = 4 setTimeout("timeup()",1000*60*duration); function getRadioValue(radioName) { var radios = document.getElementsByName(radioName); if(!radios) return ''; for (var i = 0; i < radios.length; i++) { if (radios[i].checked) return radios[i].value; } return ''; } function submit(){ if(ifTimeup){ submitTimes += 1; a = decodeBase64("NDM0Mg==\n"); score = 0; weight = 100/selNum; for(i = 0 ; i < selNum ; i++){ if(getRadioValue("sel"+(i+1))==a.charAt(i)){ score+=weight; } } alert("成绩:"+score+"分"+" 提交次数:"+submitTimes+"次"); }else{ alert("时间未满"+duration+"分钟"+"不能提交!") } } function timeup(){ ifTimeup = true; } var END_OF_INPUT = -1; var base64Chars = new Array("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "+", "/"); var reverseBase64Chars = new Array(); for (var i = 0; i < base64Chars.length; i++) { reverseBase64Chars[base64Chars[i]] = i } var base64Str; var base64Count; function setBase64Str(a) { base64Str = a; base64Count = 0 } function readReverseBase64() { if (!base64Str) { return END_OF_INPUT } while (true) { if (base64Count >= base64Str.length) { return END_OF_INPUT } var a = base64Str.charAt(base64Count); base64Count++; if (reverseBase64Chars[a]) { return reverseBase64Chars[a] } if (a == "A") { return 0 } } return END_OF_INPUT } function ntos(a) { a = a.toString(16); if (a.length == 1) { a = "0" + a } a = "%" + a; return unescape(a) } function decodeBase64(d) { setBase64Str(d); var a = ""; var c = new Array(4); var b = false; while (!b && (c[0] = readReverseBase64()) != END_OF_INPUT && (c[1] = readReverseBase64()) != END_OF_INPUT) { c[2] = readReverseBase64(); c[3] = readReverseBase64(); a += ntos((((c[0] << 2) & 255) | c[1] >> 4)); if (c[2] != END_OF_INPUT) { a += ntos((((c[1] << 4) & 255) | c[2] >> 2)); if (c[3] != END_OF_INPUT) { a += ntos((((c[2] << 6) & 255) | c[3])) } else { b = true } } else { b = true } } return a } </script> </body> </html>
发表评论
-
python截屏 内存泄露 解决办法
2015-03-05 14:57 1433http://stackoverflow.com/questi ... -
cxfreeze使用记录
2014-11-20 20:16 495【记录用,方便以后个人查看】 cxfreeze是一个将py ... -
一个简易的AVG游戏模板(python)
2014-09-02 09:03 1392from tkinter import * clas ... -
vc winio驱动级模拟按键 简记
2014-06-04 17:41 3560对于普通的模拟按键,利用keybd_event等系统函数即可, ... -
mac xcode 下搭建lua环境(宿主c语言)
2014-05-14 22:35 3014新的项目可能需要使用lua语言写脚本,故先试验了下 首先是安 ...
相关推荐
考试试卷生成系统简易考试试卷生成系统简易考试试卷生成系统简易
简易矢量图形生成系统.zip简易矢量图形生成系统.zip简易矢量图形生成系统.zip简易矢量图形生成系统.zip简易矢量图形生成系统.zip简易矢量图形生成系统.zip简易矢量图形生成系统.zip简易矢量图形生成系统.zip简易矢量...
使用JAVA编写的简易实现自动从数据库生成试卷的程序,调用MySQL数据库
用Qt写的简易矢量图形生成系统;代码不是最终版,自己优化去!
本软件是简易的SiteMap生成器,可遍历网站收集网址,生成(全站)用于搜索引擎的SiteMap文件。 软件不会对URL进行校验,所以可能会有错误网址,请生成后自行删除。 ...提示:如果网址数量较多,生成过程将会非常缓慢,请...
简易bbs系统简易bbs系统简易bbs系统简易bbs系统简易bbs系统简易bbs系统简易bbs系统简易bbs系统
C++工业软件开发设计基于QT的简易CAD系统、有向图和无向图自动生成系统源码。 内含详细文档说明,并不复杂,完全可以自己实践。 实现最基本的功能大致需要将程序分为两个主要部分: 可视化控件:类画板控件,负责...
使用Delphi 7开发的简易二维码生成器,支持中文。代码没有使用第三方控件和第三方DLL。
用于生成通用的web项目,如Service,web,Dao 方便快捷,简单灵活。
Java简易随机数生成 下载完请输入测试代码 public static void main(String[] args) { System.out.println(random(50,100));//example System.out.println(random(50.0,100.0)); }
VB简易二维码生成器
简易ATM系统简易ATM系统简易ATM系统简易ATM系统简易ATM系统简易ATM系统简易ATM系统简易ATM系统简易ATM系统简易ATM系统简易ATM系统简易ATM系统简易ATM系统简易ATM系统简易ATM系统简易ATM系统简易ATM系统简易ATM系统...
基于Qt的简易矢量图形生成系统
本简易水情检测系统以STC12C5A60S2单片机为控制核心
简易网店系统简易网店系统简易网店系统简易网店系统简易网店系统简易网店系统简易网店系统
C#简易酒店管理系统源码 C#简易酒店管理系统源码 C#简易酒店管理系统源码 C#简易酒店管理系统源码 C#简易酒店管理系统源码 C#简易酒店管理系统源码 C#简易酒店管理系统源码 C#简易酒店管理系统源码 C#简易...
简易条码生成器源代码,需要生成条码的信息从EXCEL文档中导入