#python #python_3x #алгоритм #рекурсия #timestamp
Мне нужна функция, которая принимает количество секунд и возвращает строку формата N г. N мес. N нед. N д. N ч. year = 31536000 month = 2592000 week = 604800 day = 86400 hour = 3600 from math import floor def parse_time(time_s): if time_s == 0: return None if time_s < hour: return 'меньше часа' if time_s >= year: return '{} г. '.format(floor(time_s / year)) + parse_time(time_s % year) if time_s >= month: return '{} мес. '.format(floor(time_s / month)) + parse_time(time_s % month) elif time_s >= week: return '{} нед. '.format(floor(time_s / week)) + parse_time(time_s % week) elif time_s >= day: return '{} д. '.format(floor(time_s / day)) + parse_time(time_s % day) else: return '{} ч.'.format(floor(time_s / hour)) Я написал такую функцию, но немного сомневаюсь в её корректности. year, month, week, day, hour – колличество секунд. Примеры запуска: print(parse_time(2827567.5759670734)) # 1 мес. 2 д. 17 ч. print(parse_time(269649.6857390404)) # 3 д. 2 ч.
Ответы
Ответ 1
Можно без рекурсии сделать: def parse_time(time_s): year = 31536000 month = 2592000 week = 604800 day = 86400 hour = 3600 if time_s == 0: return None if time_s < hour: return 'меньше часа' result = '' if time_s >= year: result += '{} г. '.format(int(time_s / year)) time_s %= year if time_s >= month: result += '{} мес. '.format(int(time_s / month)) time_s %= month if time_s >= week: result += '{} нед. '.format(int(time_s / week)) time_s %= week if time_s >= day: result += '{} д. '.format(int(time_s / day)) time_s %= day if time_s >= hour: result += '{} ч.'.format(int(time_s / hour)) return result Как видно, алгоритм повторяется, и меняется только пара элементов в нем, а значит это легко представить в цикле: def parse_time(time_s): items = [ (31536000, '{} г. '), (2592000, '{} мес. '), (604800, '{} нед. '), (86400, '{} д. '), (3600, '{} ч.'), ] if time_s == 0: return None if time_s < 3600: return 'меньше часа' result = '' for value, fmt in items: if time_s >= value: result += fmt.format(int(time_s / value)) time_s %= value return result Пример: print(parse_time(2827567.5759670734)) # 1 мес. 2 д. 17 ч. assert parse_time(2827567.5759670734) == "1 мес. 2 д. 17 ч." print(parse_time(269649.6857390404)) # 3 д. 2 ч. assert parse_time(269649.6857390404) == "3 д. 2 ч." PS. floor можно заменить на int. Разница между floor и int проявится на отрицательных числах.Ответ 2
Для простоты можно разделить чистые вычисления и форматирование (ввод/вывод). К примеру, можно реализовать отдельно функцию, которая разделяет секунды на отдельные единицы времени (годы, дни, часы, итд): def broken_down_time( seconds, units=[ ("year", 31536000), ("month", 2592000), ("week", 604800), ("day", 86400), ("hour", 3600), ], ): t = {} for unit, value in units: if seconds >= value: t[unit], seconds = divmod(seconds, value) return t Пример: >>> broken_down_time(2827567) {'month': 1, 'day': 2, 'hour': 17} >>> broken_down_time(269649) {'day': 3, 'hour': 2} От функции, которая форматирует полученное время: def format_time( t, units=[ ("year", "г."), ("month", "мес."), ("week", "нед."), ("day", "д."), ("hour", "ч."), ], ): return " ".join(f"{t[unit]} {unit_ru}" for unit, unit_ru in units if unit in t) Пример: >>> format_time(broken_down_time(seconds=2827567)) '1 мес. 2 д. 17 ч.' Здесь float->int преобразование до вызова функций сделано. Чтобы не дублировать набор единиц времени, можно класс создать, который принимает единицы времени, секунды и позволяет обращаться к отдельным компонентам, выводить локализованное текстовое представление (то есть объединяет приведённые функции). К примеру, как это pendulum.interval делает.
Комментариев нет:
Отправить комментарий