Python基础语法练习题(65)

紧接着是第六十五题,共用两个版本。

第六十五题,生成日期范围列表:

1.首先是原始版本:

复制代码
#定义一个函数,它接收两个遵循'YYYY-MM-DD'格式的日期字符串参数begin_date和end_date。该函数的任务是生成一个包含从begin_date到end_date(包括两端日期在内)所有日期的列表,并将该列表作为结果返回。

#导入模块

import datetime

#定义一个函数

def get_date_range(begin_date, end_date):
    """
    生成一个包含从begin_date到end_date(包括两端日期在内)所有日期的列表

    参数:
    begin_date (str): 开始日期,格式为'YYYY-MM-DD'
    end_date (str): 结束日期,格式为'YYYY-MM-DD'

    返回:
    list: 包含从begin_date到end_date(包括两端日期在内)所有日期的列表
    """
    date_range = []
    begin_date_obj = datetime.datetime.strptime(begin_date, '%Y-%m-%d')
    end_date_obj = datetime.datetime.strptime(end_date, '%Y-%m-%d')
    current_date = begin_date_obj
    while current_date <= end_date_obj:
        date_range.append(current_date.strftime('%Y-%m-%d'))
        current_date += datetime.timedelta(days=1)
    return date_range

#调用函数并接收返回的日期范围列表

begin_date = '2023-01-01'
end_date = '2023-01-10'
date_range = get_date_range(begin_date, end_date)

#输出结果:先打印标题与总数,再逐行整齐地列出每个日期

print(f"从 {begin_date} 到 {end_date} 的日期范围列表(共 {len(date_range)} 天):")
print("-" * 40)
for index, date_str in enumerate(date_range, start=1):
    print(f"  {index:>2}. {date_str}")

下面是代码思路分析:

题目要求:写函数接收起止日期,返回其间(含首尾)所有日期的列表。

我的思路是让日期"一天天走":从开始日期出发,每次 + timedelta(days=1) 挪一天、就往列表 append 一个,用 while current_date <= end_date 控制走到终点即停,<= 正好把首尾都收进来。

两个细节:一是字符串和对象分工------进函数先 strptime 转对象才能比较和加减,存的时候再 strftime 转回字符串;二是输出做了排版------用 enumerate(..., start=1) 带序号逐行打印,比甩一整坨列表好读。局限还是老问题:起止日期写死在代码里。

2.接下来是优化过的版本:

复制代码
# 定义一个函数,它接收两个遵循'YYYY-MM-DD'格式的日期字符串参数begin_date和end_date。
# 该函数的任务是生成一个包含从begin_date到end_date(包括两端日期在内)所有日期的列表,并将该列表作为结果返回。

# 本版本在原始版本的基础上做了三点优化:
# 1. 用户可自由输入日期,不限于固定格式(借助 dateutil.parser 自动识别多种写法);
# 2. 自动纠正开始/结束日期的先后顺序;
# 3. 每完成一次计算后,询问用户是否再进行一次计算。

# 导入datetime模块

import datetime

# 导入dateutil的parser模块,用于灵活解析多种日期输入格式

from dateutil import parser


# 定义一个函数

def get_date_range(begin_date, end_date):
    """
    生成一个包含从begin_date到end_date(包括两端日期在内)所有日期的列表

    参数:
    begin_date (str): 开始日期,格式为'YYYY-MM-DD'
    end_date (str): 结束日期,格式为'YYYY-MM-DD'

    返回:
    list: 包含从begin_date到end_date(包括两端日期在内)所有日期的列表
    """
    date_range = []
    begin_date_obj = datetime.datetime.strptime(begin_date, '%Y-%m-%d')
    end_date_obj = datetime.datetime.strptime(end_date, '%Y-%m-%d')
    current_date = begin_date_obj
    while current_date <= end_date_obj:
        date_range.append(current_date.strftime('%Y-%m-%d'))
        current_date += datetime.timedelta(days=1)
    return date_range


# 定义一个辅助函数:接收用户自由输入的日期字符串,
# 自动识别多种格式并统一返回标准的 YYYY-MM-DD 字符串;无法识别时返回 None

def parse_user_date(date_input):
    try:
        parsed_date_obj = parser.parse(date_input)
        return parsed_date_obj.strftime('%Y-%m-%d')
    except (ValueError, parser.parser.ParserError):
        return None


