python:计算在1901年1月1日至2000年12月31日间共有多少个星期天落在每月的第一天上

根据下列信息计算在1901年1月1日至2000年12月31日间共有多少个星期天落在每月的第一天上?
a) 1900.1.1是星期一
b) 1月,3月,5月,7月,8月,10月和12月是31天
c) 4月,6月,9月和11月是30天
d) 2月是28天,在闰年是29天
e) 公元年数能被4整除且又不能被100整除是闰年
f) 能直接被400整除也是闰年
输出格式:
一个正整数


说实话,拿到这个题目,我一眼看过去,觉得很简单,是肯定可以搞定的问题。然后,我就开干了。干了一会发现,这尼玛很繁琐,似乎不能写出通用的计算方式。于是作罢。

然而并不甘心,于是又开干。发现这个和计算时分秒是不同的。因为每年的天数是不固定的,然后每个月的天数也是不固定的。复杂度一下子就提高了不少。

然后,还是决定去解决这个问题。因为这个问题里面涉及到怎样去计算任意一天是周几。这个东西以后是可以拿到其他地方去使用的。

  • 解决这个问题,真是喷了我几口老血了….
  • 以下是全部代码
# -*- coding: UTF-8 -*-
"""
Created on 2017/4/2
@author: cat

"""
import logging
"""
根据下列信息计算在1901年1月1日至2000年12月31日间共有多少个星期天落在每月的第一天上?

a)  1900.1.1是星期一
b)  1月,3月,5月,7月,8月,10月和12月是31天
c)  4月,6月,9月和11月是30天
d)  2月是28天,在闰年是29天
e)  公元年数能被4整除且又不能被100整除是闰年
f)  能直接被400整除也是闰年

输出格式:
一个正整数

"""
logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
                    datefmt='%a, %d %b %Y %H:%M:%S')


def is_leap(year):
    """
    是否是闰年
    :param year: 
    :return: 闰年-> true ; 平年-> false
    """
    return year % 400 == 0 or (year % 4 == 0 and year % 100 != 0)


def year_total_day(year):
    return 366 if is_leap(year) else 365


def month_total_day(year, month):
    """
    一个月有多少天
    :return: 当月的天数
    """
    if month < 1 or month > 12:
        message = "month only range in [1,12] ! but current month is {0} ".format(month)
        raise ValueError(message)
    if month in [1, 3, 5, 7, 8, 10, 12]:
        total = 31
    elif month in [4, 6, 9, 11]:
        total = 30
    else:
        if is_leap(year):
            total = 29
        else:
            total = 28
    # logging.warn("total === {0}".format(total))
    return total


# print month_total_day(2003, 2)


# print year_total_day(0)


def d_value(srcyear, srcmonth, srcday, destyear, destmonth, destday):
    """
    temp函数,用于计算两个时间直接相差的天数 比如2016.3.25日 减去 2008.8.8日 等于多少天 
    :return: 相差的天数
    """
    if srcyear > destyear or (srcyear == destyear and srcmonth > destmonth) or (
                        srcyear == destyear and srcmonth > destmonth and srcday > destday):
        message = "起始时间不得大于结束时间,这样子是无法比较的:\n" \
                  "起始时间:{0}/{1}/{2} 结束时间:{3}/{4}/{5}" \
            .format(srcyear, srcmonth, srcday, destyear, destmonth, destday)
        raise ValueError(message)
    else:
        # 都回到公元元年吧 1900.1.1 --> 0年的0月0日吧
        st = 0
        for y in range(0, srcyear):
            st += year_total_day(y)
            # logging.info("st1 = {0} , y = {1}".format(st,y))
        for m in range(1, srcmonth):
            st += month_total_day(srcyear, m)
            # logging.info("st2 = {0}".format(st))
        st += srcday
        # logging.info("st = {0}".format(st))

        dt = 0
        for y in range(0, destyear):
            dt += year_total_day(y)
            # logging.info("yy = "+str(yy)+ "destday = "+str(destyear))
        for m in range(1, destmonth):
            dt += month_total_day(srcyear, m)
        dt += destday
        # logging.info("dt = {0}".format(dt))
        return dt - st


def weekday(year, month, day):
    """
    获取每天是星期几(基于1900.1.1 是周一)
    :param year: 2017
    :param month: 04
    :param day: 02
    :return: 1 - 7 ==》周一 - 周日
    """
    ds = d_value(1900, 1, 1, year, month, day) + 1
    weekday_num = ds % 7
    return 7 if weekday_num == 0 else weekday_num


# print weekday(2017, 4, 2)


def get_all_lucky():
    ret = []
    cnt = 0
    for year in range(1900, 2000 + 1):
        for month in range(1, 12 + 1):
            weekday_num = weekday(year, month, 1)
            if weekday_num == 1:
                cnt += 1
                item = (year, month, 1)
                ret.append(item)
    print "size = {0}".format(cnt)
    return ret


