我给AI素养课做了个自测平台:整个思考过程,和一套可以直接抄的题库解析代码

举报
阿诺林 发表于 2026/08/29 23:26:56 2026/08/29
【摘要】 智课工坊生成了20道题的题库md文件,但只有文件没有交互——学生没法自测,老师没法批改。花一下午做了个单文件HTML自测平台,从题库解析到错题循环,把思考过程摊开写,附上可以直接抄的解析引擎代码。 1. 起点智课工坊跑了一门入门AI素养课,第五步「题库考核」产出了一个20题的md文件。格式长这样:## 1. 【单选】在第1课中,用AI做出第一个成品时,最适合的做法是?- A. 先学习编程基础...

智课工坊生成了20道题的题库md文件,但只有文件没有交互——学生没法自测,老师没法批改。花一下午做了个单文件HTML自测平台,从题库解析到错题循环,把思考过程摊开写,附上可以直接抄的解析引擎代码。

1. 起点

智课工坊跑了一门入门AI素养课,第五步「题库考核」产出了一个20题的md文件。格式长这样:

## 1. 【单选】在第1课中,用AI做出第一个成品时,最适合的做法是?

- A. 先学习编程基础再动手
- [√] B. 直接使用AI对话工具生成内容并保存
- C. 只观看演示不自己操作
- D. 等待老师提供成品模板

**答案**:B | **难度**:easy | **对应课时**:第1课

**解析**:课程强调零代码、有产出...

单选用「【单选】」标注,多选用「【多选】」标注,正确选项前面有个 [√] 标记(智课工坊实际用√符号标记正确选项)。答案、难度、对应课时、解析都在 **答案** 和 **解析** 行里。

题目有了,但怎么用?老师拿去打印纸质卷子?太浪费了——这些题目有难度标签、有课时归属、有详细解析,应该做成一个学生打开浏览器就能用的东西。

2. 第一次推翻:不要Python脚本,要零部署的网页

我最初想的是写个Python脚本:学生跑脚本答题,终端里输出分数。

跑了一版发现不对——目标用户是大学新生,大部分人的电脑上连Python都没装。让他们装Python再跑命令行,门槛太高了。而且终端里没法做选项点选、进度条、错题回顾这些交互。

推倒重来。调研了一圈,决定做单文件HTML:一个.html文件,双击就能打开,不依赖任何后端、不装任何东西。所有题目直接嵌在文件里(也可以拖放导入外部题库md),用纯前端JavaScript搞定全部逻辑。

这个选择有一个关键好处:部署就是复制文件。放到静态服务器上、塞进课程包里、微信发个文件——学生拿到就能用。零运维成本。

3. 第二次推翻:不要一页一题,要三阶段模式

第二版我做成了一页一题的翻页模式:看完一题点下一题,最后统一提交。

做了几题发现体验很差:学生在第8题想回看第3题的题干,要往回翻6页。而且不知道总共多少题、自己答了多少。

推翻重来。改成三阶段模式:

  • 阶段一:选题。列出所有题目,可以按课时筛选(只看第3课的题)、按难度筛选(只做中等题)。一目了然。
  • 阶段二:答题。还是逐题,但顶部有进度条(第3/20题),底部有上一题/下一题导航,也可以直接点进度条跳题。当前做的题数据在内存里,来回切换不丢失。
  • 阶段三:看结果。提交后显示总分(答对X题/共Y题)、每道题的正确答案和解析。答错的题标红,答对的标绿。最关键的——有个「错题再考」按钮,只拿答错的题再来一轮。

三个阶段用 display:none/block 切换,不用路由、不用多页面,一个HTML搞定。

4. 题库解析引擎(可以直接抄)

整个平台的核心是这个解析函数——把智课工坊的md题库格式转成结构化数据。格式前面展示过了,正则匹配就行:

function parseQuestions(raw) {
  const questions = [];
  const blocks = raw.split(/\n---+\n/);
  for (const block of blocks) {
    const hMatch = block.match(/^##\s*\d+\.\s*【(单选|多选)】\s*(.+)/m);
    if (!hMatch) continue;
    const qType = hMatch[1] === '单选' ? 'single' : 'multi';
    const title = hMatch[2].trim();
    const opts = [];
    // 匹配选项行,正确选项前有勾选标记
    const optRe = /^-\s+(\[√\]\s*)?([A-F])\.\s*(.+)/gm;
    let m;
    while ((m = optRe.exec(block)) !== null) {
      opts.push({ label: m[2], text: m[3].trim(), correct: !!m[1] });
    }
    if (opts.length === 0) continue;
    const ansMatch = block.match(/\*\*答案\*\*:\s*(.+?)\s*[||]\s*/);
    const diffMatch = block.match(/\*\*难度\*\*:\s*(\w+)/);
    const lessonMatch = block.match(/\*\*对应课时\*\*:\s*(.+)/);
    const explainMatch = block.match(/\*\*解析\*\*:\s*([\s\S]+?)(?=\n*(?:---|$))/);
    questions.push({
      id: questions.length + 1,
      title, type: qType, options: opts,
      answer: ansMatch ? ansMatch[1].trim() : '',
      difficulty: diffMatch ? diffMatch[1] : 'medium',
      lesson: lessonMatch ? lessonMatch[1].trim() : '',
      explanation: explainMatch ? explainMatch[1].trim() : ''
    });
  }
  return questions;
}

这段代码处理了几个边界情况:

  • 题块分隔:智课工坊的题库用 --- 分隔每道题。直接用 split(/\n---+\n/) 切开。
  • 题型识别:从 【单选】 或 【多选】 读类型,决定后续用radio还是checkbox。
  • 正确选项定位:不是通过「答案」行反查——直接解析选项行里的勾选标记。这样即使「答案」行写错了,正确选项也丢不了。
  • 多选处理:filter(o => o.correct) 收集所有打勾的选项,多选答案可能是 A、B、D。

提交判断时,把用户选的选项 label 排序后拼成字符串,跟正确答案字符串比——单选用 ['B'] 拼成 'B',多选用 ['A','B','C'] 拼成 'ABC',一个比较搞定。

5. 两个关键设计决策

拖放导入题库:FileReader API读文件内容 → 喂给上面的parseQuestions → 替换当前题库。学生拿到新题库md后拖进页面就能用,不需要改HTML源码。这个功能让平台从「预置20题的demo」变成了「通用自测工具」。

错题再考循环:提交后如果答错X题,点「错题再考」就把 filteredQuestions 替换成答错的题集,重置作答状态,回到答题阶段。再考完还能再考——直到全对为止。这个循环让学生不是「做完看一眼分数就关」,而是「反复擦直到会」——符合学习规律。

6. 总结

三个判断:

  1. 单文件HTML是被低估的交付形态。不需要npm install、不需要docker、不需要服务器。一个.html文件,双击即用,拷到哪儿都能跑——对学生场景来说是零摩擦。
  2. 题库格式设计决定了解析成本。智课工坊的md格式用勾选标记标注正确选项、--- 分隔题块——这些约定让解析器不到60行就搞定了。如果格式是「答案单独放文件末尾」,解析要复杂很多。
  3. 错题循环是小功能但大价值。自测的核心不是打分,是让学生把不会的题反复做到会。这个循环把「一次性考试」变成了「学习工具」。

平台代码已经放在AI素养课课程包里,预置了入门版20题。题库文件拖进去就能用。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。