手把手教你打造一个考试刷题系统(五)——得分结算

之前,我们已经完成了题目的显示与作答,如果你还没看过,可以先了解一下:
手把手教你打造一个考试刷题系统(一)——界面结构搭建
手把手教你打造一个考试刷题系统(二)——界面动态加载显示
手把手教你打造一个考试刷题系统(三)——倒计时组件
手把手教你打造一个考试刷题系统(四)——题目切换与标记状态动作绑定
下面,我们来制作其中的最后一部分——得分计算。
PS:这部分,我们主要讲其中的逻辑,而不是表现形式。
▌一、得分规则
首先,我们需要确定一套得分规则。比如:
● 单选或判断题中,如果选错,是否需要倒扣分?
● 在多选题和不定项中,如果错选,是否可以得分?
● 在多选题中,只选择了一个选项,是否能够得分?
● 多选和不定项选择题中,没有错误选项,但未全对,所获分数,是根据答案的选项数来还是固定的数?
而根据一般的规则,我做出了如下的得分情况:

接下来,我们根据题型具体来看。
▌二、单选与判断
我们从简单的来说,首先是单选和判断,因为考生答案只有完全正确和完全错误两种状态。
我们只需要将考生回答与参考答案对比,如果完全一致,则得分,否则不得分或倒扣分(即得 0 分或 -0.5 分)。
以判断题为例:
▌三、多选与不定项有错误选项
接下来,我们讨论一下多选题和不定项的得分。
首先,我们需要判断,如果有错误选项,直接得零分,否则再做其他处理。那么,如何判断回答是否有错误答案呢?
首先,考生答案不能为空(我们的默认值),用代码表示即为:
当上面的条件不成立后,我们只需要对比,参考答案与考生答案中同位置的字母是否为空即可:
▌四、多选与不定项无错误选项
接下来,考生的答案中,就没有错误选项了。只需要根据规则,计算得分即可。
先说多选题,按照答案的个数,比如答案是 ABCDE,而回答为 AB,则得分为 2 / 5 * 4。
那么,怎样计算答案和答题中的选项个数呢?用循环吗?
提供一个小技巧,先将所有的空字符"_"去除,然后统计字符数就可以了。
简单解释一下: str.replace(/_/g,"")表示将所有的_替换为空 /g表示全部替换,如果没有该参数,只能将A_C_D替换为AC_D,不能替换为ACD。
有了这个思路,不定项的得分也能轻松算出:
▌五、总分统计
最后,我们只需要将每道题的得分加在一起就可以啦。
这里注意,在 JS 中,你可能会看到 0.5 - 0.4 = 0.9999999998 这种奇怪的现象,这个与计算机的二进制计算有关,不做过多解释。
但为更好的显示,我们可以仅保留两位小数,使用 num.toFIxed(2) 即可:
有了上面的操作步骤后,你就可以得到下面这样的反馈信息了:

当然,这个页面不是特别好看,你可以把上面的答案用 table 表格的方式加载到页面里,这里就不多介绍了。
▌六、一点小修正
在实际测试中,切换题目时,会出现左侧答题卡中标记为绿色(已作答),而右侧选项中选项中却没有打勾的奇怪现象:

这是因为我们刷新时,各个选项元素都会重新加载,而 input 默认是不勾选( checked )的,因此,我们在刷新时,需要从 subject 中读取之前的答案,并据此加载 input 的 checked 属性:
▌最后
至此,我们的考试刷题系统就告一段落了。
如果你也对里面的完整代码、逻辑感兴趣,可以访问:
源代码:https://gitee.com/mo-qianbei/examination-system/
语雀文档:https://www.yuque.com/moqianbei/shuati
但这个系统还不是特别完善,至少还有如下的功能细节可以优化:
是否可以选择隐藏题目的解析;
计算得分时是否可以重新作答;
是否可以根据题目数量确定每题的分值,而不是固定的4分;
计算器功能还未实现;
……
这些,就等待缘分啦,下次见~