##################################### # Global functions ##################################### def getJDN(month, day, year = None, julian = False): # JDN at at noon on the day if year == None: year = datetime.now().year month, year = (month, year) if month > 2 else (month+12, year-1) a = year//100 b = 2 - a + a//4 if not julian else 0 if year < 0: year += 1 JDN = int(365.25 * year - (0 if year>0 else .75)) + int(30.6001 * (month + 1)) + day + 1720995 + b return JDN def JDN2date(jdn, julian = False): # JDN at the previous noon jd = jdn + 0.5 # useless here Z,F = int(jdn), jdn-int(jdn) if julian: A = Z else: alpha = (Z-1867216.25)//36524.25 A = Z + 1 + alpha - alpha//4 B = A + 1524 C = int((B-122.1)/365.25) D = int(365.25 * C) E = int((B - D)/30.6001) day = int(B - D - int(30.6001 * E) + F) # note floor on the day month = E - (1 if E < 13.5 else 13) year = C - (4716 if month > 2.5 else 4715) return month, day, year def easter(year): _,A = divmod(year, 19) B,C = divmod(year, 100) D,E = divmod(B, 4) F,_ = divmod(B+8, 25) G,_ = divmod(B-F+1, 3) _,H = divmod(19*A + B - D - G + 15, 30) I,K = divmod(C, 4) _,L = divmod(32 + 2*E + 2*I - H - K, 7) M,_ = divmod(A + 11*H + 22*L, 451) N,P = divmod(H + L - 7*M + 114, 31) return N, P+1 ##################################### # Mydate class ##################################### class Mydate: '''Class to encapuslate our Julian Day Number functions''' def __init__(self, month = None, day = None, year = None, jdn = None): '''Constructor possibilities: Mydate() # today Mydate(month,day) # year is this year Mydate(month,day, year) Mydate(JDN) ''' def getjdn(self): '''Return the julian day number''' def mdy(self): '''Return month, day, year as a tuple''' def mdystr(self): '''Return month, day, year as a string. e.g., May 5, 2020''' def __repr__(self): '''Return month, day,year as a string. e.g., May 5, 2020''' def dow(self): '''Returns the day of the week as an int (Sunday = 0, etc.)''' def dowstr(self): '''Returns the day of the week as a string ('Sunday', etc.)''' def ddays(self, date2): '''Returns the number of days between given date and this date (Positive for date2 before this date)''' def dateplusdays(self, ddays): '''Date of ddays beyond this date (as Mydate object)''' def thisnext(self, dow): '''Date of next (or this) day with given dow (as Mydate object)''' def isEaster(self): '''Returns true if this date is Easter''' ##################################### # Initial test code for Mydate class ##################################### # Results follow # Actual Responses will depend on the date the test is run # The constructor should accept the following forms: day1 = Mydate() # Today day2 = Mydate(2459156) # Day of given jdn day3 = Mydate(7,4) # Defaults to this year day4 = Mydate(7,4,1776) # Month, day year print(day1.getjdn()) print(day2.getjdn()) print(day3.mdy()) print(day3.mdystr()) print(day3) print(Mydate().mdystr()) print(Mydate()) print(day4.dow()) print(day4.dowstr()) print(Mydate().ddays(day4)) print(day3.dateplusdays(10)) print(day4.thisnext(0)) print(day4.thisnext(4)) print(Mydate(7,4,2020).isEaster()) print(Mydate(4,12,2020).isEaster()) ##################################### # Results ##################################### 2459156 2459156 (7, 4, 2020) July 4, 2020 July 4, 2020 November 2, 2020 November 2, 2020 4 Thursday 89240 July 14, 2020 July 7, 1776 July 4, 1776 False True ##################################### # Results if run in the interpreter ##################################### >>> from hw10 import * >>> day1 = Mydate() # Today >>> day2 = Mydate(2459156) # Day of given jdn >>> day3 = Mydate(7,4) # Defaults to this year >>> day4 = Mydate(7,4,1776) # Month, day year >>> >>> print(day1.getjdn()) 2459156 >>> print(day2.getjdn()) 2459156 >>> print(day3.mdy()) (7, 4, 2020) >>> print(day3.mdystr()) July 4, 2020 >>> print(day3) July 4, 2020 >>> print(Mydate().mdystr()) November 2, 2020 >>> print(Mydate()) November 2, 2020 >>> print(day4.dow()) 4 >>> print(day4.dowstr()) Thursday >>> print(Mydate().ddays(day4)) 89240 >>> print(day3.dateplusdays(10)) July 14, 2020 >>> print(day4.thisnext(0)) July 7, 1776 >>> print(day4.thisnext(4)) July 4, 1776 >>> print(Mydate(7,4,2020).isEaster()) False >>> print(Mydate(4,12,2020).isEaster()) True >>> ##################################### # Dunder tests ##################################### #Add at least five "dunders" to your class so it can handle: print(Mydate() + 3) print(Mydate() - 3) # __sub__ print(Mydate() - Mydate(1,1)) # __sub__ print(Mydate() == Mydate(7,4)) print(Mydate() < Mydate(7,4)) print(Mydate() <= Mydate(7,4)) print(Mydate() > Mydate(7,4)) print(Mydate() >= Mydate(7,4)) # Generate list of 5 random dates between given dates jd1,jd2 = Mydate(1,1).getjdn(), Mydate(12,31,2022).getjdn() randdates = [Mydate(randint(jd1,jd2)) for _ in range(5)] print(sorted(randdates)) # print the dates sorted ##################################### # Global function tests ##################################### def genrandomdate(date1, date2): '''Generator function with generates random dates between the two given dates, inclusive''' def earliest(dates): '''return the earliest among a list of dates''' def latest(dates): '''return the latest among a list of dates''' # Code to set "dates" to a list of 20 random dates this year print(dates) print(earliest(dates)) print(latest(dates)) # Code to set "tuesday" to a sublist of dates that fall on Tuesdays print(tuesdays) ##################################### # Example output from global function tests ##################################### [May 15, 2020, August 23, 2020, March 23, 2020, December 15, 2020, September 12, 2020, December 5, 2020, March 21, 2020, March 26, 2020, August 31, 2020, December 7, 2020, January 30, 2020, September 23, 2020, March 6, 2020, August 19, 2020, September 29, 2020, June 25, 2020, December 11, 2020, December 6, 2020, June 15, 2020, November 3, 2020] January 30, 2020 December 15, 2020 [December 15, 2020, September 29, 2020, November 3, 2020]