从想法到代码 — 单位换算应用与六个最常用部件¶
这一章讲两件事: 一件是流程——一个应用从一句话想法走到能跑的代码,中间要经过哪六道工序; 另一件是工具——完成这些工序会用到的 Streamlit 核心部件(widget,界面上用户能操作的元素)。 读完你能独立完成一个多控件、前后端分离的小应用,并且理解作者为什么最后把按钮删了。
1. 这一章讲什么¶
前两章是「装环境」和「跑通第一个玩具」。这一章开始像真的做项目: 应用是单位换算器(选类别 → 选两个单位 → 输入数值 → 出结果)1。
作者刻意把顺序排成「先几乎不见 Streamlit,最后再写界面」—— 他的理由是:真实世界里,你做图形应用时主要精力在应用本身,不在 UI 框架; Streamlit 的成功恰恰在于它不挡路(gets out of your way)2。 所以这一章的重心其实在第 2–4 节(想法怎么变成设计),代码在第 5 节才出现。
2. 顶层全景:六道工序,和每一道的产出物¶
① 说清概念 ② 定需求 ③ 画体验 ④ 想实现 ⑤ 写代码 ⑥ 迭代
一句话说 要做什么 + 手绘界面 方案取舍 + 前端 + 用起来,
清它是啥 明确不做什么 草图(mock) 逻辑流图 后端 + 接线 边用边改
产出: 产出: 产出: 产出: 产出: 产出:
一句话 需求清单 + 一张草图 换算数学 + 能跑的代码 更好的版本
范围外清单 配置方案
图说:六道工序是一条流水线,但⑥会回头改①–⑤,所以它不是直线,是圈。
书里的原话是「把大象一口一口吃掉」3。每一道都可以按项目大小缩放: 大项目里每道花几周、多人对齐;小项目里需求清单五分钟列完、草图一张纸搞定4。 六道都走,但不必六道都重——这是这一章最容易被误读的地方。
3. 核心原理(一):需求是「要什么」,范围外清单是「不要什么」¶
需求清单(书里的五条):能输入数值和「从」单位;能选「到」单位、且两个单位必须测同一种量; 显示换算结果;同时支持英制/公制内部换算和跨制换算;加新单位要容易5。
三条写法规则值得逐条记住:
- 每条只说能力,不说实现。 「显示换算结果」是需求;「显示一个 Streamlit 按钮」是实现,不许进需求清单6。
- 需求不只来自用户。 书里第五条(加新单位容易)就是开发者的需求—— 维护者才不关心用户要什么,关心的是自己改代码要花几分钟7。 往后还有分析团队(要统计使用)、商业化团队(要订阅收费)这类非用户干系人8。
- 写「不做什么」和写「做什么」同等重要。 你眼里显然的事,用户和协作者会想当然地以为有。 明确写出来,是优先级讨论的起点9。
范围外清单(本章正式写出的两条):不做使用统计、日志、花哨可视化;不做汇率这类 换算因子随时间变的转换(那要接在线 API,复杂度超纲,留给第 05 章)10。
4. 核心原理(二):从用户体验倒推,而不是从代码正推¶
设计从一张草图开始(纸笔、白板、画图软件都行):中间一个数值输入框, 左边一列类别单选(时间/距离/质量/压力),两个单位下拉菜单,一个 Convert 按钮,底下出答案11。
书里的一个判断要单独标出来:画草图时不要先想着「Streamlit 有没有这个部件」—— 那是本末倒置;先想最好的体验是什么,再拿 Streamlit 去实现它。 就算最后发现某个部件缺,调整的过程也会让你更清楚 Streamlit 的短板在哪12。
5. 核心原理(三):换算的数学——为什么只存「到标准单位」一个数¶
这是本章的主线例子,从一次真实的换算走到底。
起点:5 磅是多少盎司? 1 磅 = 16 盎司,5 × 16 = 8013。推广成公式:
问题:每对单位存一个因子,存不起。 20 个长度单位,两两组合有 20×19÷2 = 190 个因子14。
解法:每个类别选一个标准单位,只存「1 个本单位 = 多少个标准单位」。 以米为标准,只存每个单位到米的因子。X → Y 的换算拆成两步:
第 1 步:X 单位的值 × (X→标准单位因子) = 标准单位的值
第 2 步:标准单位的值 ÷ (Y→标准单位因子) = Y 单位的值
具体走一遍:5 码 = ? 厘米
已知:码→米 = 0.9144,厘米→米 = 0.01
第 1 步:5 × 0.9144 = 4.572 米
第 2 步:4.572 ÷ 0.01 = 457.2 厘米
(0.9144 和 0.01 都是书里的真数15。)因子数量从 190 降到 20(每单位一个)—— 这个「用中间单位中转」的思路,和货币兑换里用美元做中介、网络里用 IP 做统一寻址,是同一招。
6. 核心原理(四):配置文件 + 数据类 + 模块——让「加单位」真的容易¶
需求第五条(加新单位容易)落到设计上,就是三个决定:
决定一:所有单位信息集中在一个配置文件里,格式一目了然。 配置还是普通 Python 字典, 但值不再是裸数字,而是对象:
# unit_config.py(照原书 listing 3.4 节选)
from dataclasses import dataclass
@dataclass
class Unit:
abbrev: str # 缩写,如 "kg"
value_in_std_units: float # 1 个本单位 = 多少个标准单位
@dataclass
class Quantity:
std_unit: str # 标准单位名,如 "Kilograms"
units: dict[str, Unit] # 这个量纲下所有单位
unit_config = {
"Mass": Quantity(std_unit="Kilograms", units={
"Kilograms": Unit(abbrev="kg", value_in_std_units=1),
"Grams": Unit(abbrev="g", value_in_std_units=0.001),
"Pounds": Unit(abbrev="lb", value_in_std_units=0.453592),
"Ounces": Unit(abbrev="oz", value_in_std_units=0.0283495),
}),
# Length、Time 同理……
}
dataclass(数据类)是这里唯一的新词。 它是 Python 标准库 dataclasses 模块提供的一种类:
你只声明字段(abbrev: str),它就自动替你生成初始化方法,不用手写 __init__16。
Unit("kg", 1) 之后用 kg.abbrev 点号取字段。省的是样板代码,得的是和手写类一样的行为。
注意类和文件的关系:Unit 放 unit.py,Quantity 放 quantity.py,配置放 unit_config.py——
一个 .py 文件就是一个模块(module),别的文件用 from unit import Unit 引入17。
拆模块的理由书里说得实在:防止所有东西挤在一个吓人的大脚本里,函数和类可以复用18。
而「单位名不在类里、只在配置字典的键里」 是特意设计:名字已经出现一次,再存就是重复19。
决定二:加单位 = 在配置里追加几行,别的文件一律不动。 书里的原话是配置必须是唯一提及具体单位的地方,UI 代码里不许硬编码单位名20。 这一条的威力在第 5 节接线时兑现。
决定三:前后端通过一个契约(API)交互。 书里用了汽车餐厅的例子: 点餐员和后厨只靠「菜单」沟通——后厨换厨师、换原料,只要菜单不变,点餐员就无感; 点餐员换人,只要会念菜单,后厨也无感21。 落到代码上,前端和后端之间只有三个动作:
| API 动作 | 输入 | 输出 | 实现 |
|---|---|---|---|
list_quantities() |
无 | 量纲名列表 | 配置字典的键 |
list_units(quantity_name) |
量纲名 | 该量纲的单位名列表 | 对应 Quantity 的 units 的键 |
convert_value(quantity, from_unit, to_unit, value) |
三样东西 + 数值 | Result 对象 | 两步换算:× from 因子 ÷ to 因子 |
两个细节:返回的 Result 里装了完整的 Unit 对象而不是裸缩写—— 因为「前端拿到结果想怎么显示是它的自由」,这正是关注点分离(separation of concerns, 每个模块只管一件事、互相只在约定的边界上接触)的意思22; 书里也坦白,这里的「API」是最朴素的含义(一份交互契约),和平时说的网络 API 不是一回事23。
7. 核心原理(五):前端部件逐个过——一个应用就是部件的接力¶
前端从占位(dummy)开始:先硬编码把界面搭出来,再逐个替换成后端数据24。 每个部件按「解决什么 → 怎么写 → 屏幕上是什么」过一遍:
st.radio —— 从列表里单选。 st.sidebar.radio("Select a quantity", ["Mass", "Length", "Time"])
在左侧边栏画一组单选钮,返回值是选中的那个字符串25。
顺带认识 st.sidebar:用 with st.sidebar: 块或 st.sidebar.radio(...) 点号写法,
把任何元素放进左侧栏26。
st.text_input —— 单行文本输入。 float(st.text_input("Value to convert", value="0"))——
注意它返回字符串,要当数用得自己转 float27。
st.selectbox —— 下拉选择。 两个下拉框并排,先解决并排:
st.columns 把页面切成若干列,from_col, to_col = st.columns(2) 拿到两个列容器,
再用 from_col.selectbox(...) 点号写法(或 with 块)把元素放进列里28。
index=1 让第二个下拉默认选中第二项,免得两个框默认选同一个单位29。
with 块和点号怎么选:容器里要放多个元素用 with,只放一个、或顺序乱一点,用点号30。
st.button —— 条件元素。 if st.button("Convert"): 里的代码只在「这轮运行恰好按钮被点」时执行,
本章先用 pass 占位31。
接线——把硬编码换成后端调用。 三处替换:st.sidebar.radio(..., list_quantities())、
units = list_units(quantity)、result = convert_value(quantity, from_unit, to_unit, input_num)32。
替换完,选不同量纲时下拉菜单自动跟着变——配置的威力兑现:加一个单位,UI 自动多一个选项,
一行 UI 代码都不用改33。
st.metric —— 结果要有点仪式感。 它是看板部件:标签 + 大号数字 + 涨跌指示(delta)。
from_col.metric("From", "13 lb", delta=None) 隐掉 delta34。
8. 核心原理(六):迭代——两次改动,一次比一次反直觉¶
第一改:修数字的长相。 试 4000 千克换磅,出来一长串小数,用户要先愣一秒35。
解法是 format_value():round() 控制小数位,format(x, ",") 加千分位逗号。
小数位数让用户自己定——新增 st.number_input(数字输入,自带 − / + 步进按钮、可设上下限)。
但只想要整数位数的场合,步进按钮多余,于是又加 st.checkbox:
勾选才出现位数输入框,不勾选就是全精度36。
checkbox 和 button 一样是条件元素:if st.checkbox(...) 决定它下面的代码画不画37。
有个坑当场标注:places = None 要先写在 if 外面,因为后面的代码在 if 外面还要用它38。
第二改:把 Convert 按钮整个删掉。 这是全章最大胆的一步。 按钮只是触发器,而触发器其实多余:改任何输入,结果直接刷新, 用户少点一下,体验反而更直觉39。删掉 if,把换算和显示挪到顶层—— 每改一个输入,脚本重跑,结果跟着变。注意:这一步之所以敢做,恰恰是因为 Streamlit 「输入一变就重跑」的执行模型;换传统框架,删掉按钮你得自己写一堆事件监听。
9. 作者的判断与证据¶
判断:先定理想体验,再管 Streamlit 有没有部件。 依据是「不然你的想象会被工具的既有功能框死」40。 这是设计原则,无对照证据;我们认可它对学习期成立,对交付期要打折—— 真实项目里部件缺口是有交付成本的。
判断:关注点分离 + API 契约是「好习惯」,哪怕小应用收益不明显。 书里明说这是为了真实世界的 大应用养成的习惯41。值得肯定的是它没夸大:本章代码结构对这么小的应用确实「过度设计」, 作者承认收益不明显42。
判断:按钮该删。 依据是用户体验的直觉论证(少一步操作)和 Streamlit 执行模型的天然配合43。 这是我们全书最认同的判断之一,它示范了「根据框架的真实行为重新设计交互」, 而不是把旧框架的习惯搬过来。
10. 边界与局限¶
- 错误处理被刻意略去。
list_units遇到不存在的量纲会直接抛异常; 书里明说真实代码该加检查,本章从简44。照抄本章代码做生产应用会踩这个坑。 - 「写需求」一节对单人小项目的指导密度高于团队协作,多人协作时的需求对齐、 评审流程没展开(这本书的受众设定决定了它点到为止)。
- 两处 Streamlit 的 UI 限制是「当时为真」:st.number_input 的步进按钮没法去掉45、 标签页样式改不了(第 01 章)。这类限制经常随版本松动,用前查当期文档。
- 配置文件用 Python 字典表达,好处是零学习成本,坏处是配置和代码同语言, 没有「配置不是程序」的隔离感;数据量大时该考虑 JSON(一种文本数据格式)、YAML 或数据库(第 08 章)。
判断(我们的,不是书里的): 这一章的教学设计是全书的枢纽之一: 它教的其实不是 Streamlit,而是「约束驱动设计」——需求第五条(加单位容易) 这一条约束,倒逼出了配置文件、数据类、API 契约这一整套结构。 对学编程语言的人来说,这是「非功能性需求如何塑造程序结构」的最佳入门案例: 结构不是从「正确的面向对象」教科书里抄来的,是从「谁要改什么、多久改一次」里长出来的。 如果错,会错在: 这个设计对教学是完美的,但对一次性小脚本确实过重; 「过度设计」的批评在小应用上不成立、在一次性工具上成立—— 两者的分界线(这个应用以后还会不会改)恰恰是该问的第一个问题,书里没问。
11. 可带走的¶
- 六道工序:概念 → 需求(含范围外清单)→ 体验草图 → 实现方案 → 代码 → 迭代;小项目每道都可以缩到几分钟,但顺序别乱。
- 需求只说「要什么能力」,不说「用什么实现」;「不做什么」要和「做什么」一样写下来。
- 单位换算(及一切两两转换):选标准单位中转,因子数从 n×(n−1)/2 降到 n。
- dataclass:声明字段就自动有初始化方法,是写「只装数据的类」的标准做法。
- 拆模块的理由是防「一个吓人的大脚本」;一个 .py 就是一个模块。
- API 契约 = 一份菜单:前后端各换各的实现,菜单不变就行。
- st.radio / st.selectbox 返回选中的值;st.text_input 返回字符串;st.button 和 st.checkbox 是条件元素。
- st.sidebar 和 st.columns 是仅有的两种「打破自上而下排布」的手段(本章范围);容器内多个元素用 with 块,单个用点号。
- st.metric 是「大数字 + 标签 + 涨跌」的结果展示件;st.number_input 自带步进按钮,不想要就别用它。
- 敢删按钮:当框架「输入一变就重跑」,很多显式触发器都可以删——按框架的行为重新设计交互,而不是迁就旧习惯。
12. 原文地图¶
| 主题 | 原书章 | 原文位置 |
|---|---|---|
| 六步流程图与每步说明 | 3 Taking an app from concept to code | text/12-ch03-3-taking-an-app-from-concept-to-code.txt:36搜「six-step」) |
| 小项目可缩放的说明 | 3 Taking an app from concept to code | text/12-ch03-3-taking-an-app-from-concept-to-code.txt:66搜「scale each step down」) |
| 单位换算器概念一句话 | 3 Taking an app from concept to code | text/12-ch03-3-taking-an-app-from-concept-to-code.txt:92搜「A Streamlit app that lets users convert」) |
| 需求清单五条与写法规则 | 3 Taking an app from concept to code | text/12-ch03-3-taking-an-app-from-concept-to-code.txt:105搜「Requirements should」) |
| 范围外清单(不做日志、不做汇率) | 3 Taking an app from concept to code | text/12-ch03-3-taking-an-app-from-concept-to-code.txt:138搜「what the app」) |
| 从用户体验倒推的设计法 | 3 Taking an app from concept to code | text/12-ch03-3-taking-an-app-from-concept-to-code.txt:177搜「work」) |
| 「别被 Streamlit 部件限制想象」 | 3 Taking an app from concept to code | text/12-ch03-3-taking-an-app-from-concept-to-code.txt:235搜「putting the cart before the horse」) |
| 换算因子与 190 个问题 | 3 Taking an app from concept to code | text/12-ch03-3-taking-an-app-from-concept-to-code.txt:262搜「conversion factor」) |
| 标准单位两步换算(5 码→457.2 厘米) | 3 Taking an app from concept to code | text/12-ch03-3-taking-an-app-from-concept-to-code.txt:292搜「0.9144」) |
| 配置文件的「唯一提及」原则 | 3 Taking an app from concept to code | text/12-ch03-3-taking-an-app-from-concept-to-code.txt:350搜「single configuration file」) |
| 汽车餐厅与 API 契约 | 3 Taking an app from concept to code | text/12-ch03-3-taking-an-app-from-concept-to-code.txt:811搜「drive-in fast-food」) |
| Unit / Quantity dataclass | 3 Taking an app from concept to code | text/12-ch03-3-taking-an-app-from-concept-to-code.txt:670搜「dataclass」) |
| 模块与 from unit import Unit | 3 Taking an app from concept to code | text/12-ch03-3-taking-an-app-from-concept-to-code.txt:735搜「Modules promote」) |
| 三个 API 动作 | 3 Taking an app from concept to code | text/12-ch03-3-taking-an-app-from-concept-to-code.txt:864搜「List-quantities」) |
| convert_value 的两步实现 | 3 Taking an app from concept to code | text/12-ch03-3-taking-an-app-from-concept-to-code.txt:981搜「value_in_to_units」) |
| st.radio 与 st.sidebar | 3 Taking an app from concept to code | text/12-ch03-3-taking-an-app-from-concept-to-code.txt:458搜「st.radio」) |
| st.columns 并排下拉框 | 3 Taking an app from concept to code | text/12-ch03-3-taking-an-app-from-concept-to-code.txt:560搜「st.columns」) |
| 接线:list_quantities 替换硬编码 | 3 Taking an app from concept to code | text/12-ch03-3-taking-an-app-from-concept-to-code.txt:1027搜「list_quantities」) |
| st.metric 展示结果 | 3 Taking an app from concept to code | text/12-ch03-3-taking-an-app-from-concept-to-code.txt:1070搜「st.metric」) |
| 4000 千克换磅的位数问题与 format_value | 3 Taking an app from concept to code | text/12-ch03-3-taking-an-app-from-concept-to-code.txt:1144搜「a lot of decimal places」) |
| st.number_input 与步进按钮的取舍 | 3 Taking an app from concept to code | text/12-ch03-3-taking-an-app-from-concept-to-code.txt:1173搜「step buttons」) |
| st.checkbox 条件显示 | 3 Taking an app from concept to code | text/12-ch03-3-taking-an-app-from-concept-to-code.txt:1217搜「st.checkbox」) |
| 删掉 Convert 按钮 | 3 Taking an app from concept to code | text/12-ch03-3-taking-an-app-from-concept-to-code.txt:1243搜「Getting rid of the button」) |
| 错误处理从简的声明 | 3 Taking an app from concept to code | text/12-ch03-3-taking-an-app-from-concept-to-code.txt:928搜「leaves out error handling」) |
-
出处:「3 Taking an app from concept to code」第 82–92 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:92,搜「A Streamlit app that lets users convert」)。原文概念句:「A Streamlit app that lets users convert between different units of measurement」。 ↩ -
出处:「3 Taking an app from concept to code」第 72–80 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:77,搜「gets out of your way」)。 ↩ -
出处:「3 Taking an app from concept to code」第 33–37 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:34,搜「a bite at a time」)。原文引了 Desmond Tutu 的话。 ↩ -
出处:「3 Taking an app from concept to code」第 60–70 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:66,搜「scale each step down」)。 ↩ -
出处:「3 Taking an app from concept to code」第 110–121 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:112,搜「enter a numeric quantity」)。 ↩ -
出处:「3 Taking an app from concept to code」第 105–108 与 133–136 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:107,搜「free of implementation language」)。 ↩ -
出处:「3 Taking an app from concept to code」第 126–132 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:331,搜「non-user requirement」)。 ↩ -
出处:「3 Taking an app from concept to code」第 129–132 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:130,搜「analytics team」)。 ↩ -
出处:「3 Taking an app from concept to code」第 138–146 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:145,搜「vital—and possibly more enlightening」)。 ↩ -
出处:「3 Taking an app from concept to code」第 147–163 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:155,搜「exchange rate changes daily」)。 ↩ -
出处:「3 Taking an app from concept to code」第 186–222 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:187,搜「mock-up」)。figure 3.2 是那张草图。 ↩ -
出处:「3 Taking an app from concept to code」第 232–242 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:235,搜「putting the cart before the horse」)。 ↩ -
出处:「3 Taking an app from concept to code」第 259–262 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:260,搜「16 ounces」)。 ↩ -
出处:「3 Taking an app from concept to code」第 276–282 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:279,搜「190 conversion factors」)。 ↩ -
出处:「3 Taking an app from concept to code」第 290–299 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:292,搜「0.9144」)。两因子与 457.2 的结果均照原文。 ↩ -
出处:「3 Taking an app from concept to code」第 669–702 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:684,搜「don't need to specify a init」)。 ↩ -
出处:「3 Taking an app from concept to code」第 731–736 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:733,搜「file unit.py is a module」)。 ↩ -
出处:「3 Taking an app from concept to code」第 734–736 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:734,搜「avoid putting everything」)。 ↩ -
出处:「3 Taking an app from concept to code」第 798–801 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:707,搜「name field」)。 ↩ -
出处:「3 Taking an app from concept to code」第 349–359 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:352,搜「only file that refers to specific」)。 ↩ -
出处:「3 Taking an app from concept to code」第 810–821 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:811,搜「drive-in fast-food」)。 ↩ -
出处:「3 Taking an app from concept to code」第 806–810 与 936–960 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:807,搜「separation of concerns」)。 ↩ -
出处:「3 Taking an app from concept to code」第 884–890 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:884,搜「simplest sense」)。 ↩ -
出处:「3 Taking an app from concept to code」第 420–424 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:423,搜「build the frontend incrementally」)。 ↩ -
出处:「3 Taking an app from concept to code」第 458–471 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:459,搜「quantity selector」)。 ↩ -
出处:「3 Taking an app from concept to code」第 479–496 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:479,搜「st.sidebar」)。 ↩ -
出处:「3 Taking an app from concept to code」第 510–522 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:518,搜「returns a string」)。 ↩ -
出处:「3 Taking an app from concept to code」第 560–591 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:571,搜「unpacking, and it assigns」)。 ↩ -
出处:「3 Taking an app from concept to code」第 531–554 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:549,搜「index parameter」)。 ↩ -
出处:「3 Taking an app from concept to code」第 586–590 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:586,搜「context manager makes more sense」)。 ↩ -
出处:「3 Taking an app from concept to code」第 594–606 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:596,搜「ol' faithful」)。 ↩ -
出处:「3 Taking an app from concept to code」第 1020–1063 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:1020,搜「Wiring up the frontend and backend」)。 ↩ -
出处:「3 Taking an app from concept to code」第 1048–1053 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:1046,搜「when you pass it a quantity」)。 ↩ -
出处:「3 Taking an app from concept to code」第 1070–1099 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:1072,搜「grand finale」)。 ↩ -
出处:「3 Taking an app from concept to code」第 1136–1148 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:1139,搜「4,000 kilograms」)。 ↩ -
出处:「3 Taking an app from concept to code」第 1149–1204 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:1149,搜「format_value」)。 ↩ -
出处:「3 Taking an app from concept to code」第 1217–1224 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:1220,搜「conditional element」)。 ↩ -
出处:「3 Taking an app from concept to code」第 1226–1235 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:1226,搜「places = None」)。 ↩ -
出处:「3 Taking an app from concept to code」第 1243–1254 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:1246,搜「Do we even need it」)。 ↩ -
出处:「3 Taking an app from concept to code」第 232–242 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:236,搜「Don’t let Streamlit」)。 ↩ -
出处:「3 Taking an app from concept to code」第 879–881 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:881,搜「good habit to develop」)。 ↩ -
出处:「3 Taking an app from concept to code」第 879–881 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:880,搜「benefits may not be obvious」)。 ↩ -
出处:「3 Taking an app from concept to code」第 1244–1253 与 1299–1300 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:1251,搜「more intuitive experience」)。 ↩ -
出处:「3 Taking an app from concept to code」第 926–929 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:926,搜「doesn't handle the case」)。 ↩ -
出处:「3 Taking an app from concept to code」第 1188–1193 段(
text/12-ch03-3-taking-an-app-from-concept-to-code.txt:1190,搜「remove the - and + buttons」)。 ↩