Square Root Day is an unofficial holiday celebrated on dates where both the day of the month and the month are the square root of the last two digits of the year. For example, the last two Square Root Days were celebrated on March 3, 2009 (3/3/09) and April 4, 2016 (4/4/16). The next Square Root Day will be observed on May 5, 2025 (5/5/25). The final Square Root Day of the century will occur on September 9, 2081 (9/9/2081).

Ron Gordon – a Redwood City (California, USA) high school teacher – established the first Square Root Day on September 9, 1981 (9/9/81). Gordon remains the holiday's publicist, sending news releases to world media outlets. Gordon's daughter set up a Facebook group1 where people can share how they were celebrating the day. One suggested way of celebrating the holiday is by eating square radishes, or other root vegetables cut into shapes with square cross sections, thus creating a "square root".

Square Root Day
The last Square Root Day was celebrated on March 3, 2009 (3/3/2009).

But Square Root Day is definitely not the only obscure holiday. Pi Day ($$\pi$$-day) is an annual celebration commemorating the mathematical constant $$\pi$$. Pi Day is observed on March 14 (or 3/14 in the month/day date format), since 3, 1 and 4 are the first three significant digits of $$\pi$$ in decimal form. Celebration usually starts at 1:59 p.m. since the six-digit approximation of $$\pi$$ is 3.14159.

In the year 2015, Pi Day had extra special significance on 3/14/15 at 9:26:53 a.m. and p.m., with the date and time representing the first 10 digits of $$\pi$$. That same second also contained a precise instant corresponding to all of the digits of $$\pi$$. But the ultimate $$\pi$$-moment was celebrated on March 14, 1592 at 6:53:58, since 3/14/1592 6:53:58 corresponds to the first twelve digits of $$\pi$$. Pi Day has been observed in many ways, including eating pie, throwing pies, discussing the significance of the number $$\pi$$ or organizing Einstein look-alike contests (Albert Einstein was born March 14, 1879).

pi pie
Pi pie as it is served in many schools and universities on March 14.

And what do you think about the annual holiday celebrated on the last Friday in July? There's something unnerving about standing silently in a crowded elevator. It's a brave person who breaks the uncomfortable silence – so Talk In An Elevator Day is dedicated to plucking up our courage and making polite small take whilst riding the elevator.

Assignment

Determine the next holiday that follows a given date. To do so, you first have to implement the following three functions that each take a date (datetime.date). Each function must return a Boolean value (bool) that indicates whether a particular (obscure) holiday is observed at the given date.

Now also implement a function next_holiday that has the following parameters:

The function must return the date (datetime.date) the next holiday of the given type is observed that follows the given date. If no date is given, the next holiday should follow today's date. Holidays are determined as dates for which the given function returns the value True. In case the value True is passed to the parameter self, the given date should also be taken into account in determining the next holiday. Otherwise, the given date should not be taken into account in determining the next holiday.

Preparation

In this assignment you can make use of the data types date and timedelta that are defined in the datetime module of the Python Standard Library2. Before starting to work on the actual assignment, you should first have a look at how Python responds when you execute the following sequence of instructions in an interactive Python session:

  1. >>> from datetime import date
    >>> birthday = date(1983, 1, 14)
    >>> d = date.today() - birthday
    >>> type(d)
    >>> d.days

  2. >>> from datetime import timedelta
    >>> birthday + timedelta(1)
    >>> day1 = birthday + timedelta(1)
    >>> day1
    >>> day2 = day1 + timedelta(1)
    >>> day2

  3. >>> today = date.today()
    >>> today
    >>> today.weekday()
    >>> tomorrow = today + timedelta(1)
    >>> tomorrow.weekday()
    >>> tomorrow.day

Make sure you understand why the different results are generated.

Example

>>> import datetime

>>> pi_day(datetime.date(2014, 3, 14))
True
>>> pi_day(datetime.date(2021, 5, 24))
False

>>> square_root_day(datetime.date(2016, 4, 4))
True
>>> square_root_day(datetime.date(2081, 9, 9))
True
>>> square_root_day(datetime.date(2014, 4, 5))
False

>>> elevator_day(datetime.date(2014, 7, 25))
True
>>> elevator_day(datetime.date(2015, 7, 21))
False

>>> next_holiday(holiday=square_root_day)
datetime.date(?, ?, ?)
>>> next_holiday(holiday=pi_day)
datetime.date(?, ?, ?)
>>> next_holiday(elevator_day, date=datetime.date(2014, 10, 12))
datetime.date(2015, 7, 31)
>>> next_holiday(pi_day, date=datetime.date(2015, 3, 14), self=True)
datetime.date(2015, 3, 14)
>>> next_holiday(date=datetime.date(2081, 9, 9), holiday=square_root_day)
datetime.date(2101, 1, 1)

Epilogue

New Year's Day normally falls one week after Christmas: If Christmas falls on a Thursday, then New Year's Day will fall on a Thursday as well. What is the most recent year in which Christmas and New Year's Day fell on different days of the week?

Trick question. Within any calendar year, Christmas and New Year's Day always fall on different days:

calendar
Within any calendar year, Christmas and New Year's Day always fall on different days.