1#! /usr/bin/env python 2 3# Calculate your unbirthday count (see Alice in Wonderland). 4# This is defined as the number of days from your birth until today 5# that weren't your birthday. (The day you were born is not counted). 6# Leap years make it interesting. 7 8import sys 9import time 10import calendar 11 12def main(): 13 if sys.argv[1:]: 14 year = int(sys.argv[1]) 15 else: 16 year = int(raw_input('In which year were you born? ')) 17 if 0 <= year < 100: 18 print "I'll assume that by", year, 19 year = year + 1900 20 print 'you mean', year, 'and not the early Christian era' 21 elif not (1850 <= year <= time.localtime()[0]): 22 print "It's hard to believe you were born in", year 23 return 24 25 if sys.argv[2:]: 26 month = int(sys.argv[2]) 27 else: 28 month = int(raw_input('And in which month? (1-12) ')) 29 if not (1 <= month <= 12): 30 print 'There is no month numbered', month 31 return 32 33 if sys.argv[3:]: 34 day = int(sys.argv[3]) 35 else: 36 day = int(raw_input('And on what day of that month? (1-31) ')) 37 if month == 2 and calendar.isleap(year): 38 maxday = 29 39 else: 40 maxday = calendar.mdays[month] 41 if not (1 <= day <= maxday): 42 print 'There are no', day, 'days in that month!' 43 return 44 45 bdaytuple = (year, month, day) 46 bdaydate = mkdate(bdaytuple) 47 print 'You were born on', format(bdaytuple) 48 49 todaytuple = time.localtime()[:3] 50 todaydate = mkdate(todaytuple) 51 print 'Today is', format(todaytuple) 52 53 if bdaytuple > todaytuple: 54 print 'You are a time traveler. Go back to the future!' 55 return 56 57 if bdaytuple == todaytuple: 58 print 'You were born today. Have a nice life!' 59 return 60 61 days = todaydate - bdaydate 62 print 'You have lived', days, 'days' 63 64 age = 0 65 for y in range(year, todaytuple[0] + 1): 66 if bdaytuple < (y, month, day) <= todaytuple: 67 age = age + 1 68 69 print 'You are', age, 'years old' 70 71 if todaytuple[1:] == bdaytuple[1:]: 72 print 'Congratulations! Today is your', nth(age), 'birthday' 73 print 'Yesterday was your', 74 else: 75 print 'Today is your', 76 print nth(days - age), 'unbirthday' 77 78def format((year, month, day)): 79 return '%d %s %d' % (day, calendar.month_name[month], year) 80 81def nth(n): 82 if n == 1: return '1st' 83 if n == 2: return '2nd' 84 if n == 3: return '3rd' 85 return '%dth' % n 86 87def mkdate((year, month, day)): 88 # January 1st, in 0 A.D. is arbitrarily defined to be day 1, 89 # even though that day never actually existed and the calendar 90 # was different then... 91 days = year*365 # years, roughly 92 days = days + (year+3)//4 # plus leap years, roughly 93 days = days - (year+99)//100 # minus non-leap years every century 94 days = days + (year+399)//400 # plus leap years every 4 centirues 95 for i in range(1, month): 96 if i == 2 and calendar.isleap(year): 97 days = days + 29 98 else: 99 days = days + calendar.mdays[i] 100 days = days + day 101 return days 102 103if __name__ == "__main__": 104 main() 105