极简 极易 极完美,真正随机题库

楼主
我是社区第623546位番薯,欢迎点我头像关注我哦~

笔者前面发过一篇帖子:灵活运用Rend函数,选项随机排序垂手可得https://bbs.fanruan.com/thread-135687-1-1.html
文中,笔者自我感觉良好,但是功能构建毕竟是极其粗暴地用控件堆叠而成,有道友反馈,虽依葫芦画瓢,但鉴于我的表达能力可能不够清晰,或者因控件太多展现不够直观,所以道友始终不得其门而入。我也感觉挺郁闷的。在仔细一构思,对着函数温故而知新,原来我少有用SCACH公式来表达, 导致结构复杂。对此非常抱歉,特发修正,请道友们参阅此文档。

与前文相比,本次改进毋须借助数据工厂整理数据,应用的表达式逻辑清晰,更好扩展,省事省力。在功能上与前文保持一致,主要实现的功能有:

1、自动按出题数量添加行
2、自动随机打乱抽题顺序
3、自动随机打乱选项顺序
4、前后选项数量保持一致
5、系统自动进行答题批改6、ABC答案不区分大小写
7、复选框不区分单选、多选
8、预计实现多选少选有效得分


对于多项选择逻辑解读,需要的朋友请参阅官方文档:https://t6ixa9nyl6.jiandaoyun.com/sharedoc/7dca4jXgHiAiW3fi6wgqXb补充完善


应用的搭建,与前文一样,请道友们熟悉主要应用的三个函数表达式:

 
1、INT(RAND()*(b-a)+a):获取一个大于等于 a 但小于 b 的随机整数
2、SPLIT(text, text_separator)[num]:将文本按指定字符串分割成数组并取出数组中第N个数据。

 

3、SEARCH(find_text,within_text,[start_num])
返回第一个文本字符串在第二个文本字符串中第一次出现的位置序号,从左到右查找,返回 0 则表示未查找到。
(约相当于子表单分行取数)

 

一、题库的建设参考图片,(全部单行文本也可以):https://ub35s32n7x.jiandaoyun.com/f/60bf88acd10ad1000802f8db
 

 

 
方案一:固定四个选项设置
 
 
随机数:INT(RAND()*题库+1)

试题:CONCATENATE(试卷.题干,CHAR(10),"--------------------",CHAR(10),"A、",SPLIT(试卷.选项,"-")[SPLIT(试卷.选项随机,",")[0]-1],CHAR(10),"B、",SPLIT(试卷.选项,"-")[SPLIT(试卷.选项随机,",")[1]-1],CHAR(10),"C、",SPLIT(试卷.选项,"-")[SPLIT(试卷.选项随机,",")[2]-1],CHAR(10),"D、",SPLIT(试卷.选项,"-")[SPLIT(试卷.选项随机,",")[3]-1])

选项随机:UNION(SPLIT(CONCATENATE(INT(RAND()*4+1),",",INT(RAND()*4+1),",",INT(RAND()*4+1),",",INT(RAND()*4+1)),","),"1","2","3","4")

转换:"ABCD"[SPLIT(试卷.选项随机,",")[SEARCH(试卷.单项选择,"ABCD")-1]-1]
标答、得分:我的答案建在另外一个标签内,为简便请请直接新增)标答联动题库,得分表达式:IF(答案.转换==答案.标答,答案.标准分值,0)

 
方案二:7个以内选项设置,(对比方案一,可扩展性强,表达式相对复杂,结合方案一方便理解思维,解读表达式)
对比方案一,字表单多了两个控件:
1、“题干随机序号”(主控件需要对应设置,目的去除重复随机数)
2、“选项数”(联动题库。目的是根据选项数生成对应随机个数)
 
