查看全课大纲(第 25 / 51 节)
- 1.为什么人人都该学点编程?
- 2.计算机与程序设计:你的电脑到底在“想”什么?
- 3.Python 这门语言,到底有什么魔力?
- 4.Python 开发环境配置:如何拥有你的第一个“编程工具箱”?
- 5.如何安装一个更强大的代码编辑器?
- 6.汇率兑换1.0:你的第一个“钱生钱”小程序
- 7.你的第一行代码,藏着哪些秘密?
- 8.汇率兑换2.0(上):让程序看懂“CNY”和“USD”
- 9.汇率兑换程序,如何让它“聪明”地判断币种?
- 10.汇率兑换程序能一直运行,直到我喊停吗?
- 11.汇率兑换4.0:如何把“算钱”功能打包成积木?
- 12.汇率兑换5.0:给你的程序穿上“结构化”的西装
- 13.怎么用 Python 画一个会动的五角星?
- 14.如何让程序自动画出不同大小的五角星?
- 15.函数自己调用自己,会发生什么?
- 16.用递归画出神奇的分形树
- 17.Python 怎么计算你一天躺着不动能消耗多少热量?
- 18.如何让程序“活”起来,持续为你服务?
- 19.如何让 BMR 计算器更“聪明”?
- 20.当程序遇到“不按套路出牌”的用户怎么办?
- 21.怎么用 Python 模拟一个“滚雪球”式的存钱计划?
- 22.如何用列表记录每一周的存款?
- 23.如何让程序自己数数?—— 用 for 循环解放你的双手
- 24.52周存钱挑战4.0:你的存款计算器能有多灵活?
- 25.52周存钱挑战:怎么根据日期自动查存款?
- 26.Python 怎么判断一年中的第几天?
- 27.列表 vs 元组:哪个更适合存储月份天数?
- 28.用集合给月份分个队,换个思路算天数
- 29.把月份和天数“锁”在一起:用字典给数据配个对
- 30.Python 怎么判断密码强弱?
- 31.Python 怎么给密码设置“防沉迷”系统?
- 32.Python 怎么把密码保存到文件里?
- 33.Python 怎么读取文件里的密码?
- 34.Python 怎么把密码检查工具“打包”起来?
- 35.Python 怎么把文件操作也“打包”起来?
- 36.计算机怎么“扔骰子”?——用Python模拟随机事件
- 37.如何用 Python 模拟掷两个骰子?
- 38.怎么用 Python 把骰子轨迹画出来?
- 39.骰子点数分布长啥样?用直方图一眼看穿!
- 40.用科学计算库让骰子程序“起飞”
- 41.空气质量指数怎么算?手把手教你写一个AQI计算器
- 42.空气质量指数计算:从零开始,让程序看懂空气
- 43.如何读取空气质量数据文件并找出空气质量最好的五个监测点?
- 44.JSON 数据怎么变成 Excel 表格?—— 让数据换个“马甲”
- 45.Python 怎么让程序自己判断文件类型?
- 46.如何让程序自己上网查空气质量?
- 47.用美味的汤来解析网页:Beautiful Soup 入门
- 48.如何让爬虫自动抓取全国所有城市的空气质量?
- 49.爬到的数据怎么存下来?—— 把全国空气质量数据保存为CSV文件
- 50.用 pandas 玩转空气质量数据:找出全国空气最好和最差的城市
- 51.空气质量数据怎么“洗”干净,还能画成图?
52周存钱挑战:怎么根据日期自动查存款?
约 21 分钟
小象实战讲义 · Python 入门:8 个小项目边玩边学
还记得我们之前做的“52周存钱挑战”吗?我们已经能让它自动计算每周存多少钱、还能灵活设置存钱规则了。但有个小问题:用户得自己知道“今天是第几周”才能查存款,这太不智能了!
这一节,我们要给存钱挑战加上“日期识别”的超能力——用户只需要输入一个日期(比如“2024/08/05”),程序就能自动算出这是当年的第几周,然后告诉你那周该存多少钱。就像给你的存钱计划装了个智能日历!
💡 核心导读
- 列表的妙用:把52周的存款总额存进一个列表,想查哪周就取哪周
- 日期处理的“瑞士军刀”:认识Python自带的
datetime库,它能轻松处理各种日期时间问题 - 字符串 ↔ 日期的魔法转换:学会
strptime()和strftime()这对“孪生兄弟” - ISO日历的秘密:一键获取“今天是今年的第几周”
- 编程思维训练:如何“先完成简单的,再攻克复杂的”
一、先解决“查存款”问题:列表就是你的记账本
本节新增了什么?
我们只加一件事:把每周的存款总额存进列表,然后根据周数直接查询。
还记得我们之前用列表记录每周的存款数吗?比如[10, 20, 30, ..., 520]。但用户真正关心的是“到第X周为止,我总共存了多少钱”。
所以我们需要一个新列表,专门记录每周的累计存款总额:
- 第1周:10元
- 第2周:10+20=30元
- 第3周:10+20+30=60元
- …
- 第52周:13780元
import math
def save_money_in_n_weeks(money_per_week, increase_money, total_week):
"""
计算n周内的存款金额
"""
money_list = [] # 记录每周存款数的列表
saved_money_list = [] # 记录每周账户累计(新增!)
for i in range(total_week):
money_list.append(money_per_week)
saving = math.fsum(money_list)
saved_money_list.append(saving) # 把累计金额存进列表
money_per_week += increase_money
return saved_money_list # 返回累计存款列表
# 测试一下:每周存10元,每周递增10元,存5周
saved_money_list = save_money_in_n_weeks(10, 10, 5)
print("5周的累计存款列表:", saved_money_list)5周的累计存款列表: [10.0, 30.0, 60.0, 100.0, 150.0]看到了吗?列表里依次是第1周、第2周…第5周的累计存款。有了这个列表,查询就超级简单了!
列表索引的小秘密
Python的列表有个特点:位置从0开始数。这和我们平时说的“第几周”差1位:
- 第1周 → 列表位置0
- 第2周 → 列表位置1
- 第16周 → 列表位置15(16-1)
所以查询第N周的存款,就是取列表的第N-1个元素。
import math
def save_money_in_n_weeks(money_per_week, increase_money, total_week):
"""
计算n周内的存款金额
"""
money_list = [] # 记录每周存款数的列表
saved_money_list = [] # 记录每周账户累计(新增!)
for i in range(total_week):
money_list.append(money_per_week)
saving = math.fsum(money_list)
saved_money_list.append(saving) # 把累计金额存进列表
money_per_week += increase_money
return saved_money_list # 返回累计存款列表
# 测试一下:每周存10元,每周递增10元,存5周
saved_money_list = save_money_in_n_weeks(10, 10, 5)
print("5周的累计存款列表:", saved_money_list)
# 接上面的代码,假设我们存了52周
saved_money_list = save_money_in_n_weeks(10, 10, 52)
# 用户输入第几周(这里用固定值代替input())
week_num = 16 # 用户想知道第16周存了多少钱
# 查询:第16周对应列表位置15
deposit = saved_money_list[week_num - 1]
print(f"第{week_num}周的存款:{deposit}元")5周的累计存款列表: [10.0, 30.0, 60.0, 100.0, 150.0]
第16周的存款:1360.0元import math
def save_money_in_n_weeks(money_per_week, increase_money, total_week):
"""
计算n周内的存款金额
"""
money_list = [] # 记录每周存款数的列表
saved_money_list = [] # 记录每周账户累计(新增!)
for i in range(total_week):
money_list.append(money_per_week)
saving = math.fsum(money_list)
saved_money_list.append(saving) # 把累计金额存进列表
money_per_week += increase_money
return saved_money_list # 返回累计存款列表
# 测试一下:每周存10元,每周递增10元,存5周
saved_money_list = save_money_in_n_weeks(10, 10, 5)
print("5周的累计存款列表:", saved_money_list)
# 接上面的代码,假设我们存了52周
saved_money_list = save_money_in_n_weeks(10, 10, 52)
# 用户输入第几周(这里用固定值代替input())
week_num = 16 # 用户想知道第16周存了多少钱
# 查询:第16周对应列表位置15
deposit = saved_money_list[week_num - 1]
print(f"第{week_num}周的存款:{deposit}元")5周的累计存款列表: [10.0, 30.0, 60.0, 100.0, 150.0]
第16周的存款:1360.0元太棒了!现在只要用户告诉我们周数,我们就能立刻查出存款。但问题来了——用户怎么知道今天是第几周呢?
二、日期处理的“瑞士军刀”:datetime库
本节新增了什么?
我们引入Python自带的datetime库,它能轻松处理各种日期问题。
想象一下,你有个智能助理,你问它“2024年8月5号是今年的第几周?”,它立刻就能回答你。Python的datetime库就是这样的智能助理!
首先,认识一下这个强大的库:
import datetime
# 获取当前日期和时间
now = datetime.datetime(2025, 3, 20, 14, 30, 25) # 固定时刻,真实程序这里用 now() 取当前时间
print("当前时间:", now)
print("时间类型:", type(now))当前时间: 2025-03-20 14:30:25
时间类型: <class 'datetime.datetime'>datetime.datetime是Python专门用来表示日期时间的类型。有了它,你可以轻松获取各种信息:
import datetime
now = datetime.datetime(2025, 3, 20, 14, 30, 25) # 固定时刻,真实程序这里用 now() 取当前时间
print("年份:", now.year)
print("月份:", now.month)
print("日期:", now.day)
print("小时:", now.hour)
print("分钟:", now.minute)年份: 2025
月份: 3
日期: 20
小时: 14
分钟: 30但这还不是最厉害的——datetime真正的超能力是在字符串和日期之间自由转换。
三、字符串 ↔ 日期的魔法转换
魔法一:字符串变日期(strptime)
用户输入的是字符串,比如"2024/08/05"。我们需要把它变成datetime类型才能处理。
import datetime
# 用户输入的日期字符串(这里用固定值代替input())
date_str = "2024/08/05"
# 魔法转换:字符串 → datetime
# strptime = string parse time(解析时间字符串)
input_date = datetime.datetime.strptime(date_str, "%Y/%m/%d")
print("转换后的日期:", input_date)
print("日期类型:", type(input_date))转换后的日期: 2024-08-05 00:00:00
日期类型: <class 'datetime.datetime'>关键点解析:
strptime()需要两个参数:- 日期字符串(
"2024/08/05") - 格式说明(
"%Y/%m/%d")
- 日期字符串(
格式说明就像“翻译指南”:
%Y:4位数的年份(2024)%m:2位数的月份(08,8月)%d:2位数的日期(05)
如果用户输入"2024-08-05",格式就要写成"%Y-%m-%d"。格式必须和字符串完全匹配!
魔法二:获取“第几周”(isocalendar)
日期转换好了,怎么知道是第几周呢?datetime早就准备好了:
import datetime
date_str = "2024/08/05"
input_date = datetime.datetime.strptime(date_str, "%Y/%m/%d")
# 获取ISO日历信息
iso_info = input_date.isocalendar()
print("ISO日历信息:", iso_info)
print("类型:", type(iso_info))ISO日历信息: datetime.IsoCalendarDate(year=2024, week=32, weekday=1)
类型: <class 'datetime.IsoCalendarDate'>isocalendar()返回一个元组(可以暂时理解为“固定顺序的列表”):
- 第1个值:年份(2024)
- 第2个值:第几周(32) ← 我们需要的!
- 第3个值:星期几(1=周一,7=周日)
所以获取周数超级简单:
import datetime
date_str = "2024/08/05"
input_date = datetime.datetime.strptime(date_str, "%Y/%m/%d")
week_num = input_date.isocalendar()[1] # 取元组的第2个值(索引1)
print(f"{date_str} 是2024年的第{week_num}周")2024/08/05 是2024年的第32周魔法三:日期变字符串(strftime)
有时候我们需要把日期按特定格式显示出来,比如显示成“2024年08月05日”。
import datetime
now = datetime.datetime(2025, 3, 20, 14, 30, 25) # 固定时刻便于输出对账;真实程序这里用 datetime.now() 取当前时间
# 魔法转换:datetime → 字符串
# strftime = string format time(格式化时间字符串)
formatted = now.strftime("%Y年%m月%d日 %H:%M:%S")
print("格式化后的时间:", formatted)
# 各种格式随心变
print("简写日期:", now.strftime("%y/%m/%d")) # 2位年份
print("英文月份:", now.strftime("%d-%b-%Y")) # Mar表示3月
print("星期几:", now.strftime("%A")) # Thursday格式化后的时间: 2025年03月20日 14:30:25
简写日期: 25/03/20
英文月份: 20-Mar-2025
星期几: Thursdaystrptime和strftime就像一对孪生兄弟:
strptime:字符串 → datetime(解析)strftime:datetime → 字符串(格式化)
记住口诀:p是parse(解析),f是format(格式化)。
四、完整程序:智能查存款
现在我们把所有零件组装起来,做一个真正智能的存钱查询工具!
"""
52周存钱挑战 5.0
功能:根据用户输入的日期,自动查询该周存款金额
"""
import math
import datetime
def save_money_in_n_weeks(money_per_week, increase_money, total_week):
"""
计算n周内的存款金额
"""
money_list = [] # 记录每周存款数
saved_money_list = [] # 记录每周账户累计
for i in range(total_week):
money_list.append(money_per_week)
saving = math.fsum(money_list)
saved_money_list.append(saving)
money_per_week += increase_money
return saved_money_list
# 主程序
# 1. 设置存钱计划(这里用固定值代替input())
money_per_week = 10 # 每周存10元
increase_money = 10 # 每周递增10元
total_week = 52 # 存52周
# 2. 计算所有周的存款
saved_money_list = save_money_in_n_weeks(money_per_week, increase_money, total_week)
# 3. 用户输入日期(这里用固定值代替input())
input_date_str = "2024/08/05" # 格式必须是yyyy/mm/dd
# 4. 字符串转日期
input_date = datetime.datetime.strptime(input_date_str, "%Y/%m/%d")
# 5. 获取是第几周
week_num = input_date.isocalendar()[1]
# 6. 查询存款(注意:第N周对应列表位置N-1)
deposit = saved_money_list[week_num - 1]
print(f"日期 {input_date_str} 是2024年的第{week_num}周")
print(f"第{week_num}周的存款:{deposit}元")日期 2024/08/05 是2024年的第32周
第32周的存款:5280.0元运行一下试试! 你可以把input_date_str改成你自己的生日,看看你生日那周该存多少钱。
五、编程思维:先易后难,步步为营
你可能注意到了,我们写程序时没有一口气写完所有功能,而是:
- 先实现“根据周数查存款”(这个我们熟悉)
- 再研究“怎么把日期变成周数”(学习新知识)
- 最后把两部分拼起来
这种“先完成简单的,再攻克复杂的”思维方式在编程中特别重要。就像拼乐高:
- 先把你会拼的部分拼好
- 再研究新零件的用法
- 最后把新旧零件组合起来
如果一开始就想着“我要做一个能识别日期、能查存款、还能…的超级程序”,很容易被卡住。拆解问题,逐个击破,这是程序员的核心技能之一。
📝 动手练一练
日期格式大挑战:我们的程序要求用户输入
yyyy/mm/dd格式。如果用户输入2024-08-05(用横杠分隔),程序会报错。你能修改程序,让它同时支持yyyy/mm/dd和yyyy-mm-dd两种格式吗?生日存款查询器:写一个小程序,让用户输入自己的生日(格式自定),然后告诉ta:“在你生日那一周,52周存钱挑战应该存XX元”。
【选做】错误处理小能手:如果用户输入的日期格式不对(比如
2024/8/5少写了0),程序会崩溃。你能用try...except让程序友好地提示用户“日期格式错误,请重新输入”吗?
👉 点击查看第1题参考答案
思路:先尝试用第一种格式解析,如果失败(抛出异常),再尝试第二种格式。
import datetime
def parse_date(date_str):
"""
尝试两种格式解析日期
"""
formats = ["%Y/%m/%d", "%Y-%m-%d"]
for fmt in formats:
try:
return datetime.datetime.strptime(date_str, fmt)
except ValueError:
continue # 这种格式不对,试下一种
# 两种格式都失败了
raise ValueError(f"无法解析日期: {date_str},请使用yyyy/mm/dd或yyyy-mm-dd格式")
# 测试
test_dates = ["2024/08/05", "2024-08-05", "2024/8/5"] # 最后一个会失败
for date_str in test_dates:
try:
date_obj = parse_date(date_str)
print(f"成功解析 {date_str} → {date_obj}")
except ValueError as e:
print(f"解析失败 {date_str}: {e}")成功解析 2024/08/05 → 2024-08-05 00:00:00
成功解析 2024-08-05 → 2024-08-05 00:00:00
成功解析 2024/8/5 → 2024-08-05 00:00:00👉 点击查看第2题参考答案
思路:结合本节学的所有知识,先解析生日日期,再计算周数,最后查询存款。
import math
import datetime
def save_money_in_n_weeks(money_per_week, increase_money, total_week):
"""计算存款(复用之前的函数)"""
saved_money_list = []
total = 0
for week in range(total_week):
total += money_per_week + week * increase_money
saved_money_list.append(total)
return saved_money_list
# 主程序
# 1. 设置存钱计划
money_per_week = 10
increase_money = 10
total_week = 52
# 2. 计算所有存款
saved_money_list = save_money_in_n_weeks(money_per_week, increase_money, total_week)
# 3. 用户输入生日(这里用固定值代替input())
birthday_str = "2000/05/20" # 假设生日是2000年5月20日
try:
# 4. 解析生日
birthday = datetime.datetime.strptime(birthday_str, "%Y/%m/%d")
# 5. 获取生日是第几周(注意:我们只看周数,不管年份)
week_num = birthday.isocalendar()[1]
# 6. 确保周数不超过52
if week_num > 52:
week_num = 52
# 7. 查询存款
deposit = saved_money_list[week_num - 1]
print(f"你的生日 {birthday_str} 是当年的第{week_num}周")
print(f"在你生日那一周,52周存钱挑战应该存 {deposit} 元!")
except ValueError:
print("日期格式错误!请使用 yyyy/mm/dd 格式")你的生日 2000/05/20 是当年的第20周
在你生日那一周,52周存钱挑战应该存 2100 元!本章小结
恭喜!你刚刚给“52周存钱挑战”装上了“日期识别”的超能力。现在它不再是一个简单的计算器,而是一个智能的理财小助手——用户只需要输入日期,就能立刻知道该存多少钱。
本节我们学到了:
- 列表的查询功能:把52周的存款总额存进列表,用
列表[周数-1]就能快速查询 - datetime库:Python处理日期时间的“瑞士军刀”
- 字符串 ↔ 日期转换:
strptime():字符串变日期(解析)strftime():日期变字符串(格式化)
- ISO日历:
isocalendar()一键获取年份、周数、星期几 - 编程思维:先易后难,拆解问题,逐个击破
📋 行动清单
学完立刻可以做的3件事:
- 运行完整程序:把5.0的代码复制运行,输入几个不同的日期试试
- 改造日期格式:修改程序,让它支持
yyyy-mm-dd格式(参考动手练一练第1题) - 查查特殊日期:输入春节、国庆节、你的生日,看看这些日子该存多少钱
现在你已经掌握了列表、函数、循环、日期处理等多个核心技能。下一章,我们将探索更多处理“组合数据”的方法——除了列表,Python还有哪些“容器”可以帮我们更好地组织数据?它们各有什么绝活?
敬请期待!
—— 小象教研组
配套资料 · 直接下载
课件、代码、数据集等配套资料全部免费,点击即可直接下载,无需分享或解锁。
- 下载第5章代码包:52周存钱挑战(含全部版本 5 个 .py)ZIP · 3KB