1

When I run my Python script, there is some function that takes up to a few minutes to complete, so I want to display on the shell some kind of timer that informs the user on the time elapsed.

Is there any such thing already ready to use in Python?

Ricky Robinson
  • 21,798
  • 42
  • 129
  • 185
  • 2
    It would require multi-threading – gerrit Jul 16 '12 at 14:36
  • Is the function also written in Python, so that you could add a few lines inside it? – DSM Jul 16 '12 at 14:41
  • nix command `time` will display amount of time it takes to execute command, but only after script has completed. – dm03514 Jul 16 '12 at 14:54
  • Do you mean that you want to know how much time it takes to run the function, or you want to have some sort of timer which increments as the function is running? – mgilson Jul 16 '12 at 15:03
  • I'm giving the user an estimate of how long they'll have to wait and I want to display a timer when my function starts so that the user won't have the impression that the script is taking forever to complete. Something like a progress bar would also do. – Ricky Robinson Jul 17 '12 at 10:20

5 Answers5

4

One simplistic way is to include a clock in your sys.ps1 prompt (the thing that normally defines the >>> prompt)

From the documentation for sys.ps1:

If a non-string object is assigned to either variable, its str() is re-evaluated each time the interpreter prepares to read a new interactive command; this can be used to implement a dynamic prompt.

In ~/.local/usercustomize.py (or more accurately, in whatever folder python -c 'import site; print site.USER_BASE' displays), you can add:

import sys
import datetime


class ClockPS1(object):
  def __repr__(self):
    now = datetime.datetime.now()
    return str(now.strftime("%H:%M:%S >>> "))


sys.ps1 = ClockPS1()

Then your prompt will look like this:

16:26:24 >>> import time
16:26:27 >>> time.sleep(10)
16:26:40 >>> 

It's not perfect, as the last time will be when the prompt appeared, not when the line was executed, but it might be of help. You could easily make this display the time in seconds between __repr__ invokations, and show that in the prompt.

ArtOfWarfare
  • 20,617
  • 19
  • 137
  • 193
dbr
  • 165,801
  • 69
  • 278
  • 343
  • I `LOVE` this answer - it's precisely the thing I was looking for. Just one question - is there a way I can now indent output so that it's more in line with everything else? – ArtOfWarfare Oct 31 '13 at 17:43
  • @ArtOfWarfare You mean if, say, you run `print "blah"`, you want the "blah" to be indented by 9 spaces (to line up with the timestamp)? You could intercept everything written to `sys.stdout` and `sys.stderr`, but it might be difficult to to nicely (e.g how would it handle long lines?) – dbr Nov 01 '13 at 10:11
  • 1
    Yeah, that's what I meant. I decided instead to just change the style of the time so that it gets printed as teal underlined text - it helps distinguish between prompts and output well enough. – ArtOfWarfare Nov 02 '13 at 05:35
1

The simplest way to do it would be to calculate the elapsed time in the function that takes a few minutes to complete and simply print that time to the shell. However depending on your function this probably is not the best solution.

The second way to do it would to use multi-threading. So have the function that takes awhile run in a thread, while your program then sits in a loop and prints out the elapsed time every so often and looks for the thread to be completed.

Something like:

import threading
import time
arg1=0
arg2=1
etc=2

# your function that takes a while.
# Note: If your function returns something or if you want to pass variables in/out,
# you have to use Queues
def yourFunction(arg1,arg2,etc):
    time.sleep(10) #your code would replace this

# Setup the thread
processthread=threading.Thread(target=yourFunction,args=(arg1,arg1,etc)) #set the target function and any arguments to pass
processthread.daemon=True
processthread.start() # start the thread

#loop to check thread and display elapsed time
while processthread.isAlive():
    print time.clock()
    time.sleep(1) # you probably want to only print every so often (i.e. every second)

print 'Done'

You can then get fancier by overwriting the time in the shell or even better, using a gui to display a progress bar!

Onlyjus
  • 5,799
  • 5
  • 30
  • 42
1

If you are on a Linux or BSD system, try the pv command (http://www.ivarch.com/programs/pv.shtml).

$ python -c 'import time;time.sleep(5)' | pv
   0B 0:00:05 [   0B/s ] [<=>                   ]

It will give you a timer and depending on how you code the output of your app, some other stats as well.

dowski
  • 3,188
  • 2
  • 20
  • 16
0

Are you talking about measuring the time it takes a function to complete and then print the HH:MM:SS.MS?

You can do:

import datetime, time

time_begin = datetime.datetime.fromtimestamp(time.time())
# call your function here
time_end = datetime.datetime.fromtimestamp(time.time())

print("Time elapsed: ", str(time_end - time_begin))
Carlos Quintanilla
  • 12,937
  • 3
  • 22
  • 25
0

you can use datetime

for example,

import datetime
import time

class Profiler(object):
    def __init__(self):
        self.start = 0
        self.duration = 0

    def start(self):
        self.start = datetime.datetime.now()

    def end(self):
        self.duration = datetime.datetime.now() - self.start

class SomeClass(Profiler):
    def __init__(self):
        Profiler.__init__(self)

    def do_someting(self):
        self.start()
        time.sleep(10)
        self.end()

if __name__ == "__main__":
    foo = SomeClass()
    foo.do_something()
    print 'Time :: ', foo.duration
kanghyojmun
  • 350
  • 2
  • 6