方案二核心字表单控件名称展示:
主要控件“试题”函数表达式:CONCATENATE(试卷.题干,CHAR(10),"✻✼❄❅❆❇❈❉❊",CHAR(10),"A、",SPLIT(试卷.选项,",")[SPLIT(试卷.选项随机,",")[0]-1],CHAR(10),"B、",SPLIT(试卷.选项,",")[SPLIT(试卷.选项随机,",")[1]-1],CHAR(10),"C、",SPLIT(试卷.选项,",")[SPLIT(试卷.选项随机,",")[2]-1],IFS(试卷.选项数>=4,CONCATENATE(CHAR(10),"D、",SPLIT(试卷.选项,",")[SPLIT(试卷.选项随机,",")[3]-1])),IFS(试卷.选项数>=5,CONCATENATE(CHAR(10),"E、",SPLIT(试卷.选项,",")[SPLIT(试卷.选项随机,",")[4]-1])),IFS(试卷.选项数>=6,CONCATENATE(CHAR(10),"F、",SPLIT(试卷.选项,",")[SPLIT(试卷.选项随机,",")[5]-1])),IFS(试卷.选项数>=7,CONCATENATE(CHAR(10),"G、",SPLIT(试卷.选项,",")[SPLIT(试卷.选项随机,",")[6]-1])))
主要控件“选项随机”表达式:IFS(试卷.选项数==2,UNION(SPLIT(CONCATENATE(INT(RAND()*2+1),",",INT(RAND()*2+1)),","),"1","2"),试卷.选项数==3,UNION(SPLIT(CONCATENATE(INT(RAND()*3+1),",",INT(RAND()*3+1),",",INT(RAND()*3+1)),","),"1","2","3"),试卷.选项数==4,UNION(SPLIT(CONCATENATE(INT(RAND()*4+1),",",INT(RAND()*4+1),",",INT(RAND()*4+1),",",INT(RAND()*4+1)),","),"1","2","3","4"),试卷.选项数==5,UNION(SPLIT(CONCATENATE(INT(RAND()*5+1),",",INT(RAND()*5+1),",",INT(RAND()*5+1),",",INT(RAND()*5+1),",",INT(RAND()*5+1)),","),"1","2","3","4","5"),试卷.选项数==6,UNION(SPLIT(CONCATENATE(INT(RAND()*6+1),",",INT(RAND()*6+1),",",INT(RAND()*6+1),",",INT(RAND()*6+1),",",INT(RAND()*6+1),",",INT(RAND()*6+1)),","),"1","2","3","4","5","6"),试卷.选项数==7,UNION(SPLIT(CONCATENATE(INT(RAND()*7+1),",",INT(RAND()*7+1),",",INT(RAND()*7+1),",",INT(RAND()*7+1),",",INT(RAND()*7+1),",",INT(RAND()*7+1),",",INT(RAND()*7+1)),","),"1","2","3","4","5","6","7"))
选项随机支持7个以内选项,可以根据自己实际需要删减,注意理解数字对应关系。
由于选项随机,所以需要将选项结果做一个比对解读,“转换”控件表达式:IFS(ISEMPTY(试卷.单项选择)!=1,SPLIT(试卷.选项随机,",")[SEARCH(试卷.单项选择,"ABCDEFG")-1])。
 
我的答案建在另外一个标签内,如果一个标签内,可以直接赋值"得分“,完整表达式为IFS(IFS(ISEMPTY(试卷.单项选择)!=1,SPLIT(试卷.选项随机,",")[SEARCH(试卷.单项选择,"ABCDEFG")-1])==SEARCH(答案.标答,"ABCDEFG"),答案.标准分值),
控件”“题干”,“选项”,“选项数”,“标答”,“标准分值”,均为联动题库而来,随机数、题干随机序号公式参阅前面文档。单项选择为答题控件。
 
极简 极易 极完美,真正随机题库,完整链接体验:https://ub35s32n7x.jiandaoyun.com/f/60bf846ca0580d00075e3bd1
谢谢!
分享扩散:
参与人数 +1 F币 +10 理由
云团 + 10 奖励给这种研究精神

查看全部评分

