打鱼还是晒网


1.问题描述
中国有句俗语叫“三天打鱼两天晒网”。某人从1990年1月1日起便开始“三天打鱼两天晒网”,问这个人在以后的某一天中是“打鱼”还是“晒网”。
2.问题分析
根据题意可以将解题过程分为以下三步:
1)计算从1990年1月1日开始至指定日期共有多少天。
2)由于“打鱼”和“晒网”的周期为5天,所以将计算出的天数用5去除。
3)根据余数判断他是在“打鱼”还是在“晒网”。
若余数为1,2,3,则他是在“打鱼”,否则是在“晒网”。
3.算法设计
本题目使用的算法为数值计算算法,要利用循环求出指定日期距1990年1月1日的天数,并考虑到循环过程中的闰年情况,闰年二月为29天,平年二月为28天。判断闰年的方法可以用伪语句描述如下:
如果能被4整除并且不能被100整除或者能被400整除,则该年是闰年,否则不是闰年。
提示:在Python语言中判断能否整除可以使用求余运算符“%”。
4.确定程序框架
程序流程图如图1.11所示。

图1.11 程序流程图
根据流程,构建程序框架如下:

if __name__ == '__main__':

print("please input 指定日期 包括年,月,日 如:1999 1 31")
    year, month, day = [int(i) for i in input().split()]
    # 定义一个日期字典
    today = {'year': year, 'month': month, 'day': day}

    totalDay = countDay(today)              # 求出指定日期距离1990年1月1日的天数
    print("%d年%d月%d日与1990年1月1日相差 %d 天" % (year, month, day,
totalDay))

    # 天数 % 5,判断输出打鱼还是晒网
 

  result = totalDay % 5
    if result > 0 and result < 4:
        print("今天打鱼")
    else:
        print("今天晒网")


5.求出指定日期距离1990年1月1日的天数
这里为整个算法的核心部分,经过分析可以得到指定日期距离1990年1月1日的天数totalDay=1990年至指定年的前一年共有多少天+指定年中到指定日期的天数。由于每月天数不同,可以设置一个月份数组int perMonth[13]存放每月的天数。程序利用年份作为循环变量,要判断指定年份之前的每一年是否为闰年,若为闰年则执行totalDay=totalDay+366,否则执行totalDay=totalDay+365;对于指定年份,也要判定是否为闰年,然后根据月份数,将每月的天数累加到totalDay中。
perMonth数组的初始化设置如表1.2所示。该设置含有13个元素,perMonth[0]元素并不使用,原因在于这种设置可以使数组下标和月份对应,便于编程设置循环变量,数组中二月天数初始设置为28,如果当前年份为闰年,则需要执行perMonth[2]+=1操作。
表1.2 perMonth数组初始化

 提炼功能模块,我们设计一个函数countDay(currentDay)来实现求总天数的功能,设计一个函数runYear(year)来判断是否为闰年。判断是否为闰年的函数runYear(year)的实现如下:

# 判断是否为闰年。是,则返回1,否,则返回0
def runYear(year):  
    if (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0):  # 是闰年
        return 1
    else:
        return 0

求总天数的函数countDay(currentDay)的实现如下:

# 计算指定日期距离1990年1月1日的天数
def countDay(currentDay):  
    # 每月天数数组
    perMonth = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30]
    totalDay = 0
    year = 1990
    while year < currentDay['year']:     # 求出指定日期之前的每一年的天数之和
        if runYear(year) == 1:                      # 判断是否为闰年
            totalDay = totalDay + 366
        else:
            totalDay = totalDay + 365

        year += 1

   

 # 如果为闰年,则二月份为29天
    if runYear(currentDay['year']) == 1:
        perMonth[2] += 1

    i = 0
    while i < currentDay['month']:               # 将本年内的天数累加到totalDay中
        totalDay += perMonth[i]
        i += 1

    totalDay += currentDay['day']           # 将本月内的天数累加到totalDay中

    return totalDay

6.完整的程序
根据上面的分析,编写程序如下:

#!/usr/bin/python3

# -*- coding: utf-8 -*- 
# @author : liuhefei
# @desc: 打鱼还是晒网

# 判断是否为闰年。是,则返回1;否,则返回0
def runYear(year):
    if (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0):  # 是闰年
        return 1
    else:
        return 0


# 计算指定日期距离1990年1月1日的天数
def countDay(currentDay):
    # 每月天数数组
    perMonth = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30]
    totalDay = 0
    year = 1990
    while year < currentDay['year']:     # 求出指定日期之前的每一年的天数之和
        if runYear(year) == 1:                      # 判断是否为闰年

totalDay = totalDay + 366
        else:
            totalDay = totalDay + 365

        year += 1

    # 如果为闰年,则二月份为29天
    if runYear(currentDay['year']) == 1:
        perMonth[2] += 1

    i = 0
    while i < currentDay['month']:               # 将本年内的天数累加到totalDay中
        totalDay += perMonth[i]
        i += 1

    totalDay += currentDay['day']           # 将本月内的天数累加到totalDay中

    return totalDay


if __name__ == '__main__':
    while True:
        print("please input 指定日期 包括年,月,日 如:1999 1 31")
        year, month, day = [int(i) for i in input().split()]
        # 定义一个日期字典
        today = {'year': year, 'month': month, 'day': day}

        totalDay = countDay(today)          # 求出指定日期距离1990年1月1日的天数
        print("%d年%d月%d日与1990年1月1日相差 %d 天" % (year,month, day,totalDay))

        # 天数 % 5,判断输出打鱼还是晒网
        result = totalDay % 5
        if result > 0 and result < 4:
            print("今天打鱼")
        else:
            print("今天晒网")

7.运行结果
在PyCharm下运行程序,结果如图1.12所示。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值