第四课 如何开发一个万年历---下篇

来源:互联网 发布:2016淘宝开店得多少钱 编辑:程序博客网 时间:2024/06/07 03:59

第三阶段:确定月历中的一号是星期几,然后输出月历


        第三阶段的目标是当确定某月一日与星期的对应关系后就能够输出正确的月历,面对一个月历分析一下,每月从最左端开始(日期的1号对应星期日)可以方便地控制以7个日期加入一个回车的形式输出该月的天数,但是实际的月历并不都是从最左边开始的,怎么办呢?

观察得知,若开始打印位置不是周日,那么打印结束的位置就会延展相应的天数。举个例子:




        若某月的1日是周3,那么开始和结束打印的位置将都向后3个打印位置。那么将每月1日对应的星期设为wd,其中周日对应wd=0,周六对应wd=6。那么把打印的范围修改成:

range(print_days+wd)

        这样就可以向后拓展打印范围了但是会有个小问题,请看下面修改的代码和运行结果:




        在15行确定了wd=3,第19行拓展了打印范围,从结果看有些奇怪,输入的是2015年4月,但是日期从1打印到33了,而且打印开始的位置也不正确,对此程序需要修补一下,很简单,第20行是需要打印的日期的数字,将它改成:pd=i+1-wd,代码和结果如下:





        观察结果,发现事情变得很简单了,只需控制打印0以上的数字照原样打印,其他数字打印占位符,这样就大功告成了。




       

        注意程序的22-31行,在原有的if结构中嵌入了判断数字是否大于0的结构。

        至此第三阶段也完成了。程序已经能打印一个正常的月历,离最终的目标已经相当接近,其中“小技巧”固然重要,但是需要着重体会的是“迭代”的方法。下面只要让程序能够自动计算wd的值就可以了,这是第四阶段要解决的问题。


第四阶段:打印当年的任意月历(完成“年历”)


        虽然现在可以完成最后的任务,但是在第四阶段还是只验证一个想法,然后在第五阶段给一个提示,最后的任务还是请大家自己完成。


        如何计算wd呢,观察月历可以发现日期对应于星期的规律是7天一个循环,那么只要知道年份的1月1日对应的星期,然后用累计天数对7求余的方法就可以知道任意一天对应的星期了。

        比如2015年1月1日是周4,那么59天后的3月1日就是 (59+4)%7=0,这样可以计算出3月1日是周三。

如此,再次进化的万年历程序变成了这样:




        可以看到在两个地方做了改变,一个是第2行,有了新的工具包,这个函数文件中加入了两个函数,一个是days_before_month函数用来计算一月一日到某个月之前一共有多少天,而在第15行调用了week_day函数,它将利用days_before_month来计算指定月份的1日是周几?


        下面是can_4_1_tools工具包的源文件。这个程序特地使用了各种不同的语法结构开发,目的是使读者更快的熟悉各种基本的语法,在26行使用了while循环。





         第4阶段也完成了,程序的运行结果如下:





第五阶段:本项目最后一个函数的提示,现在由你完成“万年历”


       最后很简单,程序已经能够利用计算一年中某月之前的天数来确定某月的1日是周几,然后打印该月的月历,那么同样的道理,若知道从公元1年1月1日(星期一)起到某年某月之前一共有多少天,就可以知道该月1日应该打印位置了。

可以将求总天数分成两部分,一部分是已经完成的:求当年天数,另一部分就是求该年份之前的所有年份的总天数,这个需求可以利用一个循环完成,其中闰年累加366,平年累加365。


        现在由你自己完成最后一步吧。





0 0
原创粉丝点击