Python 环境加载中…

记账本 v1

4 道练习题·预计 60 分钟·做对一题解锁下一段

完整通读本章 →

教学 01 / 10· 已读

前言

前面三章,我们学了列表、元组、字典、集合,还学了条件判断和循环。

学到这里,各位童鞋是不是有种感觉:脑子里装了一堆零件,每个零件都认识,可真要拼成一个能用的程序,又不知道从哪儿下手?

其实,这时候缺的往往不是语法,而是拆问题的习惯。

什么叫拆问题呢?就是写程序之前,先用大白话把要做的事一条一条写下来,再看看每一条该用学过的哪个零件。拆清楚了,写代码基本上就是照着翻译。

光说不练可不行。这一章,咱们还是拿实战 1 的记账本来练手。它现在只能记一笔,而且程序一结束,记过的账也就忘了。我们要让它一口气记下一整天的账,最后还能告诉你:钱都花到哪儿去了。

代码会比实战 1 长不少,第一遍写不对很正常。别急着看答案,先对照流程,把程序一步一步走一遍,看看是哪一步出了岔子。自己找出来的问题,比直接看答案记得牢多了。

学这一章之前,需要先学完 实战 1 的记账本 v0,以及第 3~5 章的列表、字典、条件判断和循环。哪里卡住了,就回到对应的章节看一看:第 3 章 、第 4 章 、第 5 章 。

目录

这一章会学到:

  • 一、一天要记好几笔,怎么办?——看看记账本 v0 差在哪儿
  • 二、先别写代码,把需求拆开——用大白话写出步骤,再画成流程
  • 三、一笔账怎么存?——两个列表为什么容易对不上,换成「列表里装字典」
  • 四、让程序一直问下去——用 while True 加 break ,输入「完」就结束
  • 五、钱都花哪儿了?——用字典按类别汇总
  • 六、常见坑
  • 七、自己查一次文档——dict.items() 到底返回了什么
  • 八、记账本 v1
  • 九、小结与回看

学完这一章,你的记账本可以一口气记下一整天的账,列出每一笔明细,再按类别算出各花了多少钱。

教学 02 / 10· 已读

一、一天要记好几笔,怎么办?

咱们先回顾一下,实战 1 写出来的记账本 v0 是这样的:

Python· 可在网页运行
item = input('买了什么:')
cost = float(input('花了多少钱:'))
print(f'记下了:{item},{cost:.2f} 元')

输出的结果:

文本
买了什么:奶茶
花了多少钱:12.5
记下了:奶茶,12.50 元

问题很明显:它只能记一笔。可一天下来,早饭、地铁、午饭、奶茶……少说也有五六笔。

那么,照着样子多写几遍 input() ,行不行呢?

Python· 语法示意
item1 = input('买了什么:')
cost1 = float(input('花了多少钱:'))
item2 = input('买了什么:')
cost2 = float(input('花了多少钱:'))
item3 = input('买了什么:')
cost3 = float(input('花了多少钱:'))
# ……今天要是记了 8 笔呢?

写是能写,可问题马上就来了:

  • 每天花几笔是不固定的,今天 3 笔,明天可能 8 笔。代码里到底写几个 input() ?
  • 变量 item1 、item2 、item3……越写越多,最后算合计时,还得一个一个加起来。

是不是发现,这两个问题,前面几章其实都给过办法?

  • 数量不固定、要装很多个东西,用列表。
  • 同样的事要做很多遍,用循环。

所以这一章要做的,就是这件事:用列表把账装起来,用循环一笔一笔地问,记完了再汇总。

不过,先别急着写代码。动手之前,还有一件更要紧的事要做,下一节就来说。

教学 03 / 10· 已读

二、先别写代码,把需求拆开

上一节说,先别急着写代码。为什么呢?因为很多童鞋一拿到题目,就直接打开编辑器开始敲。敲着敲着就乱了:这个变量放循环里面还是外面?什么时候停下来?合计又在哪儿算?

其实,写代码之前,先用大白话把要做的事写下来,很多问题自己就清楚了。

不信咱们试一试。假设没有电脑,你拿着一个小本子帮朋友记账,会怎么做?

  1. 准备一个空本子。
  2. 问朋友:买了什么?
  3. 朋友说「完了」,就不再问了,直接跳到第 6 步。
  4. 再问:花了多少钱?
  5. 把这一笔写到本子上,回到第 2 步接着问。
  6. 把本子上的每一笔念一遍,再加起来算个总数。

这几步,就是程序要做的事。把它们画成流程,中间那一圈「问了又问」就看得更清楚了:

文本
① 准备一个空账本
② 问:买了什么?
     ├─ 回答「完」:跳到 ⑤
     └─ 其他回答:往下走