p = 0
for it in get_all_lucky():
    p += 1
    if p % 5 == 0:
        print
    print it,


  • 里面的逻辑就不详述了,大体上还是容易理解的,主要是思路。

输出如下:

size = 175
(1900, 1, 1) (1900, 10, 1) (1901, 4, 1) (1901, 7, 1)
(1902, 9, 1) (1902, 12, 1) (1903, 6, 1) (1904, 2, 1) (1904, 3, 1)
(1904, 11, 1) (1905, 5, 1) (1906, 1, 1) (1906, 10, 1) (1907, 4, 1)
(1907, 7, 1) (1908, 9, 1) (1908, 12, 1) (1909, 2, 1) (1909, 3, 1)
(1909, 11, 1) (1910, 8, 1) (1911, 5, 1) (1912, 1, 1) (1912, 10, 1)
(1913, 9, 1) (1913, 12, 1) (1914, 6, 1) (1915, 2, 1) (1915, 3, 1)
(1915, 11, 1) (1916, 8, 1) (1917, 1, 1) (1917, 10, 1) (1918, 4, 1)
(1918, 7, 1) (1919, 9, 1) (1919, 12, 1) (1920, 6, 1) (1921, 8, 1)
(1922, 5, 1) (1923, 1, 1) (1923, 10, 1) (1924, 4, 1) (1924, 7, 1)
(1925, 6, 1) (1926, 2, 1) (1926, 3, 1) (1926, 11, 1) (1927, 8, 1)
(1928, 5, 1) (1929, 4, 1) (1929, 7, 1) (1930, 9, 1) (1930, 12, 1)
(1931, 6, 1) (1932, 2, 1) (1932, 3, 1) (1932, 11, 1) (1933, 5, 1)
(1934, 1, 1) (1934, 10, 1) (1935, 4, 1) (1935, 7, 1) (1936, 9, 1)
(1936, 12, 1) (1937, 2, 1) (1937, 3, 1) (1937, 11, 1) (1938, 8, 1)
(1939, 5, 1) (1940, 1, 1) (1940, 10, 1) (1941, 9, 1) (1941, 12, 1)
(1942, 6, 1) (1943, 2, 1) (1943, 3, 1) (1943, 11, 1) (1944, 8, 1)
(1945, 1, 1) (1945, 10, 1) (1946, 4, 1) (1946, 7, 1) (1947, 9, 1)
(1947, 12, 1) (1948, 6, 1) (1949, 8, 1) (1950, 5, 1) (1951, 1, 1)
(1951, 10, 1) (1952, 4, 1) (1952, 7, 1) (1953, 6, 1) (1954, 2, 1)
(1954, 3, 1) (1954, 11, 1) (1955, 8, 1) (1956, 5, 1) (1957, 4, 1)
(1957, 7, 1) (1958, 9, 1) (1958, 12, 1) (1959, 6, 1) (1960, 2, 1)
(1960, 3, 1) (1960, 11, 1) (1961, 5, 1) (1962, 1, 1) (1962, 10, 1)
(1963, 4, 1) (1963, 7, 1) (1964, 9, 1) (1964, 12, 1) (1965, 2, 1)
(1965, 3, 1) (1965, 11, 1) (1966, 8, 1) (1967, 5, 1) (1968, 1, 1)
(1968, 10, 1) (1969, 9, 1) (1969, 12, 1) (1970, 6, 1) (1971, 2, 1)
(1971, 3, 1) (1971, 11, 1) (1972, 8, 1) (1973, 1, 1) (1973, 10, 1)
(1974, 4, 1) (1974, 7, 1) (1975, 9, 1) (1975, 12, 1) (1976, 6, 1)
(1977, 8, 1) (1978, 5, 1) (1979, 1, 1) (1979, 10, 1) (1980, 4, 1)
(1980, 7, 1) (1981, 6, 1) (1982, 2, 1) (1982, 3, 1) (1982, 11, 1)
(1983, 8, 1) (1984, 5, 1) (1985, 4, 1) (1985, 7, 1) (1986, 9, 1)
(1986, 12, 1) (1987, 6, 1) (1988, 2, 1) (1988, 3, 1) (1988, 11, 1)
(1989, 5, 1) (1990, 1, 1) (1990, 10, 1) (1991, 4, 1) (1991, 7, 1)
(1992, 9, 1) (1992, 12, 1) (1993, 2, 1) (1993, 3, 1) (1993, 11, 1)
(1994, 8, 1) (1995, 5, 1) (1996, 1, 1) (1996, 10, 1) (1997, 9, 1)
(1997, 12, 1) (1998, 6, 1) (1999, 2, 1) (1999, 3, 1) (1999, 11, 1)
(2000, 8, 1)

Process finished with exit code 0

你可能感兴趣的:(computer,大猫学python)