#################################################### # Classes derived from Mydate() #################################################### class Holiday(Mydate): '''Subclass for different holidays''' def __repr__(self): '''Return object as string (e.g.) (2020)''' return f'{type(self).__name__}({self.mdy()[2]})' class Easterdate(Holiday): def __init__(self, year=None): # Code here to find m,d for easter of the given year # Also handle the case where year is None (using current year) Holiday.__init__(self,m,d,year) # Call "Holiday" init def __str__(self): '''Return object as string (e.g.) Easter Sunday, April 12, 2020''' # return f-string of the given format class FixedHoliday(Holiday): '''At the moment this class doesn't add anything to the Holiday class''' pass class July4date(FixedHoliday): def __init__(self, year = None): # Call constructor for FixedHoliday with m,d = 7,4 and year as the given year def __str__(self): '''Return object as string (e.g.) Saturday, July 4th, 2020''' # return f-string of the given format class Cincodemayo(FixedHoliday): def __init__(self, year = None): # Call FixedHoliday constructor with m,d = 5,5 and the given year def __str__(self): '''Return object as string (e.g.) Cinco de Mayo, Tuesday, May 5, 2020''' # return f-string of the given format class DOWholiday(Holiday): '''Holidays that occur on a particular weekday of a given month; for example, MLK day is the third Monday of Feburary ''' def __init__(self, month, dow, occurrence, year): '''The arguments passed are, e.g., for MLK day month, day, occurrence, year = 2,1,3,year''' # This code will compute the day of the month then # call the "Holiday" constructor with this month day and year. class Thanksgiving(DOWholiday): def __init__(self, year = None): # Call the DOWholiday constructor with 11, 4, 4, year def __str__(self): '''Return object as string (e.g.) Thanksgiving, November 26, 2020''' # return f-string of the given format (Note, no day of the week string) class IndigenousPeoples(DOWholiday): def __init__(self, year = None): # Call the DOWholiday constructor passing the second Monday in October def __str__(self): '''Return object as string (e.g.) Indigenous Peoples Day, Monday, October 12, 2020''' # return f-string of the given format def printstuff(date): '''Global function to look at repr() and str() for an object''' print(f"Object: {type(date).__name__}") print("repr():", repr(date)) print("str():", str(date)) print("eval(repr()):", eval(repr(date)), '\n') #################################################### # Some test code for the above #################################################### printstuff(Mydate(11, 9)) printstuff(Easterdate(2021)) printstuff(July4date(2021)) printstuff(Cincodemayo(2021)) printstuff(Thanksgiving(2021)) printstuff(IndigenousPeoples(2021)) printstuff(Mydate()) printstuff(Easterdate()) printstuff(July4date()) printstuff(Cincodemayo()) printstuff(Thanksgiving()) printstuff(IndigenousPeoples()) print("Trying some other operations") print("July 4 plus 4 days") printstuff(July4date() + 4) print("Thanksgiving - Easterdate") printstuff(Thanksgiving() - Easterdate()) print("Thanksgiving >= Easterdate") printstuff(Thanksgiving() >= Easterdate()) holidays = [Easterdate(), July4date(), Cincodemayo(), Thanksgiving(), IndigenousPeoples()] print(sorted(holidays)) printstuff(sorted(holidays)) for year in range(2018, 2023): print(Thanksgiving(year)) #################################################### # Test code results should be exactly this #################################################### Object: Mydate repr(): Mydate(11,9,2020) str(): Monday, November 9, 2020 eval(repr()): Monday, November 9, 2020 Object: Easterdate repr(): Easterdate(2021) str(): Easter Sunday, April 4, 2021 eval(repr()): Easter Sunday, April 4, 2021 Object: July4date repr(): July4date(2021) str(): Sunday, July 4th, 2021 eval(repr()): Sunday, July 4th, 2021 Object: Cincodemayo repr(): Cincodemayo(2021) str(): Cinco de Mayo, Wednesday, May 5, 2021 eval(repr()): Cinco de Mayo, Wednesday, May 5, 2021 Object: Thanksgiving repr(): Thanksgiving(2021) str(): Thanksgiving, November 25, 2021 eval(repr()): Thanksgiving, November 25, 2021 Object: IndigenousPeoples repr(): IndigenousPeoples(2021) str(): Indigenous Peoples Day, Monday, October 11, 2021 eval(repr()): Indigenous Peoples Day, Monday, October 11, 2021 Object: Mydate repr(): Mydate(11,8,2020) str(): Sunday, November 8, 2020 eval(repr()): Sunday, November 8, 2020 Object: Easterdate repr(): Easterdate(2020) str(): Easter Sunday, April 12, 2020 eval(repr()): Easter Sunday, April 12, 2020 Object: July4date repr(): July4date(2020) str(): Saturday, July 4th, 2020 eval(repr()): Saturday, July 4th, 2020 Object: Cincodemayo repr(): Cincodemayo(2020) str(): Cinco de Mayo, Tuesday, May 5, 2020 eval(repr()): Cinco de Mayo, Tuesday, May 5, 2020 Object: Thanksgiving repr(): Thanksgiving(2020) str(): Thanksgiving, November 26, 2020 eval(repr()): Thanksgiving, November 26, 2020 Object: IndigenousPeoples repr(): IndigenousPeoples(2020) str(): Indigenous Peoples Day, Monday, October 12, 2020 eval(repr()): Indigenous Peoples Day, Monday, October 12, 2020 Trying some other operations July 4 plus 4 days Object: Mydate repr(): Mydate(7,8,2020) str(): Wednesday, July 8, 2020 eval(repr()): Wednesday, July 8, 2020 Thanksgiving - Easterdate Object: int repr(): 228 str(): 228 eval(repr()): 228 Thanksgiving >= Easterdate Object: bool repr(): True str(): True eval(repr()): True [Easterdate(2020), Cincodemayo(2020), July4date(2020), IndigenousPeoples(2020), Thanksgiving(2020)] Object: list repr(): [Easterdate(2020), Cincodemayo(2020), July4date(2020), IndigenousPeoples(2020), Thanksgiving(2020)] str(): [Easterdate(2020), Cincodemayo(2020), July4date(2020), IndigenousPeoples(2020), Thanksgiving(2020)] eval(repr()): [Easterdate(2020), Cincodemayo(2020), July4date(2020), IndigenousPeoples(2020), Thanksgiving(2020)] Thanksgiving, November 22, 2018 Thanksgiving, November 28, 2019 Thanksgiving, November 26, 2020 Thanksgiving, November 25, 2021 Thanksgiving, November 24, 2022 #################################################### # Date Range class #################################################### class DateRange: '''Class representing a period of time''' def __init__(self, startdate=None, enddate=None, numdays = None): ''' Constructor should handle the following: DateRange(Mydate(), Mydate(12,31)) # Give start and end dates DateRange(Mydate(), 5) # Give start and number of days DateRange(enddate = Mydate(12,31)) # Start is today DateRange(numdays = 10) ''' if not bool(enddate) ^ bool(numdays): raise ValueError("exactly one of enddate or numdays must be given") self.startdate = startdate if startdate else Mydate() # finish constructor code, defining self.enddate def __len__(self): # if you need the len() '''Returns the number of days in interval, including start and end''' # Return the number of days in the range def __repr__(self): '''Returns object as (e.g.) DateRange(Mydate(1,1,2020), Mydate(1,31,2020))''' # return f-string of the given format def __str__(self): '''Returns object as (e.g.) Dates from Wednesday, January 1, 2020 to Friday, January 31, 2020) ''' # return f-string of the given format def __getitem__(self, position): # to allow indexing and slicing if isinstance( position, slice): start, stop, step = position.indices(len(self)) return [self.startdate + i for i in range(start, stop, step)] else: return self.startdate + position #################################################### # Test code for the above #################################################### range1 = DateRange(Mydate(1,1,2020), Mydate(1,31,2020)) print("len(range1):", len(range1)) print("range1[1]", range1[1]) print("range1[1:25:7]", range1[1:25:7]) print() printstuff(range1) range2 = DateRange(July4date(2020), 7) printstuff(range2) range3 = DateRange(July4date(2020), numdays = 7) # same printstuff(range3) range4 = DateRange(Easterdate(2020), enddate = July4date(2020)) printstuff(range4) print(f"Days until {Mydate(1,20,2021)}: {Mydate(1,20,2021) - Mydate()} ") #################################################### # The above should produce the following #################################################### len(range1): 31 range1[1] Thursday, January 2, 2020 range1[1:25:7] [Mydate(1,2,2020), Mydate(1,9,2020), Mydate(1,16,2020), Mydate(1,23,2020)] Object: DateRange repr(): DateRange(Mydate(1,1,2020), Mydate(1,31,2020)) str(): Dates from Wednesday, January 1, 2020 to Friday, January 31, 2020) eval(repr()): Dates from Wednesday, January 1, 2020 to Friday, January 31, 2020) Object: DateRange repr(): DateRange(July4date(2020), Mydate(7,11,2020)) str(): Dates from Saturday, July 4th, 2020 to Saturday, July 11, 2020) eval(repr()): Dates from Saturday, July 4th, 2020 to Saturday, July 11, 2020) Object: DateRange repr(): DateRange(July4date(2020), Mydate(7,11,2020)) str(): Dates from Saturday, July 4th, 2020 to Saturday, July 11, 2020) eval(repr()): Dates from Saturday, July 4th, 2020 to Saturday, July 11, 2020) Object: DateRange repr(): DateRange(Easterdate(2020), July4date(2020)) str(): Dates from Easter Sunday, April 12, 2020 to Saturday, July 4th, 2020) eval(repr()): Dates from Easter Sunday, April 12, 2020 to Saturday, July 4th, 2020) Days until Wednesday, January 20, 2021: 73