③ 问:花了多少钱?
④ 把这一笔记进账本,回到 ②
⑤ 列出每一笔,算出合计

画成流程的时候,清单里的第 3 步并进了第 ② 步,变成了它下面的两个分叉,所以流程比清单少了一步。

流程有了,接下来,给每一步找一个学过的零件,也就是看看每一步该用什么来写:

要做的事用什么
准备一个空账本空列表 entries = []
一遍一遍地问循环
回答「完」就不问了if 判断,再用 break 跳出循环
记一笔账列表的 append()
算合计再用一次循环,把金额一笔一笔加起来

你会发现,表格右边那一栏,全是前面几章学过的东西,没有一样是新的。

不过,还有一个问题表里没回答:「一笔账」本身该怎么存?它有名称、有金额,后面还要加上类别。这几样东西怎么放在一起,就是下一节要解决的问题。

教学 04 / 10

三、一笔账怎么存?

上一节留下了一个问题:一笔账该怎么存?先想想,一笔账至少有两样东西:买了什么、花了多少钱。

最先想到的办法,可能是用两个列表,一个存名称,一个存金额:

Python· 可在网页运行
items = ['奶茶', '地铁', '午饭']
costs = [12.5, 4, 25]
print(items[0], costs[0])
print(items[2], costs[2])

输出的结果:

文本
奶茶 12.5
午饭 25

同一个位置上的名称和金额,正好凑成一笔账。看起来没毛病。

可是,要是删掉其中一笔呢?比如地铁那笔记错了,要删掉:

Python· 可在网页运行
items = ['奶茶', '地铁', '午饭']
costs = [12.5, 4, 25]
del items[1]
print(items[1], costs[1])

输出的结果:

文本
午饭 4

午饭怎么变成 4 块钱了?

因为只删了 items 里的「地铁」,忘了删 costs 里的 4 ,两个列表一下子就对不上了。而且程序没有报错,又是一个「不报错的 bug」。

说到底,两个列表要时刻保持一致,每次增删都得记着同时改两处,一不留神就会出错。那么,能不能把一笔账的名称和金额绑在一起,放进同一个东西里呢?

能。第 4 章学的字典,干的正是这个活儿:

Python· 可在网页运行
entry = {'item': '奶茶', 'cost': 12.5}
print(entry['item'])
print(entry['cost'])

输出的结果:

文本
奶茶
12.5

一个字典就是一笔账,用 'item' 、'cost' 这两个键,就能取出名称和金额。

一笔账是一个字典,那很多笔账呢?就是很多个字典。把它们装进一个列表里,再用 for 一笔一笔地打印出来:

Python· 可在网页运行
entries = [
    {'item': '奶茶', 'cost': 12.5},
    {'item': '地铁', 'cost': 4},
    {'item': '午饭', 'cost': 25},
]
for entry in entries:
    print(f"{entry['item']} {entry['cost']:.2f} 元")

输出的结果:

文本
奶茶 12.50 元
地铁 4.00 元
午饭 25.00 元

这段代码里,有个小地方要留意一下:f-string 外面的引号,换成了双引号。为什么要换呢?因为花括号里取键用的是单引号,外面要是也用单引号,Python 3.12 之前的版本会直接报语法错误。新版本虽然不报错,可读起来也很容易看混。

再回到删除的问题。这回要删掉地铁那笔,del entries[1] 一下就行。名称和金额是一起删掉的,不可能再对不上了。

算合计也不难,同样是用循环,一笔一笔地加:

Python· 可在网页运行
entries = [
    {'item': '奶茶', 'cost': 12.5},
    {'item': '地铁', 'cost': 4},
    {'item': '午饭', 'cost': 25},
]
total = 0
for entry in entries:
    total = total + entry['cost']
print(f'合计:{total:.2f} 元')

输出的结果:

文本
合计:41.50 元

total 一开始是 0,循环每转一圈,就把这一笔的金额加上去。是不是和第 5 章算 1 到 100 的和,是一个路子?

账本的样子定下来了。先做一道练习,用 for 循环打印明细、算出合计。下一节,再让程序自己一笔一笔地问。

练习 1 / 4列表里装字典:打印明细和合计题目有问题?

编辑器里的 entries 存了今天的四笔账,每一笔都是一个字典。请用 for 循环把每一笔打印成一行,金额保留两位小数,同时算出合计,最后打印合计。

运行后的输出应该是:

文本
早饭 8.00 元
地铁 4.00 元
午饭 25.00 元
奶茶 12.50 元
合计:49.50 元
main.py
可编辑
做对当前题解锁下一段 ·04

推荐一个,全网最全最友好的中文 AI 编程指南: coding.stormzhang.ai

学习目录