源码下载:https://download.csdn.net/download/wjcroom/86308452
最近用两三天时间部署了一个考试练习系统,原因是有一个WORD文档题库有1千来个题目和答案,想要从里面随机取出一部分来进行练习。
我想大体步骤是
- 将WORD转换成规范的表格格式用于导入
- 找一个考试系统,可以导入题库
- 从中随机抽取一部分形成试卷进行练习
- 判断对错,提示正确答案,最好形成错题本,用于下次复习
一. 规范word形成题库
word的形式是
12.题目内容(AB)、
A.选项1 B.选项2
C.选项3D.选系4
将word成块的内容拷贝到editplus,这是我用着习惯的工具,支持正则表达式的工具都可以,WORD自身也行,只是我用不习惯。将选项ABC排成一行用TAB分隔,这就能拷贝到excel了。
- 拷贝到editplus,取消全部\t由于有很多多余的制表符,先清空一下。
- 查找A-D加.开头前面有换行的,去掉换行。并在前面加入TAB 也就是\t
查找:
[\n]*([A-E]\.)
//\n换行*多次 \. 是,的转义符
结果:
12.题目内容(AB)、 A.选项1 B.选项2 C.选项3 D.选系4
替换为: \t\1
3. 将答案接取出来,显示成空括号,答案放在新的一列。
查找:
(\n[0-9]+.*?)([A-E]+)
解释:以换行和数个数字开始,后跟任意字符,以多个或一个A-E字母结束。这里因为(后面有不定个空格,所以没有做为特征提取。这造成题目中不能有大写字母。行成,1,2两个模式把它的全套替换为:
\2\t\1
这样答案出来了,单括号留下了。
改进1
(\n[0-9]+.*?([ ]* )([A-E]+)
替换为 \n\2\t\1
将换行为开始,一个单括号(这里是中文的英文的需要\转义)加若干空格做为第一个模式匹配。将后续的字母组合取出来。颠倒位置为新的顺序
然而它忽率了第一行,并且空格是editplus允许的,在常规正则下用\s表示更好
所以
改进2
^([0-9]+.*?(\s*)([A-E]+)
首尾合适中间任意.*?,分为两组颠倒顺序,这样题干里的答案就被提取出来了。
结果:
AB 12.题目内容()、 A.选项1 B.选项2 C.选项3 D.选系4
- 将格式化的题库存成excel排除错误调整代用,做为自己的试用版,存成了txt以tab和换行分隔的文件。sigle.txt,muti.txt
二.构建考试系统
下载源代码
https://github.com/hsian/flask-exampy
按照说明部署
提示,这个初始化代码不完善,需要自己生成管理员,权限表,role,user ,简要构建用户。
python manager.py shell
使用以上命令,可以调用main model.py 中User类方法,User.insert_admin()和Role类方法,Role.insert_role() 确认一下IP字段和相应的main view.py里的IP部分的代码。
不过较为简单易懂,不足的地方是年代久远版本较低,但是完成度很好。
先建构平台,试运行
安装一个sqllite编辑工具,读懂一个全部代码。建立相应的用户。否则都没法看到菜单。role表需要,和user需要新加。user需要分配admin权限role。要一点点读懂。
进行定制
- 从txt文本读出50个题目形成一期新试卷,由题库文件生成新subject的主要过程
maxperiod= db.session.query(func.max(Select.period)).scalar() or 0
with open('./sigle.txt','r',encoding='utf-8') as sigles:
lns=sigles.readlines()
for ln in random.sample(lns[1:],50):
#ln=lns[rd].strip().split('\t')这里lns[rd]是资源下载中的纰漏,应该只是ln
ln=ln.strip().split('\t')
s=Select()
s.title=re.sub('[\d+、..•]', '', ln[0])
s.option="###".join(ln[1:5]+[''])
s.answer=ln[5]
s.period=maxperiod+1
print(s.option)
db.session.add(s)
- 从提交页面处理中反回错误题目
@login_required
def figure_score(id,username):
data = json.loads(request.form.get('list'))
if username == current_user.username:
exist = Score.query.filter_by(period=id,u_id=current_user.id).first()
if exist is None:
score = 0
wrong={
}
selects = Select.query.filter_by(period=id)
for n in selects:
print(data[str(n.id)]+n.answer)
if data[str(n.id)] == n.answer:
score +=[1,2] [len(n.answer)>=1] #多选2,单选1
else:
wrong[str(n.id)]=n.answer
o_score = Score(u_id=current_user.id,
username=current_user.username,
score=score,
period=id)
# db.session.add(o_score)
db.session.commit()
return json.dumps({
'score':score,'wrong':wrong})
else:
return "不能重复提交"
else:
return "用户信息错误"
- 在模板文件中显示错误答案
$.ajax({
url : "/figure/{
{period}}/{
{current_user.username}}",
type : "POST",
data : data,
success : function(res){
if(res != "不能重复提交"){
res=JSON.parse(res)
score = "你答了" + res.score + "分";
}
document.rsd=res
$("#release").attr("disabled", true)
$("#result").html(score);
$.each($(".answer span"),function(i,e){
right=res.wrong[$(e).attr("data-id")]
if (right)
{
$(e).html( $(e).html()+"<font color='red'>答案:"+ right+"</font>");
}
else
1
// {
$(e).parent().parent().css("display","none")}
})
//alert(res.wrong);
}
})
以上的定制就结束了
以上全部代码放在我的下载中了,请有需要的下载试用吧。里面有很多说明。