第 2 章 · 让数据进入程序
变量、输入与预算计算
第一章的欢迎卡只能显示写死的文字。本章让使用者输入活动数据,让同一个程序计算不同活动的预算,并通过多组数据检查结果是否可信。
- 预计阅读
- 55 分钟
- 上机实践
- 90 分钟
- 前置知识
- 第 1 章
- 本章产出
- 个人预算计算器
学完本章,你应该能够
- 解释变量与赋值,并为活动数据取清楚的名字。
- 区分
str、int、float,知道input()返回字符串。 - 将输入转换为合适的类型,写出剩余预算和人均预算公式。
- 使用 f-string 输出有说明文字、金额保留两位小数的报告。
- 先写预期,再用正常值、边界值和错误值检验程序。
2.1 从固定文字到可变数据
第 1 章的欢迎卡把社团名称、时间和地点直接写进 print()。如果换一个活动,就得修改源代码。现在考虑一张预算单:活动名称、总预算、预计人数和已支出都可能变化。我们希望只修改输入数据,程序本身仍然能使用。
先把任务说清楚:使用者输入四项数据;程序计算“剩余预算”和“预计人均预算”;最后输出一份可核对的报告。
| IPO | 本章预算问题 | 示例 |
|---|---|---|
| 输入 | 活动名称、总预算、预计人数、已支出 | 迎新晚会、2000、40、760 |
| 处理 | 剩余 = 总预算 − 已支出;人均 = 总预算 ÷ 人数 | 1240、50 |
| 输出 | 带名称与单位的预算报告 | 剩余 1240.00 元 |
这里的“预计人均预算”是总预算除以预计人数,不是已支出除以人数,也不是剩余预算除以人数。写公式前必须先确定业务含义。
2.2 变量与赋值
变量让程序中的数据有名字。下面三行分别把活动名称、总预算和预计人数关联到三个名称。之后的代码可以通过名称使用这些值。
activity_name = "迎新晚会"
total_budget = 2000.0
expected_people = 40
print(activity_name, total_budget, expected_people)迎新晚会 2000.0 40
赋值语句的形式是 名称 = 表达式。解释器先计算右边,再让左边的名称指向计算结果。这里的等号表示赋值,不是数学中的“左右永远相等”。
remaining_budget = total_budget - spent_amount读这行代码时,先读右边:取出 total_budget 与 spent_amount 的当前值并相减;再读左边:把结果交给 remaining_budget。
变量的值可以更新
remaining_budget = 1240.0
remaining_budget = remaining_budget - 200.0
print(remaining_budget)1040.0
第二行用旧值 1240.0 参与右侧计算,得到 1040.0,再让同一个名字指向新结果。变量并不是一个永远不变的数学符号。
在 Python 中,名称关联到对象;重新赋值会让名称关联到另一个对象。现阶段用“保存值”理解简单程序即可,但遇到多个名称时,“标签”模型更准确。
first = "摄影社"
second = first
first = "音乐社"
print(second)摄影社
second 在第二行关联的是原来的字符串。后来修改 first,并不会自动修改 second。
2.3 给变量取好名字
变量名同时服务计算机和阅读代码的人。名称合法只是最低要求;能够表达数据的含义,才方便检查公式和修改程序。
| 名称 | 结果 | 原因 |
|---|---|---|
total_budget | 推荐 | 小写单词用下划线连接,含义清楚 |
budget2 | 合法 | 数字可以出现在后面,但含义不够明确 |
2budget | 错误 | 不能以数字开头 |
total budget | 错误 | 名称中不能有空格 |
total_budget 与 Total_Budget | 两个名称 | Python 区分大小写 |
本课程采用 snake_case 风格:小写英文单词之间用下划线连接。名称可以使用字母、数字和下划线,但不能以数字开头,也不能使用 Python 关键字。还应避免把 input、print、int、float 当作普通变量名,否则会遮蔽这些内置函数。
input = "迎新晚会"
activity_name = input("活动名称:")执行第二行时,input 已被第一行改为字符串,再把它当函数调用会得到 TypeError。如果在交互控制台中试过这段错误代码,重新启动控制台可恢复原来的内置名称。
2.4 str、int 和 float
程序需要知道一项数据是文字还是数字,因为不同类型支持的操作不同。本章先用三种最常见的类型。
| 类型 | 例子 | 适合表示 | 预算程序中的数据 |
|---|---|---|---|
str | "迎新晚会" | 文本、编号 | 活动名称 |
int | 40 | 完整个数 | 预计人数 |
float | 2000.0 | 可能含小数的数值 | 总预算、已支出 |
一串数字不一定是数值。例如学号 "026012345" 需要保留开头的 0,也不参与加减,更适合用字符串。反过来,预算 "2000" 看上去像数字,但只要有引号,它仍是字符串。
print(type("2000"))
print(type(40))
print(type(2000.0))<class 'str'> <class 'int'> <class 'float'>
type() 可以帮助观察类型。项目程序不必显示这些类型;判断类型的目的,是决定后面能否正确计算。
本章用 float 完成入门预算练习。浮点数在计算机中可能有极小的表示误差;:.2f 只是把报告显示为两位小数。真正的财务结算还要考虑更严格的金额表示方法。
2.5 使用 input() 接收数据
input() 让程序暂停,显示提示并等待使用者键入内容。按下回车后,它把键入的内容作为字符串返回。提示文字应当说明要输入什么,以及必要的单位。
activity_name = input("活动名称:")
print(f"正在处理:{activity_name}")活动名称:迎新晚会 正在处理:迎新晚会
上面的运行结果中,“迎新晚会”是使用者键入的内容。复制代码时只会复制源代码,不会复制示例输入。
输入 40,为什么还不能直接计算?
people = input("预计人数:")
print(type(people))预计人数:40 <class 'str'>
键盘传来的首先是字符。解释器无法只凭外观判断 40 是人数、房间号还是编号,所以 input() 一律返回 str。如果后续要做数值计算,需要显式转换。
2.6 把输入文本转换成数字
人数应当是整数,金额可能有小数。分别用 int() 和 float() 转换;从内到外读嵌套调用。
expected_people = int(input("预计人数:"))
total_budget = float(input("总预算(元):"))input("预计人数:")等待输入,假设返回字符串"40"。int("40")得到整数40。=让expected_people关联到这个整数。
不转换会发生什么
people = input("预计人数:")
print(people + 1)预计人数:40 TypeError: can only concatenate str (not "int") to str
这里的 people 是字符串,不能直接与整数 1 相加。应在输入时使用 int(input(...))。如果把两个字符串相加,得到的是拼接,而不是数值加法:"40" + "1" 的结果是 "401"。
三种常用的显式转换
| 写法 | 得到的值 | 类型 |
|---|---|---|
int("40") | 40 | int |
float("2000.5") | 2000.5 | float |
str(40) | "40" | str |
转换函数会返回一个新值,原来的字符串不会因为调用了 int() 就自行改变。只有把返回值赋给变量,后续代码才会通过这个变量取到转换后的数据。
int("四十")、float("两千") 都会出现 ValueError。本章先要求使用者按提示输入可转换的数字,并把错误输入记录在测试表中;后续章节再学习程序怎样主动处理它。
2.7 用算术表达式写出公式
先用自然语言确认计算口径,再把它写成由变量和运算符组成的表达式。Python 会先计算右侧,随后赋值给左侧。
| 运算符 | 含义 | 例子 |
|---|---|---|
+ | 加法 | venue_cost + material_cost |
- | 减法 | total_budget - spent_amount |
* | 乘法 | unit_price * quantity |
/ | 除法 | total_budget / expected_people |
( ) | 明确优先顺序 | (venue_cost + material_cost) / people |
total_budget = 2000.0
spent_amount = 760.0
expected_people = 40
remaining_budget = total_budget - spent_amount
cost_per_person = total_budget / expected_people
print(remaining_budget)
print(cost_per_person)1240.0 50.0
本例中 cost_per_person 表示“总预算折算到每人”的预计金额;实际支出的人均数是另一项指标,不能混在一起。若要先把场地费和材料费相加再除以人数,应写 (venue_cost + material_cost) / expected_people。括号让计算意图清楚可见。
2.8 用 f-string 输出可读报告
只输出 1240.0,读者无法判断它是什么。f-string 让文字与变量值出现在同一行:字符串前加 f,花括号中写表达式。
activity_name = "迎新晚会"
remaining_budget = 1240.0
print(f"{activity_name}剩余预算:{remaining_budget} 元")迎新晚会剩余预算:1240.0 元
金额通常需要统一显示两位小数。在花括号中写 :.2f:
remaining_budget = 1240.0
print(f"剩余预算:{remaining_budget:.2f} 元")
print(remaining_budget)剩余预算:1240.00 元 1240.0
第一行显示两位小数,第二行仍打印变量原本的值。这说明 :.2f 控制的是输出格式,并没有改变变量。f-string 中的花括号和冒号都要使用英文符号。
2.9 完成活动预算计算器
现在把输入、转换、计算与输出串成一份完整程序。请先阅读四段结构,再复制或亲手敲入 Spyder。文件保存为 budget_calculator.py 后,从第一行运行。
# 第2章:活动预算计算器
activity_name = input("活动名称:")
total_budget = float(input("总预算(元):"))
expected_people = int(input("预计人数:"))
spent_amount = float(input("已支出(元):"))
remaining_budget = total_budget - spent_amount
cost_per_person = total_budget / expected_people
print()
print("=" * 32)
print(f"活动名称:{activity_name}")
print(f"总预算:{total_budget:.2f} 元")
print(f"预计人数:{expected_people} 人")
print(f"已支出:{spent_amount:.2f} 元")
print(f"剩余预算:{remaining_budget:.2f} 元")
print(f"预计人均预算:{cost_per_person:.2f} 元")
print("=" * 32)活动名称:迎新晚会 总预算(元):2000 预计人数:40 已支出(元):760 ================================ 活动名称:迎新晚会 总预算:2000.00 元 预计人数:40 人 已支出:760.00 元 剩余预算:1240.00 元 预计人均预算:50.00 元 ================================
- 1输入与转换
活动名称保持字符串,金额转浮点数,人数转整数。
- 2计算
两条公式分别得到剩余预算与预计人均预算。
- 3报告
逐项显示名称、单位和金额格式,便于人工核对。
- 4复测
换一组数据从头运行,确认程序确实可复用。
人均预算使用 total_budget / expected_people。变量名沿用课堂课件中的 cost_per_person,报告标签明确写作“预计人均预算”。
2.10 测试与排错
一次运行成功,只能说明某一组数据得到了结果。测试要先写“预期”,再输入数据,最后把“实际”与预期逐项对照。
| 类别 | 输入:预算 / 人数 / 已支出 | 预期结果 | 检查目的 |
|---|---|---|---|
| 正常值 | 2000 / 40 / 760 | 剩余 1240.00;人均 50.00 | 验证两条基本公式 |
| 边界值 | 800 / 1 / 800 | 剩余 0.00;人均 800.00 | 验证人数为 1、余额为 0 |
| 错误值 | 800 / 0 / 100 | ZeroDivisionError | 记录当前程序的限制 |
第三组不是“通过”的测试,而是明确发现当前程序无法处理零人数。它不会自动给出解释性提示;修复这类问题需要后续学习的条件判断。也可以另测输入“八百”时的 ValueError,记录发生在哪一行。
根据错误类型缩小范围
| 错误或现象 | 优先检查 | 例子 |
|---|---|---|
NameError | 变量是否先赋值,拼写是否一致 | total_buget 少了字母 d |
TypeError | 运算两侧的数据类型 | 字符串人数参与除法 |
ValueError | 输入能否转换成目标类型 | float("八百") |
ZeroDivisionError | 除数是否为 0 | total_budget / expected_people |
| 能运行但结果不对 | 公式口径、变量名和测试预期 | 把已支出错写成总预算 |
2.11 练习与个人任务
先想一想
- 读代码
执行
budget = 1000; budget = budget - 250; print(budget)后输出什么?等号在第二句中做什么?查看答案
输出
750。先用旧值减去 250,再把新结果赋给同一个名称。 - 判断类型
学号
"026012345"、预计人数40、预算2000.50分别适合什么类型?查看答案
分别是
str、int、float。是否参与数值计算比外观更重要。 - 修复输入
people = input("人数:")后,怎样让total_budget / people可以计算?查看答案
使用
people = int(input("人数:")),并输入非零整数。零人数仍会产生除零错误。 - 解释格式
f"{amount:.2f}"会不会把amount永久改成两位小数?查看答案
不会。它只控制这一处显示出来的字符串。
制作自己的活动预算计算器
每位学生独立完成、测试并解释一份程序。活动名称和数据由自己选择;同伴可以临时互测,但源文件、测试记录与讲解都由本人提交。
最低要求
- 接收活动名称、总预算、预计人数和已支出四项输入。
- 正确转换数值类型,计算剩余预算与预计人均预算。
- 输出含单位的报告,金额显示两位小数。
- 写下至少三组数据的“输入—预期—实际—结论”,其中包含一组已知错误值。
- 提交
w02_学号_budget_calculator.py、运行截图与测试记录。
章末检查
- 我知道赋值语句先算右边,再关联左边名称。
- 我能解释为什么
input()的数字输入仍是字符串。 - 我会根据数据用途选择
str、int或float。 - 我能说清“剩余预算”和“预计人均预算”的计算口径。
- 我写下过测试预期,并记录了程序当前不能处理的输入。
延伸阅读:廖雪峰《Python教程》在线 PDF中的“输入和输出”“数据类型和变量”,以及菜鸟教程 Python 3 教程中的基本数据类型、数据类型转换部分。本章按 ClubHub 活动预算任务重新组织示例,并以本课程知识边界为准。