5
\$\begingroup\$

I'm self taught in python 3, and I frequently keep track of how long my scripts have been running using the time library.

import time
startTime = time.time()

#The main body of script...

print('The script finished in {0} seconds'.format(time.time() - startTime)

However this can be unhelpful if the script has been running for some time, an example output being:

'The script has been running for 4323.580279111862 seconds'

I wrote a function which takes a float variable and prints the time in a more readable way. I convert the seconds to integer to get rid of the 12 decimal places, and I can pass a boolean value which changes the wording of the print to indicate that the script is still running or has finished.

def printRuntime(seconds,finished=False):
    seconds = int(seconds)
    status = 'has been running for'
    if finished == True:
        status = 'finished in'

    if seconds < 60:
        print('The script {} {} seconds'.format(status,seconds))
        return
    elif seconds < 3600:
        minutes = seconds // 60
        seconds = seconds - 60*minutes
        print('The script {} {} minutes & {} seconds'.format(status,minutes,seconds))
        return
    else:
        hours = seconds // 3600
        minutes = (seconds - 3600*hours) // 60
        seconds = seconds - 3600*hours - 60*minutes
        print('The script {} {} hours, {} minutes & {} seconds'.format(status,hours,minutes,seconds))
        return

import time
startTime = time.time()

#The main body of script...

printRuntime(time.time() - startTime)

Since I'm self taught I have no real idea about best practice. I feel like there must be a more concise way of doing this, what mistakes am I making?

\$\endgroup\$
5
\$\begingroup\$

There is a built-in timeit module which is quite convenient for measuring execution times, but, if we were to improve this particular solution, I would switch to using divmod as suggested by Brandon here, utilize short if/else version for the status definition and join the time value parts with a comma filtering non-zero values only.

Something along these lines:

seconds = int(seconds)
status = 'has been running for' if not finished else 'finished in'

minutes, seconds = divmod(seconds, 60)
hours, minutes = divmod(minutes, 60)

periods = [('hours', hours), ('minutes', minutes), ('seconds', seconds)]
time_string = ', '.join('{} {}'.format(value, name)
                        for name, value in periods
                        if value)

print('The script {} {}'.format(status, time_string))
\$\endgroup\$
-1
\$\begingroup\$

I am also self-taught and do it much the same as you.

For a different reason (wanted to periodically run functions) I was looking for "time until execute" logging, anyway, I codged this together after reading several examples (including this page).

def secs_to_dhms(seconds):
    from datetime import datetime, timedelta    
    d = datetime(1,1,1) + timedelta(seconds=int(seconds))
    output = "{:02}:{:02}:{:02}:{:02}" .format(d.day-1, d.hour, d.minute, d.second)
    return output

Not exactly what you wanted, but maybe of use to you, anyway.

\$\endgroup\$
  • 2
    \$\begingroup\$ Welcome to Code Review! You have presented an alternative solution, but haven't reviewed the code. Please edit to show what aspects of the question code prompted you to write this version, and in what ways it's an improvement over the original. It may be worth (re-)reading How to Answer. \$\endgroup\$ – Toby Speight Nov 13 '18 at 16:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.