首页
/ freeCodeCamp 课程解读:Drawing a Shape —— 用 Python print 语句在控制台绘制图形的视频课与课后测评全解析

freeCodeCamp 课程解读:Drawing a Shape —— 用 Python print 语句在控制台绘制图形的视频课与课后测评全解析

2026-09-07 13:16:05作者:冯爽妲Honey

本指南围绕 freeCodeCamp 开源课程中 Python 入门阶段的视频课 "Drawing a Shape"(drawing-a-shape-video.md)展开,它是 "Core Primitives in Python"(Python 核心原语)讲座块的第一节课,主题是如何用一条条 print 语句把一个基础图形(三角形)逐行打印到控制台。读完本文,你将掌握本课程在免费课程体系中的结构与文件规范,理解 print() 逐行输出的底层行为,并能逐条剖析其课后测评的四个选项,最终获得可直接在本地运行验证的完整示例代码。

一、这节课在 freeCodeCamp 课程体系中的位置

在深入了解文件本身之前,先看它属于哪个课程模块。根据 block 结构文件 core-primitives-in-python.jsonCore Primitives in Python 是一个 challenge-list 布局的讲座块("blockLabel": "lecture"),共包含 5 个视频课时,按顺序为:

  1. Drawing a Shape
  2. Variables and Data Types
  3. Working with Strings
  4. Working with Numbers
  5. Getting Input from Users

这一块的 helpCategory 为 Python,说明它属于 Python 课程。向上追溯,superblock 结构文件 learn-python-for-beginners.json 列出了 Python 入门认证课程的 8 个块,core-primitives-in-python 位于第二位,前面是 python-setup-first-steps(含 Introduction / Installing Python and PyCharm / Hello World Program 等视频课,见 python-setup-first-steps 目录),后面依次是小型 Python 项目、列表与元组、控制流与函数等。也就是说,"Drawing a Shape" 是学习者完成环境搭建与 Hello World 之后、系统接触 Python 核心原语的第一课,承担着"体验多行输出"的入门角色。

二、挑战文件结构:front-matter、描述与测评区

本课内容存放在课程源文件中,采用 freeCodeCamp 的标准挑战 Markdown 格式:文件头部是 YAML front-matter,之后以 # --description--# --questions-- 分隔教学描述与随堂测评。

front-matter 字段逐项说明

源文档第 1~7 行定义了如下元信息:

字段 含义
id 62baa9d28e8723f635a0093e 挑战全局唯一 ID,用于块内排序、数据库关联与进度追踪
title Drawing a Shape 课程标题,同时展示在学习界面的挑战列表
challengeType 11 挑战类型,11 即 video 类型
videoId vcNZZSeyZkY 视频平台上的外部视频标识
dashedName drawing-a-shape 短横线命名,用于 URL 与文件定位

其中 challengeType 的取值定义在共享包 challenge-types.ts 中:const video = 11(第 13 行)。同一文件中还可以确认 video 类型的三条配套规则:它被列入 hasNoSolution(视频课没有传统意义上的代码答案,见第 75~103 行),其 viewTypesgeneric(渲染为通用视频播放页,第 117 行),submitTypestests(完成以测评通过为准,第 159 行)。

这些约束在课程校验层同样生效。schema 定义 challenge-schema.js 要求所有挑战必须有 challengeType(第 180 行),并且当 challengeType 为 video 时:videoId 为必填(第 294 行附近),questions(随堂测评)也为必填(第 314 行附近)。因此本文件的 videoIdquestions 部分都不是可选项,而是视频课格式的硬性要求。

教学描述与测评区

文件第 9~11 行的描述区只有一句话:

In this video, you will learn how to print a basic shape to the console using print statements.

(在这段视频中,你将学习如何使用 print 语句向控制台打印一个基础图形。)

随后第 13~54 行是 --questions-- 测评区:给出题干"Which of the following is the correct way to print a triangle to the console?"(下面哪个选项是在控制台打印三角形的正确方式),列出 4 个候选答案,最后以 --video-solution-- 标注正确答案序号 4。测评区必须紧跟视频内容,学习者看完视频后选择答案,以此验证是否真正理解了 print 的逐行输出机制。

三、核心知识点:print 是"一语句一行"

本课要解决的第一个概念问题,是为什么打印一个图形需要好几条 print 语句,而不是一条。这与 Python print() 的行为直接相关:

  • print() 每次调用会输出其参数,并默认在末尾追加一个换行符 \n
  • 因此一次调用只产生一行控制台输出;
  • 要构造一个多行的图形(例如 4 层高的三角形),就需要依次执行多条 print,每条负责一行;
  • 在 Python 中,多条 print 顺序执行时,输出会按行自然堆叠,形成"字符画"。

第二个概念是字符串字面量必须用引号包裹。Python 中未经引号的裸字符(如 /|)会被当作表达式解析,/ 会被理解为除法运算符,从而导致语法错误(SyntaxError)。只有写成 " /|" 这样的字符串,斜杠、竖线、空格和下划线才会被原样作为文本输出。

第三个概念同样关键:字符串内部的空格是内容的一部分。字符串 " /|" 开头的三个空格会精确地出现在控制台上,正是这些前置空格决定了每一行图形的水平偏移,从而勾勒出三角形的斜边。控制台图形的核心技巧,就是精心计算每行字符串内的前置空格数量。

本课目标图形

四个选项都围绕同一个目标形状展开——一个由 /(斜边)、|(垂直边)与 _(底边)组成的直角三角形,期望输出效果如下:

print("   /|")
print("  / |")
print(" /  |")
print("/___|")

运行后控制台显示:

   /|
  / |
 /  |
