Here is the way I do this using functional programming - no global namespace pollution, proper inflection of plurals, only one function call at the very top of your script, all with only three imports, compatible with versions of Python starting from 3.6. I have this function in all my scripts:
import atexit
import re
import time
def time_script(): -> None
"""Local namespace to keep starting time as a free variable."""
starting_time = 0.0
@atexit.register
def time_script_enclosed(): -> None
"""Time your scripts easily. Run in the very beginning of the script."""
nonlocal starting_time
if not starting_time:
starting_time = time.perf_counter()
print(time.strftime("%H:%M:%S", time.localtime()), end="")
return print(": Starting script...")
runtime = int(time.perf_counter() - starting_time)
# Formatting with proper inflection of plurals
runtime = time.strftime(
"%#H hours, %#M minutes and %#S seconds", time.gmtime(runtime)
)
runtime = re.sub(r"^0 hours, ", "", runtime)
runtime = re.sub(r"^1 hours", "1 hour", runtime)
runtime = re.sub(r"(?=[^ ])0 minutes and ", "", runtime)
runtime = re.sub(r"(?=[^ ])1 minutes", "1 minute", runtime)
runtime = re.sub(r"(?=[^ ])1 seconds", "1 second", runtime)
return print(f"The script took {runtime} to run.")
time_script_enclosed()
Sample input:
def main():
time_script()
time.sleep(15)
if __name__ == '__main__':
main()
Output:
20:58:28: Starting script...
The script took 15 seconds to run.
Sample input:
def main():
time_script()
time.sleep(61)
if __name__ == '__main__':
main()
Output:
22:47:29: Starting script...
The script took 1 minute and 1 second to run.