# 程序启动时先打印一段功能简介,让用户清楚这个程序是做什么的、以及需要如何配合输入

print("=" * 46)
print("            日期范围列表生成器")
print("=" * 46)
print("功能说明:本程序会根据您输入的【开始日期】和【结束日期】,")
print("          自动列出这两天之间(含首尾)的所有日期。")
print("使用提示:日期不必拘泥于固定格式,例如 2023-01-01、")
print("          2023/1/1、2023年1月1日、Jan 1 2023 等写法都能识别。")
print("=" * 46)

# 主循环:支持用户反复进行计算

while True:
    print("\n【第 1 步 / 共 2 步】请提供范围起点,也就是日期列表从哪一天开始:")
    while True:
        begin_input = input(">>> 请输入开始日期:").strip()
        begin_date = parse_user_date(begin_input)
        if begin_date is not None:
            break
        print("    无法识别该日期,请重新输入一个有效的日期!")

    print("\n【第 2 步 / 共 2 步】请提供范围终点,也就是日期列表到哪一天结束:")
    while True:
        end_input = input(">>> 请输入结束日期:").strip()
        end_date = parse_user_date(end_input)
        if end_date is not None:
            break
        print("    无法识别该日期,请重新输入一个有效的日期!")

    # 若开始日期晚于结束日期,自动交换两者,保证范围有效

    if begin_date > end_date:
        begin_date, end_date = end_date, begin_date
        print("注意:您输入的开始日期晚于结束日期,已自动调整为从早到晚的顺序。")

    # 调用函数生成日期范围并整齐输出结果

    date_range = get_date_range(begin_date, end_date)
    print(f"\n计算结果 —— 从 {begin_date} 到 {end_date} 的日期范围列表(共 {len(date_range)} 天):")
    print("-" * 40)
    for index, date_str in enumerate(date_range, start=1):
        print(f"  {index:>2}. {date_str}")

    # 计算完成后询问用户是否再进行一次计算

    again = input("\n是否再进行一次计算?(输入 y 继续 / 其他任意键结束):").strip().lower()
    if again != 'y':
        print("感谢使用,程序已结束!")
        break

可以看到代码量有了显著的提升,思路分析呈现如下:

优化目标:让用户自由输入、不怕输错、还能反复算。

核心生成函数我一字没动,优化全加在"怎么把日期交给它"这一环。

输入彻底放飞: 借 64 再优化版的 dateutil.parser 封了 parse_user_date,2023/1/1、2023年1月1日、Jan 1 2023 都能认,认不出返回 None 让外面重问。自动摆正顺序: 用 if begin_date > end_date 判断后一行交换两个变量,用户填反了也能纠正,范围永远有效。算完能续用: 外层 while True 每次问"要不要再来",非 y 才退出,开头还加了功能横幅简介。

小结

三处优化本质是同一件事:把"只能算写死范围、跑完就结束"的脚本,改成"随便输、输反能纠正、算完能续用"的完整程序。日期走路逻辑始终没变,升级的全是对用户的友好度。

相关推荐
fanjiu20201 小时前
flask接收消息
python·flask
浅尝辄止;1 小时前
设计模式在HIS/LIS医疗系统中的完整实践指南(C#版)
开发语言·设计模式·c#
iReachers1 小时前
Termux:把安卓手机变成随身的命令行工具箱
python·安卓·termux·命令行·实用工具
xy_zoe1 小时前
揭秘市面上那些热门的SEO优化服务机构!
python·facebook
Python图像识别1 小时前
43-【2027毕设】YOLO11暴力检测识别系统 - Python完整源码+PyQt5界面+训练模型+数据集
python·qt·课程设计
卷无止境1 小时前
如何让AI Agent老老实实遵守公司代码规范——以Pi Agent为例
后端·python
计算机编程指导师1 小时前
计算机毕设怎么做?基于Hadoop+Spark的商场商铺数据分析与可视化系统源码 毕业设计 选题推荐 毕设选题 数据分析 机器学习
大数据·hadoop·python·spark·毕业设计·课程设计·商场商铺
李福春2 小时前
斗破Google ADK Java苍穹-第7境斗皇-御天地-Harness治理
java·人工智能·python·深圳同盟·腾讯云架构师技术同盟·adk java·harness 治理
Wang's Blog2 小时前
Java 项目部署之 Docker工具快速入门: 容器命令练习:创建、改文件、重启到删除的完整闭环
java·开发语言·docker