Verjaardagen zijn zo voorspelbaar: als je geboren bent op 5 oktober, dan ben je voor de rest van je leven gedoemd om ook op 5 oktober je verjaardag te vieren. Daarom hebben we enkele alternatieve manieren bedacht om je geboortedag te vieren. Als je op de vijfde van de maand geboren bent en dat was een woensdag, dan zou je bijvoorbeeld elke vijfde van de maand kunnen vieren als die ook op een woensdag valt. Of je zou bijvoorbeeld elke honderdste dag dat je leeft kunnen vieren. Bovendien lossen deze alternatieven ook het probleem op dat mensen die op 29 februari geboren zijn anders maar om de vier jaar hun verjaardag kunnen vieren.

Humpty Dumpty
Humpty Dumpty draagt de stropdas die hij als geschenk voor zijn onjaardag gekregen heeft van de Witte Koning en Koningin. Uit het boek Through the Looking-Glass van Lewis Carroll, met illustraties van John Tenniel.

Als je er niet genoeg van kunt krijgen om je geboortedag te vieren, dan is dit misschien wel iets voor jou. Een onjaardag wordt gevierd op elk van de 364 (of 365 in het geval van een schrikkeljaar) dagen waarop een persoon niet zijn verjaardag viert. Het is een neologisme dat werd uitgevonden door Lewis Carroll voor zijn boek Through the Looking-Glass, en gaf aanleiding tot The Unbirthday Song1 in de Disney animatiefilm Alice in Wonderland uit 1951.

Opgave

Schrijf eerst en vooral vier functies waarmee kan bepaald worden of iemand op een gegeven datum zijn (alternatieve) verjaardag viert. Dit wordt aangegeven door de Booleaanse waarde (bool) die door de functies teruggegeven wordt. Aan deze functies moeten telkens twee datums (datetime.date) doorgegeven: de geboortedatum van de persoon en de datum waarvan moet bepaald worden of het een verjaardag is.

Schrijf nu ook nog een functie verjaardagen die een tuple teruggeeft met alle (alternatieve) verjaardagen (datetime.date) die vallen tussen een startdatum en een einddatum (inclusief deze datums zelf). De verjaardagen moeten daarbij in chronologische volgorde opgelijst worden. Aan de functie moet de geboortedatum (datetime.date) doorgegeven worden van de persoon waarvan de verjaardagen moeten bepaald worden.

De functie verjaardagen heeft ook nog twee optionele parameters start en einde waaraan respectievelijk de startdatum en de einddatum van de periode kunnen doorgegeven worden. Als de startdatum niet expliciet wordt opgegeven bij het aanroepen van de functie, dan moet de geboortedatum als startwaarde gebruikt worden. Als de einddatum niet expliciet wordt opgegeven bij het aanroepen van de functie, dan moet de datum van vandaag als eindwaarde gebruikt worden.

De functie verjaardagen heeft ook nog een optionele parameter verjaardag, waaraan een functie kan doorgegeven worden die moet gebruikt wordt om de verjaardagen te bepalen. Deze functie moet dezelfde twee parameters hebben als de eerste vier functies die je voor deze opgave hebt geschreven (waaraan respectievelijk een geboortedatum (datetime.date) en een datum (datetime.date) moeten doorgegeven worden) en moet een Booleaanse waarde (bool) teruggeven die aangeeft of de gegeven datum al dan niet een verjaardag is voor iemand met de gegeven geboortedatum. Als er bij het aanroepen van de functie verjaardagen niet expliciet een waarde wordt doorgegeven aan de parameter verjaardag, dan moet de functie een lijst met alle gewone verjaardagen teruggeven die binnen de periode vallen.

Voorbeeld

>>> from datetime import date

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

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

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

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

>>> verjaardagen(date(1969, 10, 5), einde=date(1972, 1, 1))
(datetime.date(1969, 10, 5), datetime.date(1970, 10, 5), datetime.date(1971, 10, 5))
>>> verjaardagen(date(1969, 10, 5), verjaardag=verweekdag, 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))
>>> verjaardagen(date(1969, 10, 5), start=date(1975, 1, 1), einde=date(1976, 1, 1), verjaardag=verhonderddag)
(datetime.date(1975, 3, 28), datetime.date(1975, 7, 6), datetime.date(1975, 10, 14))