Birthdays have always been so predictable: someone who was born on October 5th is doomed to celebrate his anniversary each year on October 5th. That's why we have devised some alternative ways to celebrate your birthday. For example, if you were born on the 5th day of the month, which was a Wednesday, you could celebrate every 5th day of the month that also falls on a Wednesday. Or you might celebrate every hundredth day that you are alive. Moreover, these alternatives also solve the problem that people born on February 29th can only celebrate their birthdays once every four or eight years.

Humpty Dumpty
Humpty Dumpty wearing the cravat he received as an unbirthday present from the White King and Queen. From the book Through the Looking-Glass by Lewis Carroll, with illustrations by John Tenniel.

If you cannot get enough of it to celebrate your birthday, then this might be something for you. An unbirthday is celebrated on any of the 364 (365 in leap years) days in which it is not a person's anniversay. It is a neologism coined by Lewis Carroll in his Through the Looking-Glass, giving rise to The Unbirthday Song1 in the 1951 Disney animated feature film Alice in Wonderland.

Assignment

Start writing four functions that can be used to determine whether someone is celebrating his (alternative) birthday on a given date. This is indicated by the Boolean value (bool) returned by these functions. All functions take two dates (datetime.date): the date of birth of a person and the date of which must be determined whether it is an (alternative) anniversary.

Now also write a function birthdays that returns a tuple containing all (alternative) birthdays (datetime.date) that fall within the period between given start and end dates (including both dates). The birthdays must be listed in chronological order. The function takes the date of birth (datetime.date) of the person whose birthdays must be determined.

The function birthdays also has two optional parameters start and end, that can be used to pass the start and/or end dates (datetime.date) to the function. If no start date is explicitly passed when calling the function, the given date of birth must be used as the default value. If no end date is explicitly passed when calling the function, today's date must be used as the default value.

The function birthdays also has an optional parameter birthday, that can be used to pass a function that must be used to determine whether a given date is an (alternative) birthday. This function must have the same two parameters as the first four functions you have implemented for this assignment (to which a date of birth (datetime.date) and another date (datetime.date) must be passed respectively) and must return a Boolean value (bool) that indicates whether the given date is a birthday for someone born on the given date of birth. If no value is explicitly passed to the parameter birthday when calling the function birthdays, the function must return the anniversaries that fall within the period.

Example

>>> from datetime import date

>>> birthday(date(1969, 10, 5), date(2015, 10, 5))
True
>>> birthday(date(1969, 10, 5), date(1989, 10, 4))
False

>>> sameweekday(date(1969, 10, 5), date(2002, 5, 5))
True
>>> sameweekday(date(1969, 10, 5), date(1989, 10, 4))
False

>>> hundredday(date(1969, 10, 5), date(1975, 10, 14))
True
>>> hundredday(date(1969, 10, 5), date(1989, 10, 4))
False

>>> unbirthday(date(1969, 10, 5), date(2015, 10, 5))
False
>>> unbirthday(date(1969, 10, 5), date(1989, 10, 4))
True

>>> birthdays(date(1969, 10, 5), end=date(1972, 1, 1))
(datetime.date(1969, 10, 5), datetime.date(1970, 10, 5), datetime.date(1971, 10, 5))
>>> birthdays(date(1969, 10, 5), birthday=sameweekday, start=date(2020, 1, 1))
(datetime.date(2020, 1, 5), datetime.date(2020, 4, 5), datetime.date(2020, 7, 5), datetime.date(2021, 9, 5), datetime.date(2021, 12, 5), datetime.date(2022, 6, 5))
>>> birthdays(date(1969, 10, 5), start=date(1975, 1, 1), end=date(1976, 1, 1), birthday=hundredday)
(datetime.date(1975, 3, 28), datetime.date(1975, 7, 6), datetime.date(1975, 10, 14))