来自 5#
发表于 2021-6-9 16:15:17
多选随机体验:https://ub35s32n7x.jiandaoyun.com/f/60c0328c2cca69000838664e 编辑于 2021-6-10 23:09  
沙发
发表于 2021-6-9 04:24:11 发布于APP客户端
彭宇,你这也太敬业了啊,半夜都在研究啊,我正在学习你的随机方法啊!
板凳
发表于 2021-6-9 08:32:34 发布于APP客户端
选项中分割字符建议使用不常用的字符,避免实际场景中出现错误分割,也可以直接是连续的特殊字符,比如“###”。
地板
发表于 2021-6-9 11:13:35
因为支持7个以内选项,所以试题和随机选项看起来比较复杂,这实际上是一个冗余设计,绝大部分选项四个,7个以内可以实用99%的题库建设。建议道友们在理解表达式的基础上删减,会更完美
6楼
发表于 2021-6-9 20:25:30 发布于APP客户端
彭宇大神,今天太忙了,明天估计有空刚好试验下你这方法啊,为你点赞啊
7楼
发表于 2021-6-9 20:34:32 发布于APP客户端
彭宇祝贺你啊,哎呀,我的用户名终于显示正常了!
8楼
发表于 2021-6-10 00:41:21 发布于APP客户端
这实现得完美!?
9楼
发表于 2021-6-10 11:52:45
优化了转换表达式:"ABCDEFG"[SPLIT(试卷.选项随机,",")[SEARCH(试卷.单项选择,"ABCDEFG")-1]-1]
10楼
发表于 2021-6-10 13:13:39
Rend随机函数实践对比反馈:主表单用穷举法列出65个随机数(随机取数范围1~100),生成600余份表单,数据表明,重复率很高,最低36,最高58.。字表单生成20行随机数(取值范围同上),几乎无重复,当然重复率与取数区间和取值数量相关。 编辑于 2021-6-10 13:16  
11楼
发表于 2021-6-10 13:19:52
优化了复选框的表达公式,这样单选与多选子表单选控件数量一致,逻辑一致,只需要对应的控件,复选框也可以做单选:UNION(SPLIT(CONCATENATE("ABCDEFG"[SPLIT(试卷.选项随机,",")[SEARCH(试卷.多项选择[0],"ABCDEFG")-1]-1],",","ABCDEFG"[SPLIT(试卷.选项随机,",")[SEARCH(试卷.多项选择[1],"ABCDEFG")-1]-1],",","ABCDEFG"[SPLIT(试卷.选项随机,",")[SEARCH(试卷.多项选择[2],"ABCDEFG")-1]-1],",","ABCDEFG"[SPLIT(试卷.选项随机,",")[SEARCH(试卷.多项选择[3],"ABCDEFG")-1]-1],",","ABCDEFG"[SPLIT(试卷.选项随机,",")[SEARCH(试卷.多项选择[4],"ABCDEFG")-1]-1],",","ABCDEFG"[SPLIT(试卷.选项随机,",")[SEARCH(试卷.多项选择[5],"ABCDEFG")-1]-1],",","ABCDEFG"[SPLIT(试卷.选项随机,",")[SEARCH(试卷.多项选择[6],"ABCDEFG")-1]-1]),","))+"-"
12楼
发表于 2021-6-10 13:21:29
统一了单选得分的表达式,看起来要复杂一点,主要是为了与多选对其:IF(AND(COUNT(答案.转换)==COUNT(SPLIT(答案.标答,',')),COUNT(UNION(SPLIT(答案.转换+','+答案.标答,',')))==COUNT(SPLIT(答案.标答,','))),答案.标准分值,0)
13楼
发表于 2021-6-10 13:23:33
感觉表达式还可以进一步优化,但本人才疏学浅,暂时找不到优化的空间,欢迎各位大神指点。
14楼
发表于 2021-6-10 13:48:45
多选少选也能计算为有效分,怎么设置,大神们
15楼
发表于 2021-6-11 00:26:26 发布于APP客户端
我再加个需求 如何剔除随机过的题
16楼
发表于 2021-6-11 06:20:01
聚合表、智能助手、数据工厂都是用一个少一个,真金白银。本应用的构建完全不占以上内容,但”选项“需要在整理数据中用符号分割,文章默认使用英文状态下",",建议大家用其它特殊符号分割,如~、-、#等,同时修正公式中分割表达式,以避免文字描述中不区分中英文状态而导致选项取数组错误
17楼
发表于 2021-6-11 19:02:39
贴出了方案一,四个单选固定选项设置,公式简洁,结合方案二,方便道友们理解扩展函数结构及意义。
18楼
发表于 2021-6-13 10:24:42
解答道友关于页面控件的属性的疑问:得分为数字,选择答案下拉框,其余均为单行文本控件。
19楼
发表于 2021-6-13 10:34:41
序号是利用子表单动态变化行数实现可参考:https://hc.jiandaoyun.com/blog/12020
20楼
发表于 2021-6-16 17:24:23
我就想问一下,论坛中有人像我一样认定研究彭宇先生的这个贴子,认真的去实验了吗?有人实现了吗?
21楼
发表于 2021-6-25 16:33:25 发布于APP客户端
我还是没明白,第二种方案,怎么确定输出几个选项啊?
22楼
发表于 2021-6-27 10:04:47 发布于APP客户端
请问下,这个是单选,如果是多选,怎么转换那个选择啊?
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

31回帖数 6关注人数 7959浏览人数
最后回复于:2021-11-3 09:26

返回顶部 返回列表