问题背景
设计一套试卷,里面有单选,多选,判断题(实际上判断题就是两个选项的单选题而已)
其他都很好处理,
里面的关键点,显然是多选题的错选、漏选、以及选对该如何处理
这里提供了一种方案,个人感觉比较合理。
思路和方案
- 选项用2^n的整数值表示
- 判断对错用位元算
- 多选题如果没选全,则看选对了的数目占正确答案的选项数目的比例
- 可设置题目分数是否一定为整数还是可以是0.5的倍数
方案
多选题:
代码如下[MSTest直接执行]:
using System;
using System.Diagnostics;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Web.Test.BinaryTest
{
[Flags]
public enum Options
{
O = 0,
A = 1,
B = 1 << 1,
C = 1 << 2,
D = 1 << 3
}
[TestClass]
public class UnitTest1
{
[DataRow(Options.O)] //空
[DataRow(Options.A)] //无错,未选全
[DataRow(Options.B)] //无错,未选全
[DataRow(Options.C)] //无错,未选全
[DataRow(Options.A | Options.B)]//无错,未选全
[DataRow(Options.A | Options.C)]//无错,未选全
[DataRow(Options.B | Options.C)]//无错,未选全
[DataRow(Options.A | Options.B | Options.C)]//对
[DataRow(Options.A | Options.B | Options.D)]//有对有错,算错
[DataRow(Options.C | Options.B | Options.D)]//有对有错,算错
[DataRow(Options.C | Options.A | Options.D)]//有对有错,算错
[DataRow(Options.A | Options.B | Options.C | Options.D)]//有对有错,算错
[TestMethod]
public void TestMethod1(Options option, bool isIntegerPoint = false)
{
//isIntegerPoint 为true时,每道题只有整数得分值;否则,可以为0.5的倍数的得分值
int totalScore = 4;
int totalAnswer = (int)(Options.A | Options.B | Options.C | Options.D); //ABCD
int rightAnswer = (int)(Options.A | Options.B | Options.C); //ABC
int wrongAnswer = totalAnswer - rightAnswer;
double score;
var intOption = (int)option;
//选对时
if (rightAnswer == intOption)
{
score = totalScore;
Debug.WriteLine($"score = {score}");
}
//选错时
else if ((wrongAnswer & intOption) > 0)
{
score = 0;
Debug.WriteLine($"score = {score}");
}
//未错,但未选全时
else
{
var rightOptionsCount = Convert.ToString(rightAnswer, 2).Replace("0", "").Length; //总选项数
var userOptionsCount = Convert.ToString(intOption, 2).Replace("0", "").Length; // 用户选项数
//整数分值
if (isIntegerPoint)
{
var point = totalScore * userOptionsCount / rightOptionsCount;
score = point;
}
//0.5的倍数的分值
else
{
var point = (double)(totalScore * userOptionsCount) / rightOptionsCount;
score = Math.Round((2 * point), MidpointRounding.AwayFromZero);
}
Debug.WriteLine($"score = {score / 2}");
}
}
}
}