/___|

如果对齐四个字符画观察坐标系:第一行 / 位于第 4 个字符、第二行第 3 个、第三行第 2 个、第四行第 1 个,/ 每次左移一列,形成一条平滑的斜边;而 | 始终固定在同一列,构成竖直的直角边;末行用 _ 填充斜边与竖直边之间,构成底边。

四、课后测评:四个选项逐条剖析

本课测评要求选出"打印三角形的正确方式",正确答案是第 4 个选项(--video-solution--4)。下面把四个选项逐一拆解,弄清它们为什么错、为什么对。

选项 1:所有内容塞进一条 print

print("   /|  / |  /  | /___|")

这条语句语法合法,但只调用了一次 print,因此控制台上只会出现一行长文本 /| / | / | /___|。三角形被横向"摊平"在同一条线上,且各段之间的空格数不一致(1、2、1 个),根本无法还原图形轮廓。它违背了"一个图形行对应一条 print"的核心原则。

选项 2:漏掉引号

print(   /|)
print(  / |)
print( /  |)
print(/___|)

这组代码结构上分成了 4 行,思路正确,但致命错误是字符串没有加引号。Python 解释器看到裸的 / 会尝试把它当作运算符解析, /| 并不是合法表达式,会直接抛出 SyntaxError,程序根本无法运行。这一选项同时也说明了本课反复强调的"字符串必须加引号"这一前提。

选项 3:斜边没有逐行左移

print(" /|")
print(" / |")
print(" /  |")
print("/___|")

这组代码每条都加了引号、也分了行,语法完全正确。但观察每行的 / 位置:前三行的 / 都停留在同一列,只有最后一行的 / 才跳到最左边,而竖直边 | 的位置每一行都不同。这样的字符画无法形成一条连续的斜边,视觉上只是几条参差不齐的散线,而不是一个规整的三角形。

选项 4:正确答案

print("   /|")
print("  / |")
print(" /  |")
print("/___|")

这是唯一同时满足三个条件的写法:

  1. 引号完整:每个字符串都正确加引号,可正常执行;
  2. 逐行打印:4 次 print 对应图形的 4 行,利用默认换行实现行堆叠;
  3. 空格精确:前置空格从 3、2、1 到 0 逐行递减,使 / 组成的斜边平滑左移,同时 | 始终对齐在同一列。

因此它是四个选项中唯一能在控制台正确呈现三角形的方式,也正是 --video-solution-- 取值为 4 的原因。

五、同一思路的延伸:让"图形打印"更灵活

掌握了"一语句一行 + 引号内空格即内容"之后,可以在不改变本课主题的前提下做几组小练习,加深对输出的掌控(以下为便于验证自行编写,非课程视频内容的转述):

延伸 1:用字符串重复生成对称图形

print 中可以使用字符串乘法快速生成重复字符。下面用 * 运算符构造一个逐行变宽的等腰三角形:

for i in range(1, 5):
    print(" " * (5 - i) + "*" * (2 * i - 1))

输出:

    *
   ***
  *****
 *******

这里同时用到了两个知识点:" " * n 生成前置空格(延续本课的偏移思想),"*" * m 生成本行的星号内容。

延伸 2:用三引号一次性输出多行

当图形行数固定且不需要循环时,Python 的多行字符串(三引号)也能实现同样效果,但要注意它会引入字符串内部的换行:

print("""   /|
  / |
 /  |
/___|""")

输出与本课目标完全一致。对比可知,"多条 print"与"一条多行字符串"各有适用场景:前者适合用循环动态生成,后者适合静态整块输出。

延伸 3:用 end 参数控制行尾

print 默认以换行结束,但它的 end 参数可以改写行尾字符。例如下面用空格作结尾,在一行内铺开图形:

print("   /|", end="  ")
print("  / |", end="  ")
print(" /  |", end="  ")
print("/___|")

理解 end 默认值为 "\n",也就理解了一开始"为什么一条 print 只输出一行"。

六、本地验证与仓库内的校验机制

本课没有传统意义上的"可提交代码"(video 类型在 challenge-types.ts 中属于 hasNoSolution),其测评在课程前端以选择题形式作答。如果你想本地验证选项 4 的输出,只需把对应 4 行代码保存为 shape.py,然后用 Python 解释器执行即可:

python3 shape.py

(若系统默认命令为 python,替换即可;本课代码不依赖任何第三方库。)

至于课程文件本身是否合法,则交由课程工具链校验。freeCodeCamp 仓库的 schema 校验代码 challenge-schema.js 与其配套测试 challenge-schema.test.mjs 会对所有挑战文件做结构化检查,例如 videoIdquestions 是否在 video 类型下齐全;challengeTypes 常量则被 challenge-types.ts 集中维护。若你修改了本文件的 front-matter(例如误删 videoId 或把 challengeType 改成其他数字),这些测试便会失败,从而保证视频课的格式在长期演进中保持一致。

七、小结

"Drawing a Shape" 作为 Python 入门讲座块的第一个课时,用"在控制台画一个三角形"这件小事,把 print 的逐行输出、字符串必须加引号、字符串内空格即内容这三点讲透。其挑战源文件 drawing-a-shape-video.md 同时展示了 freeCodeCamp 视频课的标准文件结构——YAML front-matter 声明类型与视频 ID,description 描述学习目标,questions 与 video-solution 承载随堂测评。理解这一课的知识点与文件规范,既有助于你掌握 Python 的基础输出能力,也能帮你读懂整个 freeCodeCamp 课程体系中同类视频课的存储与校验方式。

登录后查看全文
热门项目推荐
相关项目推荐