python挑选黄道吉日

280 阅读2分钟

日期无非就是个数字,如果赶不上节假日,或者什么重大纪念日,那就来玩一点纯数学的。 比如5月16日,516这个数字做因式分解,它的各种因数的集合中,会出现从1到9的所有数字。

516 = 2 x 2 x 3 x 43 = 2 x 3 x 86 = 3 x 172 = 4 x 129

像这种类似的日期又有哪些呢?下面直接上代码。主要涉及以下知识点:

  1. 因式分解
  2. 排列组合itertools.combination
  3. set集合去重
  4. arrow库处理日期
import arrow
import itertools

def div(num):
    '''
    对输入的正整数进行因式分解
    # https://blog.csdn.net/qq_39321542/article/details/89287248
    '''
    factor = []
    while num > 1:
        for i in range(num - 1):
            k = i + 2
            if num % k == 0:
                factor.append(k)
                num = int(num / k)
                break
    return factor

def conc(fs):
    '''
    fs: 因数列表,返回所有的连乘组合的字符串
    '''
    data = []
    n = len(fs)
    for r in range(n):
        for i in itertools.combinations(fs, r+1):
        # 排列组合
            if len(i)>1:
                cc = 1
                for l in i:
                    cc *= l
            else:
                cc = i[0]
            data.append(cc)
    return "".join(map(str, data))

def dep(ns):
    '''
    ns: 一串数字,字符串
    '''
    data = []
    for n in ns:
        num = int(n)
        data.append(num)
    data2 = set(data)  # set是自动去重的
    return data2

def isLeapYear(years):
    '''
    通过判断闰年,获取年份years下一年的总天数
    :param years: 年份,int
    :return:days_sum,一年的总天数
    # https://www.cnblogs.com/andy9468/p/10710142.html
    '''
    # 断言:年份不为整数时,抛出异常。
    assert isinstance(years, int), "请输入整数年,如 2018"
 
    if ((years % 4 == 0 and years % 100 != 0) or (years % 400 == 0)):  # 判断是否是闰年
        # print(years, "是闰年")
        days_sum = 366
        return days_sum
    else:
        # print(years, '不是闰年')
        days_sum = 365
        return days_sum
    
def getAllDayPerYear(years):
    '''
    获取一年的所有日期
    :param years:年份
    :return:全部日期列表
    # https://www.cnblogs.com/andy9468/p/10710142.html
    '''
    start_date = '%s-1-1' % years
    a = 0
    all_date_list = []
    days_sum = isLeapYear(int(years))
    print()
    while a < days_sum:
#         b = arrow.get(start_date).shift(days=a).format("YYYY-MM-DD")
        b = arrow.get(start_date).shift(days=a).format("YYYYMMDD")
        a += 1
        all_date_list.append(b)
    # print(all_date_list)
    return all_date_list

def main(year=2020):
    all_date_list = getAllDayPerYear(year)
    udate = []
    check = set([1,2,3,4,5,6,7,8,9])
    for date in all_date_list:
        md = date[4:]
        if md[0] is '0':
            md = md[1:]
        dd = dep(conc(div(int(float(md)))))
        if dd == check:
            print(date)
            udate.append(date)
    print("------\n%d 年共计有这样的日子 %d 天"%(year, len(udate)))

if __name__=="__main__":
    main(year=2020)

通过以上代码,只要直接修改main函数中指定的年份,就可以查看了。但实际上,月和日几乎是不变的,一年共有十一天这样的日子。分别是: