Enable Javascript in your browser and then refresh this page, for a much enhanced experience.
First solution in Clear category for Next Birthday by PythonLearner
import calendar
from datetime import date
from typing import Dict, Tuple
Date = Tuple[int, int, int]
FEBRUARY = 2
LEAP_DAY = 29
MARCH = 3
FIRST_DAY = 1
def birthday_date(birthdate: date, year: int) -> date:
month = birthdate.month
day = birthdate.day
if month == FEBRUARY and day == LEAP_DAY and not calendar.isleap(year):
month = MARCH
day = FIRST_DAY
return date(year, month, day)
def nearest_birthday_date(birthdate: date, today: date) -> date:
birthday = birthday_date(birthdate, today.year)
return birthday if today <= birthday else birthday_date(birthdate, today.year + 1)
def next_birthday(today: Date, birthdates: Dict[str, Date]) -> Tuple[int, Dict[str, int]]:
today_date = date(*today)
birthdates = {name: date(*birthdate) for name, birthdate in birthdates.items()}
nearest_birthdays = {name: nearest_birthday_date(birthdate, today_date) for name, birthdate in birthdates.items()}
nearest_birthday = min(nearest_birthdays.values())
names = {name for name in nearest_birthdays if nearest_birthdays[name] == nearest_birthday}
return (nearest_birthday-today_date).days, {name: nearest_birthday.year-birthdates[name].year for name in names}
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.')
Oct. 2, 2020
Comments: