news 2026/9/10 0:37:27

freeCodeCamp Python 每日挑战第 40 题精讲:Photo Storage 的单位换算与整除运算

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
freeCodeCamp Python 每日挑战第 40 题精讲:Photo Storage 的单位换算与整除运算

freeCodeCamp Python 每日挑战第 40 题精讲:Photo Storage 的单位换算与整除运算

【免费下载链接】freeCodeCampfreeCodeCamp.org's open-source codebase and curriculum. Learn math, programming, and computer science for free.项目地址: https://gitcode.com/GitHub_Trending/fr/freeCodeCamp

本篇指南围绕 freeCodeCamp 开源仓库中「Daily Coding Challenges」Python 系列的第 40 道题展开:给定每张照片的大小(MB)与硬盘容量(GB),计算硬盘最多能存储多少张完整照片。文章不仅会逐条拆解官方给出的全部测试用例与解法,还会结合仓库中挑战的存储结构、API 路由与数据校验实现,帮助你理解这类「单位换算 + 向下取整」题目的完整解题链路与工程化背景。读完本文,你既能独立通过这道题,也能掌握 freeCodeCamp 每日挑战从题库到前端展示的运作方式。

一、题目背景:它在 Daily Coding Challenges 体系中的位置

这道题位于仓库的 Python 每日挑战块(block)中,文件路径为 curriculum/challenges/english/blocks/daily-coding-challenges-python/68b1f72371a5ac895ac70a02.md。根据 curriculum/structure/blocks/daily-coding-challenges-python.json 的定义,该块:

  • helpCategoryPython,即题目面向 Python 学习者;
  • usesMultifileEditortrue,学员在多功能编辑器中作答;
  • blockLayoutlegacy-challenge-list,按挑战列表顺序编排;
  • 全块共 200+ 道 Python 小题,从「Vowel Balance」到「Letter and Number Count」,覆盖数值计算、字符串处理、数据结构与算法等主题。

本题Challenge 40: Photo Storage属于该块前 40 道中的一道数值计算题,与其相邻的第 41 题File Storage、第 42 题Video Storage组成了「存储容量换算」小主题,本题目的是让学习者熟练处理跨单位换算整除取整

二、题目描述与约束条件

题目原文要求如下:

给定照片大小(以兆字节 MB 为单位)和硬盘容量(以千兆字节 GB 为单位),返回该硬盘能够存储的照片数量,须满足以下约束:

  • 1 GB 等于 1000 MB;
  • 返回硬盘能够存储的完整照片数量。

据此,题目的函数签名与两个关键约束为:

def number_of_photos(photo_size_mb, drive_size_gb): # photo_size_mb:单张照片大小(MB,可为小数) # drive_size_gb:硬盘容量(GB,可为小数) ...

两点约束值得注意:

  1. 采用十进制换算(1 GB = 1000 MB),而非二进制换算(1 GiB = 1024 MiB)。这是消费级存储设备厂商常用的标称方式,也是本题答案的关键前提——number_of_photos(1, 1)的期望值 1000 直接由 1 GB = 1000 MB 推导而来。
  2. 只返回完整照片数,即对计算结果做向下取整(floor),丢弃不能存下完整一张照片的零头。这一约束决定了必须使用整数除法而不是普通除法。

三、官方测试用例逐条推演

挑战的--hints--部分给出了 5 组断言,全部通过 Python 内置unittest框架执行。我们逐条验证换算逻辑:

({test: () => { runPython(` from unittest import TestCase TestCase().assertEqual(number_of_photos(1, 1), 1000)`) }})
输入(photo_size_mb, drive_size_gb)硬盘容量换算为 MB计算结果期望输出
(1, 1)1 × 1000 = 10001000 ÷ 1 = 10001000
(2, 1)1 × 1000 = 10001000 ÷ 2 = 500500
(4, 256)256 × 1000 = 256000256000 ÷ 4 = 6400064000
(3.5, 750)750 × 1000 = 750000750000 ÷ 3.5 ≈ 214285.71 → 取整214285
(3.5, 5.5)5.5 × 1000 = 55005500 ÷ 3.5 ≈ 1571.42 → 取整1571

观察最后两组用例:照片大小与硬盘容量都是浮点数,除不尽的结果必须向下取整。例如750000 / 3.5 = 214285.714...,只能完整存储 214285 张,第 214286 张会因空间不足而无法容纳——这正是「返回完整照片数量」这一约束的体现。

四、从种子代码到解决方案

挑战为学员提供了种子代码,函数体只有一个占位返回值,等待被替换:

def number_of_photos(photo_size_mb, drive_size_gb): return photo_size_mb

官方解决方案如下:

def number_of_photos(photo_size_mb, drive_size_gb): drive_size_mb = drive_size_gb * 1000 return drive_size_mb // photo_size_mb

其推导思路可分为两步:

第 1 步:统一单位。drive_size_gb * 1000把硬盘容量从 GB 换算为 MB,得到以 MB 为单位的可用总空间drive_size_mb。这一步骤直接落实了「1 GB 等于 1000 MB」的约束。

第 2 步:整除取整。用整数除法运算符//计算drive_size_mb // photo_size_mb,得到能存储的完整照片数。//会对商向下取整,天然满足「返回完整照片数量」的要求,无需再调用int()math.floor()

为什么用//而不是/int()

