用正则表达式处理题库及Flask+sqllite开源考试系统的使用

源码下载: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了。

  1. 拷贝到editplus,取消全部\t由于有很多多余的制表符,先清空一下。
  2. 查找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

  1. 将格式化的题库存成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);
				}
			})

以上的定制就结束了
在这里插入图片描述
以上全部代码放在我的下载中了,请有需要的下载试用吧。里面有很多说明。

猜你喜欢

转载自blog.csdn.net/wjcroom/article/details/126148144