Enable Javascript in your browser and then refresh this page, for a much enhanced experience.
First solution in Clear category for Next Birthday by mortonfox
from typing import Dict, Tuple
Date = Tuple[int, int, int]
from calendar import isleap
from datetime import date
# Returns the date on which the birthday will fall in a particular year,
# taking into account Feb 29 birthdays and non-leap years.
def date_on_year(dtuple, year):
return date(year, 3, 1) if dtuple[1:] == (2, 29) and not isleap(year) else date(year, *dtuple[1:])
def next_birthday(today: Date, birthdates: Dict[str, Date]) -> Tuple[int, Dict[str, int]]:
today = date(*today)
mindays = 366
members = {}
for name, dtuple in birthdates.items():
# Find the family member's next birthday.
d = date_on_year(dtuple, today.year)
if d < today:
d = date_on_year(dtuple, today.year + 1)
days = (d - today).days
if days < mindays:
# If we found a closer birthday, restart the members dict.
mindays = days
members.clear()
if days == mindays:
members[name] = d.year - dtuple[0]
return (mindays, members)
if __name__ == '__main__':
FAMILY = {
'Brian': (1967, 5, 31),
'Léna': (1970, 10, 3),
'Philippe': (1991, 6, 15),
'Yasmine': (1996, 2, 29),
'Emma': (2000, 12, 25),
}
TESTS = [
((2020, 9, 8), (25, {'Léna': 50})),
((2021, 10, 4), (82, {'Emma': 21})),
((2022, 3, 1), (0, {'Yasmine': 26})),
]
for nb, (day, answer) in enumerate(TESTS, 1):
user_result = tuple(next_birthday(day, FAMILY.copy()))
if user_result != answer:
print(f'You failed the test #{nb}.')
print(f'Your result: {user_result}')
print(f'Right result: {answer}')
break
else:
print('Well done! Click on "Check" for real tests.')
Sept. 15, 2020
Comments: