Skip to content

Instantly share code, notes, and snippets.

@dmurvihill
Created October 21, 2023 03:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dmurvihill/9759f0295073f1c800cf58fd8f311f6d to your computer and use it in GitHub Desktop.
Save dmurvihill/9759f0295073f1c800cf58fd8f311f6d to your computer and use it in GitHub Desktop.
Python date calculator
'''Simple date calculator for an interview question, homework problem, or programming kata.
Renders any number of seconds as a breakdown by years, days, hours, minutes, and seconds,
with proper grammar and a friendly hello. Unit names and sizes are fully customizable.
'''
YEARS = {
"singular": "year",
"plural": "years",
"next_unit": None
}
DAYS = {
"singular": "day",
"plural": "days",
"next_unit": YEARS,
"qty_in_next_unit": 365
}
MARTIAN_SOLS = {
"singular": "sol",
"plural": "sols",
"next_unit": YEARS,
"qty_in_next_unit": 670
}
HOURS = {
"singular": "hour",
"plural": "hours",
# "next_unit": DAYS,
# "qty_in_next_unit": 24
# Uncomment below and comment above for Mars mode.
"next_unit": MARTIAN_SOLS,
"qty_in_next_unit": 25 # (note: rounded up. A real sol is about 24h/40m)
}
MINUTES = {
"singular": "minute",
"plural": "minutes",
"next_unit": HOURS,
"qty_in_next_unit": 60
}
SECONDS = {
"singular": "second",
"plural": "seconds",
"next_unit": MINUTES,
"qty_in_next_unit": 60
}
def main():
print('Welcome to the time calculator!')
num_seconds = int(input('enter a number: '))
formatted_time = format_segmented_time(calc_segmented_time(num_seconds))
print(f"{num_seconds}s is " + formatted_time)
print("Let me know if I can compute another time for you! I've got nothing but time.")
def format_segmented_time(segmented_time):
rendered_segments = list(render_segments(segmented_time))
if (len(rendered_segments) == 0):
return 'no time at all!'
elif (len(rendered_segments) == 1):
return rendered_segments[0] + '.'
elif (len(rendered_segments) == 2):
return ' and '.join(rendered_segments) + '.'
else:
first_part = ', '.join(rendered_segments[0:-1])
oxford_comma = f", and {rendered_segments[-1]}"
return first_part + oxford_comma + '.'
def calc_segmented_time(qty, unit = SECONDS):
next_unit = unit["next_unit"]
if (qty == 0):
return []
elif next_unit is None:
return [(qty, unit)]
else:
unit_size = unit["qty_in_next_unit"]
out = qty % unit_size
return calc_segmented_time(qty // unit_size, next_unit) + [(out, unit)]
def render_segments(segmented_time):
for segment in segmented_time:
rendered = render_time_segment(segment)
if (rendered) != '':
yield rendered
def render_time_segment(segment):
(qty, unit) = segment
if (qty == 0):
return ""
elif (qty == 1):
return f"{qty} {unit['singular']}"
else:
return f"{qty} {unit['plural']}"
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment