案例描述
输入某年某月某日,判断这一天是这一年的第几天?
例子:
输入的日期为2017/03/05,是2017年的第几天?
输入的日期为2012/03/05,是2012年的第几天?
案例分析
1.每个月份的天数不同
2.闰年与平年的2月份天数不同
3.闰年判断:四年一闰,百年不闰,四百年再闰
项目实现
V1.0——输入某年某月某日,判断这一天是这一年的第几天
将每月的天数存入元组中,根据输入直接访问元组中数据来计算是第几天。
- 元组(tuple)是特殊的序列类型
- 一旦被创建就不能修改,使得代码更安全
- 使用逗号和圆括号来表示,如 (‘red’, ‘blue’, ‘green’), (2, 4, 6)
- 访问方式和列表相同
- 一般用于表达固定数据项、函数多返回值等情况
- 元组的特点:
- 元组中的元素可以是不同类型的
- 元组中各元素存在先后关系,可通过索引访问元组中元素
代码实现:
from datetime import datetime
def main():
input_date_str = input('请输入日期(yyyy/mm/dd):')
input_date = datetime.strptime(input_date_str, '%Y/%m/%d')
year = input_date.year
month = input_date.month
day = input_date.day
days_in_month_tup = (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)
# 计算输入月份之前的月份天数总和以及当月天数
days = sum(days_in_month_tup[:month - 1]) + day
# 大于二月份的需要判断是否为闰年,若为闰年则天数加1
if month > 2:
if (year % 400 == 0) or ((year % 4 == 0) and (year % 100 != 0)):
days += 1
print('这是第{}天'.format(days))
if __name__ == '__main__':
main()
V2.0——用列表替换元组
将存储每月天数的元组修改为使用列表存储。
列表与元组的区别
- 元组是不可变的,列表是可变的
- 元组通常由不同的数据组成,列表通常是由相同类型的数据组成
- 元组表示的是结构,列表表示的是顺序
- …
由于列表是可以修改的,判断用户输入的年份若为闰年,将列表中存2月份的天数修改为29。
代码实现:
from datetime import datetime
def is_leap_year(year):
"""
功能:判断是否为闰年
若为闰年,返回TRUE
否则返回False
"""
is_leap = False
if (year % 400 == 0) or ((year % 4 == 0) and (year % 100 != 0)):
is_leap = True
return is_leap
def main():
input_date_str = input('请输入日期(yyyy/mm/dd):')
input_date = datetime.strptime(input_date_str, '%Y/%m/%d')
year = input_date.year
month = input_date.month
day = input_date.day
days_in_month_list = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
if is_leap_year(year):
days_in_month_list[1] = 29
# 计算输入的日期是当年第几天
days = sum(days_in_month_list[:month - 1]) + day
print('这是第{}年的第{}天'.format(year, days))
if __name__ == '__main__':
main()
V3.0——将月份划分为不同的集合再操作
每个月份的天数可分为三种:30天、31天以及2月份的天数。
使用两个集合分别存储30天以及31天的月份,根据输入进行操作。
- Python中的集合(set)类型同数学中的集合概念一致,即包含0或多个数据项的无序组合
- 集合中的元素不可重复
- 集合是无序组合,没有索引和位置的概念
- set()函数用于集合的生成,返回结果是一个无重复且排序任意的集合
- 集合通常用于表示成员间的关系、元素去重等
集合操作 | 含义 |
---|---|
s - t 或 s.difference(t) | 返回在集合s中但不在t中的元素 |
s & t 或 s.intersection(t) | 返回同时在集合s和t中的元素 |
s | t或 s.union(t) | 返回集合s和t中的所有元素 |
s^t 或 s.symmetric_difference(t) | 返回集合s和t中的元素,但不包括同时在其中的元素 |
将定义数据以及操作使用如下代码实现:
_30_days_month_set = {4, 6, 9, 11}
_31_days_month_set = {1, 3, 5, 7, 8, 10, 12}
# 初始化天数
days = day
for i in range(1, month):
if i in _30_days_month_set:
days += 30
elif i in _31_days_month_set:
days += 31
else:
days += 28
if month > 2 and is_leap_year(year):
days += 1
V4.0——将月份及其对应天数通过字典表示
使用字典数据结构存储月份以及对应的天数,根据输入直接从字典中获取月份对应的天数。
- 字典类型(dict)是“键–值”数据项的组合,每个元素是一个键值对
- 如:身份证号(键)–个人信息(值)
- 字典类型数据通过映射查找数据项
- 映射:通过任意键查找集合中的值的过程
- 字典类型以键为索引,一个键对应一个值
- 字典类型的数据是无序的
字典的增删改查:
- 增加一项:d[key] = value
- 访问字典中某项:d[key]
- 删除某项:del d[key]
- key是否在字典中:key in d
字典的遍历:
- 遍历所有的key
for key in d.keys():
print(key)
- 遍历所有的value
for value in d.values():
print(value)
- 遍历所有的数据项
for item in d.items():
print(items)
使用字典定义数据以及操作使用如下代码实现:
month_day_dict = {1: 31,
2: 28,
3: 31,
4: 30,
5: 31,
6: 30,
7: 31,
8: 31,
9: 30,
10: 31,
11: 30,
12: 31}
# 初始化天数
days = day
for i in range(1, month):
days += month_day_dict[i]
if month > 2 and is_leap_year(year):
days += 1
也可使用如下方式定义字典:
month_day_dict = {30: {4, 6, 9, 11},
31: {1, 3, 5, 7, 8, 10, 12}}
# 初始化天数
days = day
for i in range(1, month):
if i in month_day_dict[30]:
days += 30
elif i in month_day_dict[31]:
days += 31
else:
days += 28
if month > 2 and is_leap_year(year):
days += 1
总结:使用各种数据结构存储数据实现计算一年中的第几天,使我熟练掌握了各个数据结构的使用。而python中有内置函数,可直接根据输入计算出第几天。
使用如下语句即可直接获取到第几天
input_date_str = input('请输入日期(yyyy/mm/dd):')
input_date = datetime.strptime(input_date_str, '%Y/%m/%d')
print(int(input_date.strftime('%j')))