写法(3.5, 750)的结果是否符合要求
drive_size_mb / photo_size_mb214285.71428571428(浮点数)否,不是整数
int(drive_size_mb / photo_size_mb)214285是,但多一步转换
drive_size_mb // photo_size_mb214285(直接整除)是,最简洁

对于正数而言,int(x / y)x // y结果一致;但//语义更清晰、性能更优,且能直接处理浮点操作数(Python 的//支持浮点数向下取整),是本题最合适的运算符。

边界情况与可扩展讨论

  • 照片大小大于硬盘容量:如number_of_photos(2000, 1),换算后1000 // 2000 = 0,返回 0,逻辑正确。
  • 照片大小等于硬盘容量:如number_of_photos(1000, 1)1000 // 1000 = 1,恰好存一张。
  • 小数照片大小:如number_of_photos(0.5, 1)1000 // 0.5 = 2000,浮点数整除依然成立。
  • 工程化改进:若未来约束改为二进制换算(1 GiB = 1024 MiB),只需将常量 1000 替换为 1024;若要求返回「还能剩多少 MB」,可补充取余运算drive_size_mb % photo_size_mb

五、在 freeCodeCamp 中挑战是如何被检验与运行的

这道题并非静态文本,而是 freeCodeCamp「Daily Coding Challenges」线上功能的一部分。其验证机制与工程链路可以从仓库源码中得到印证:

1. 测试以runPython方式注入

文档的--hints--使用runPython(...)在学员代码环境中执行unittest断言(见 challenge 文件)。每一条 hint 都是一次独立的TestCase().assertEqual(...)调用,5 组用例全部通过后挑战才算完成。

2. 数据库中的结构校验

每日挑战从题库数据库读出后,前端会用 Joi 对数据结构做严格校验。见 client/src/utils/daily-coding-challenge-validator.ts:每条挑战必须包含idchallengeNumbertitledatedescription,以及javascriptpython两种语言的tests(含texttestString)和challengeFiles。也就是说,本题在数据库中会同时保存 Python 的种子代码与测试字符串,供每日挑战组件读取渲染。

3. 后端 API 按日期提供挑战

挑战内容通过 API 对外提供,路由实现在 api/src/daily-coding-challenge/routes/daily-coding-challenge.ts,包括:

  • GET /daily-coding-challenge/today:返回今天的挑战;
  • GET /daily-coding-challenge/date/:date:按YYYY-MM-DD返回指定日期的挑战(晚于最后挑战日期会返回 404);
  • GET /daily-coding-challenge/day/:day:按MM-DD返回(自动映射到最近的源日期);
  • GET /daily-coding-challenge/month/:month:按YYYY-MM返回当月挑战列表;
  • GET /daily-coding-challenge/allGET /daily-coding-challenge/newest:分别返回全部挑战与最新挑战日期。

值得注意的细节是:所有路由都以美国中部时间(US Central)为「今天」的判定基准,且不会返回日期晚于今天的挑战——这意味着 Photo Storage 这类题目只有在排期日期到达后才会对学习者开放。

4. 题库是如何种入数据库的

题库种子脚本位于 tools/daily-challenges/README.md:脚本通过 GraphQL 从启用了「upcoming changes」的客户端获取「Dev Playground」超级块中的挑战,写入 MongoDB 的DailyCodingChallenges集合。运行前需将 tools/daily-challenges/sample.env 复制为.env并配置MONGOHQ_URL,然后在tools/daily-challenges目录下执行:

pnpm seed-daily-challenges

前端展示组件位于 client/src/components/daily-coding-challenge/,其中widget.tsx负责当日挑战的答题小部件,calendar.tsx提供按月历查看历史挑战的入口。至此,「题库 Markdown → 种子脚本 → MongoDB → API → 前端组件」的完整链路便闭环了。

六、小结与举一反三

本题Photo Storage的核心考点可以浓缩为一句话:先统一单位(GB → MB),再用整数除法取整。它同时训练了三项基本功:

  1. 单位换算意识:识别题目给定的换算率(1 GB = 1000 MB),切勿想当然地套用 1024;
  2. 整除语义:理解「完整数量」等价于向下取整,选择//而非/
  3. 浮点输入处理:Python 的//*都能透明处理浮点数,使代码在整数与小数输入下均保持一致行为。

如果你已完成此题,不妨继续挑战同块的 第 41 题 File Storage 与 第 42 题 Video Storage,它们的核心思路与本题一脉相承:同样是「单位换算 + 容量分配」,但在数据维度上做了延伸,能帮助你巩固这类存储计算题的通用解法。

【免费下载链接】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),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 0:21:39

KMS权限故障排查实录:区块链验证节点签名中断的隐形陷阱

接手这条链的第五天,我盯着一台明明在线、却连续好几轮没能出块的验证节点,日志里反复出现同一段来自 KMS 的报错。报错本身不可怕,可怕的是它不致命——节点进程不崩、网络不断、区块照常同步,只有仔细对比出块记录时&#xff0c…

作者头像 李华
网站建设 2026/9/10 0:21:11

论文降AI率避坑指南:七大常见误区与正确重写方法

先讲个真实场景。工作室里带过的学弟,交完论文初稿来找我,一脸崩溃:“学姐,我这段几乎每个字都改过了,为什么AI检测出来反而比之前更高?”我点开他的稿子一看,第一段写的是“近年来,…

作者头像 李华