21. Порядковая дата в григорианский календарь.

(открыть в новой вкладке)

Условие:

Разработайте функцию, принимающую в качестве параметра порядковую дату, включающую в себя год и день по порядку.
В качестве результата функция должна возвращать день и месяц, соответствующие переданной порядковой дате. Убедитесь, что ваша функция корректно обрабатывает високосные годы.
Для начала должен производиться запрос года и порядковой даты у пользователя. После этого программа должна вычислить реальную дату и вывести её на экран.

Код:

import my_lib                                                                                           # импорт самописной библиотеки

# ввод данных
while True:
    try:
        year = input("%75s" % "Введите год (в формате 2023): ")
        year = int(year)
        day = input("%75s" % "Введите порядковый номер дня в году: ")
        day = int(day)        
        result = my_lib.digit_date_of_year(year, day)                                                   # на выходе кортеж из 2 элементов, результат функции из самописной библиотеки, первый элемент это флаг проверки существуте дата или нет (True/False) (с учётом високосного года), а второй элемент это реальная дата
        if result[0]:                                                                                  
            break        
    except:
        print("%74s" % "Вы ввели не цифры или несуществующий номер дня в году.")
         
print("%74s" % "Дата:", result[-1])
		

Код библиотеки:

# определяет дату по номеру дня в году
def our_date(leap, day): 
    dict_1 = {1: 31, 2: 28, 3: 31, 4: 30, 5: 31, 6: 30, 7: 31, 8: 31, 9: 30, 10: 31, 11: 30, 12: 31}                                                                # словарь для обычного года
    dict_2 = {1: 31, 2: 29, 3: 31, 4: 30, 5: 31, 6: 30, 7: 31, 8: 31, 9: 30, 10: 31, 11: 30, 12: 31}                                                                # словарь для високосного года
    dict_1_mod = dict()                                                                                                                                             # составим более интересный словарь, где значением ключа (месяца) является range из порядковых номеров в году
    dict_2_mod = dict()                                                                                                                                             # -||-
    if leap:                                                                                                                                                        # определение даты для високосного года
        temp_1 = 1        
        temp_2 = 1
        for a, b in dict_2.items():     
            temp_2 += b       
            dict_2_mod[a] = range(temp_1, temp_2)
            temp_1 += b
        max_of_last_month = 0
        for a, b in dict_2_mod.items():
            if day in b:
                result = str(a) + "-" + str(day - max_of_last_month)
            max_of_last_month = max(b)
    else:                                                                                                                                                           # определение даты для не високосного года
        temp_1 = 1        
        temp_2 = 1
        for a, b in dict_1.items():     
            temp_2 += b       
            dict_1_mod[a] = range(temp_1, temp_2)
            temp_1 += b
        max_of_last_month = 0
        for a, b in dict_1_mod.items():
            if day in b:
                result = str(a) + "-" + str(day - max_of_last_month)
            max_of_last_month = max(b)
    return result


# возвращает кортеж с двумя элементами, где первый элемент - это True или False (определяет существует такая дата или нет), а второй элемент - это реальная дата (определение даты переадресована в другую функцию)
def digit_date_of_year(year, day):     
    if (((year % 4 == 0 and year % 100 != 0) or (year % 100 == 0 and year % 400 == 0)) == False) and (day > 365 or day < 1):                                                  
        flag = False
        number = 0
    elif ((year % 4 == 0 and year % 100 != 0) or (year % 100 == 0 and year % 400 == 0)) and (day > 366 or day < 1):                  
        flag = False                                                                                                                                               
        number = 0       
    elif ((year % 4 == 0 and year % 100 != 0) or (year % 100 == 0 and year % 400 == 0)):                    
        flag = True
        leap = True
        number = our_date(leap, day) 
    elif (((year % 4 == 0 and year % 100 != 0) or (year % 100 == 0 and year % 400 == 0)) == False):                    
        flag = True
        leap = False
        number = our_date(leap, day)     
    return (flag, (str(year) + "-" + number))                                                                                                                        # возвращаем кортеж, первый элемент которого является флагом прошла дата проверку на существование или нет, а второй элемент это реальная дата