简易试卷生成系统

期中考试,如何机考是个难题,就用了半天时间写了这么一个试卷生成系统。基本思路很简单,就是读取题目,然后生成一个html网页,这个网页分发给学生,进行测试。考虑到机房那破电脑,就不搞b/s结构了,所有逻辑都在html中实现。
当然,有几个问题必须考虑。
一是如何自动评分
二是如何尽可能的防止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>
  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
很好,您需要一个简易版的代码生成制造执行系统。这个系统可以自动生成制造流程,并将其转化为可执行的代码,使得生产过程更加自动化和高效化。下面是一个简单的实现方案: 1. 需要一个数据库来存储产品信息、制造流程和生产计划等。这个数据库可以使用关系型数据库或者NoSQL数据库,根据具体需求而定。 2. 在数据库中建立产品信息表,包含产品名称、零部件清单、工艺流程,例如:产品A需要零件B、C、D,制造流程为加工B、装配C、检验D。 3. 在数据库中建立制造流程表,包含工艺流程名称、所需零件清单和工艺参数等。例如:加工B需要设备X、工艺参数Y;装配C需要设备Z、工艺参数W。 4. 根据生产计划,从产品信息表中查询所需产品及其零部件清单和制造流程,然后从制造流程表中查询所需工艺参数和设备信息等。将这些信息整合起来,生成可执行的代码,包括设备控制命令、传感器数据采集和处理、错误处理等。 5. 执行生成代码,控制设备完成加工和装配等工艺流程。在过程中采集和处理传感器数据,进行错误处理和质量检验等。 6. 根据执行结果,更新数据库中的生产记录,包括产品完成情况、生产时间、质量检验结果等。 这个简易版的代码生成制造执行系统可以满足基本的生产自动化需求,但是还需要根据具体生产环境和需求进行进一步的优化和改进。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值