freeCodeCamp 课程源码解析:Convert Celsius to Fahrenheit——从一道入门题看懂 JavaScript 挑战题的文件规范与测试机制
【免费下载链接】freeCodeCampfreeCodeCamp.org's open-source codebase and curriculum. Learn math, programming, and computer science for free.项目地址: https://gitcode.com/GitHub_Trending/fr/freeCodeCamp
本文以 freeCodeCamp 开源课程仓库中 JavaScript 认证的第一道算法题《Convert Celsius to Fahrenheit》为主体,完整还原其公式要求、全部断言测试与种子代码,并结合仓库中的课程结构文件与题型定义源码,讲清楚这道题在 freeCodeCamp 课程管线中是如何被组织、加载和判分的。读完你可以掌握:该挑战题的完整解题方法、挑战题 Markdown 源文件(frontmatter + 分节标记)的规范结构,以及challengeType数值如何决定题目视图与提交方式。
题目定位:JavaScript 认证的第一道算法题
这道挑战题位于curriculum/challenges/english/blocks/basic-algorithm-scripting/56533eb9ac21ba0edf2244b3.md,文件名是题目在数据库中的唯一id。它在课程结构中的位置可以从两个层级文件确认:
- 区块文件 basic-algorithm-scripting.json 的
challengeOrder数组中,56533eb9ac21ba0edf2244b3("Convert Celsius to Fahrenheit")排在第一位,其后依次是 "Reverse a String"、"Factorialize a Number" 等题目; - 超级区块文件 javascript-algorithms-and-data-structures.json 声明了 JavaScript 算法与数据结构认证的十个区块,
basic-algorithm-scripting是其中的第六个,排在 basic-javascript、es6、regular-expressions、debugging、basic-data-structures 之后。
此外,该题目 id 还被 lab-celsius-to-fahrenheit-converter.json 引用(标题为 "Build a Celsius to Fahrenheit Converter",usesMultifileEditor: true),说明同一份题目内容也被复用于多文件编辑器场景的 lab 练习——从源码结构看,这是课程团队对同一知识点在不同练习形式中复用内容的做法。
题目原文与公式要求
原题的完整技术要求如下:
The formula to convert from Celsius to Fahrenheit is the temperature in Celsius times
9/5, plus32.You are given a variable
celsiusrepresenting a temperature in Celsius. Use the variablefahrenheitalready defined and assign it the Fahrenheit temperature equivalent to the given Celsius temperature.
即:华氏温度 = 摄氏温度 × 9/5 + 32。题目明确要求:给定变量celsius,把已声明的变量fahrenheit赋值为对应的华氏温度后返回。这限制了答题形式——不能改函数名,必须复用let fahrenheit这个声明。
种子代码(seed)
题目预置给学习者的代码如下:
function convertCtoF(celsius) { let fahrenheit; return fahrenheit; } convertCtoF(30);注意此时fahrenheit处于"声明未赋值"状态,直接运行convertCtoF(30)会返回undefined,测试无法通过。学习者需要做的唯一改动就是给fahrenheit赋值转换结果。
标准答案(solutions)
原文件# --solutions--小节给出的参考实现:
function convertCtoF(celsius) { let fahrenheit = celsius * (9 / 5) + 32; return fahrenheit; } convertCtoF(30);一行转换式celsius * (9 / 5) + 32是题目的核心考点:在 JavaScript 中9 / 5是浮点除法(结果为1.8),乘法与加法按运算符优先级先乘后加,等价于celsius * 1.8 + 32。由于测试用例的输入(-30、-10、0、20、30)都恰好能得到整数结果,strictEqual这类严格相等断言不会因为浮点尾差而失败。
全部测试断言(hints 即判分用例)
原题# --hints--小节共列出 6 条断言,这就是判分时实际执行的全部测试用例,逐条继承如下:
convertCtoF(0)should return a number:
assert.isNumber(convertCtoF(0));convertCtoF(-30)should return a value of-22:
assert.strictEqual(convertCtoF(-30), -22);convertCtoF(-10)should return a value of14:
assert.strictEqual(convertCtoF(-10), 14);convertCtoF(0)should return a value of32:
assert.strictEqual(convertCtoF(0), 32);convertCtoF(20)should return a value of68:
assert.strictEqual(convertCtoF(20), 68);convertCtoF(30)should return a value of86:
assert.strictEqual(convertCtoF(30), 86);用例设计上有三个值得注意的点:
- 类型检查先行:第一条用
assert.isNumber而非strictEqual,专门拦截"返回了字符串或 undefined"这类错误(例如忘了赋值、返回了未初始化的fahrenheit); - 覆盖负数与零点:-30、-10 验证公式在负温区间的正确性(-30 × 1.8 + 32 = -22),0 则是两种温标最经典的锚点(冰点 0°C = 32°F);
- 精确值断言:后续 5 条全部使用
assert.strictEqual,要求返回值与期望值严格相等,不允许近似。
挑战题文件规范:frontmatter 与分节标记
这道题的源文件完整展示了 freeCodeCamp 课程挑战题的 Markdown 规范格式。文件由三部分构成:
1. frontmatter 元数据
--- id: 56533eb9ac21ba0edf2244b3 title: Convert Celsius to Fahrenheit challengeType: 1 forumTopicId: 16806 dashedName: convert-celsius-to-fahrenheit ---各字段含义:
id:题目全局唯一标识,同时是文件名(56533eb9ac21ba0edf2244b3.md),课程区块 JSON 中即通过该 id 引用题目;title:题目展示标题;challengeType: 1:题型编号。对照 challenge-types.ts,数值1对应常量js(JavaScript 经典题)。该文件同时定义了题型到视图和提交方式的映射:viewTypes中js映射为'classic'(经典单文件编辑器视图),submitTypes中js映射为'tests'——即提交后运行测试用例判分,这正是上文 6 条断言被执行的机制来源;forumTopicId:对应的社区论坛讨论区编号,用于把题目页面与官方论坛的讨论串关联起来;dashedName:URL 友好的短横线命名,用作学习页面路径的一部分。
2. 分节标记(# --xxx--)
文件正文使用一组约定的二级分节标记组织内容,本题中依次出现:
| 分节 | 作用 |
|---|---|
# --description-- | 题目描述,渲染到题面区 |
# --hints-- | 提示区内容,同时也是测试用例的书写位置(每条 hint 含一句人话说明 + 一段js代码块) |
# --seed--/## --seed-contents-- | 编辑器初始种子代码 |
# --solutions-- | 官方参考解答 |
这种"一个 Markdown 文件 = 题面 + 测试 + 种子代码 + 解答"的自包含结构,配合 challenge-schema.js 中对challengeType: Joi.number().min(0).max(33).required()的校验(题型编号范围 0–33,与challenge-types.ts中定义的最大值freeCodeCampOsCert = 33吻合),构成了课程仓库对挑战题文件的格式约束。
从题型体系看这道题的判分链路
结合 challenge-types.ts 的源码可以还原这类题目的完整生命周期:
- 内容组织:题目以 Markdown 存放在
curriculum/challenges/english/blocks/basic-algorithm-scripting/下,区块顺序由curriculum/structure/blocks/中的 JSON 决定; - 题型路由:
challengeType: 1被解析为js类型,viewTypes[js] = 'classic'决定前端使用经典代码编辑器组件; - 提交判分:
submitTypes[js] = 'tests'表示点击完成后,用户代码连同# --hints--中的断言(assert.isNumber/assert.strictEqual)一起在沙箱中执行,全部通过才计为完成; - 解答可见性:
hasNoSolution列表中不包含js类型,因此本题在解答可见策略中属于"可查看官方解答"的经典题。
小结:这道入门题的完整知识地图
- 要解决的数学:
fahrenheit = celsius * (9 / 5) + 32,一个乘法加加法的线性变换; - 要写出的代码:仅一行赋值
let fahrenheit = celsius * (9 / 5) + 32;,保持函数签名与return fahrenheit不变; - 要通过的测试:1 条
isNumber类型检查 + 5 条strictEqual精确值断言(-30→-22、-10→14、0→32、20→68、30→86); - 背后的课程机制:frontmatter 声明
id/challengeType: 1,challenge-types.ts将其路由到 classic 视图与 tests 提交方式,区块 JSON 决定它在认证中的顺序。
这道题虽然只有一行核心代码,但它恰好是观察 freeCodeCamp 课程仓库"内容即数据"设计(Markdown 挑战题 + JSON 结构 + 共享题型配置)的最小完整样本:从题目内容、判分测试到题型路由,全部可以在仓库中溯源验证。
【免费下载链接】freeCodeCampfreeCodeCamp.org's open-source codebase and curriculum. Learn math, programming, and computer science for free.项目地址: https://gitcode.com/GitHub_Trending/fr/freeCodeCamp
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考