A small proxy iterator showing a progress bar on the console. Only works with iterators that provide a length (i.e. len(iterator)
must be defined).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | import sys
def progressbar(it, prefix = "", size = 60):
count = len(it)
def _show(_i):
x = int(size*_i/count)
sys.stdout.write("%s[%s%s] %i/%i\r" % (prefix, "#"*x, "."*(size-x), _i, count))
sys.stdout.flush()
_show(0)
for i, item in enumerate(it):
yield item
_show(i+1)
sys.stdout.write("\n")
sys.stdout.flush()
|
Example:
import time
for i in progressbar(range(15), "Computing: ", 40):
time.sleep(0.1) # long computation
Output:
Computing: [........................................] 0/15
...
Computing: [########................................] 3/15
...
Computing: [########################################] 15/15
it
can be any iterable object with a len
, e.g. ['a', 'b', 'c']
works just fine.
I have tried in my system(python 2.6.2), I have to flush stdout to make it work well, or I can not see the animate.
@kamidox Huang: What's your operating system? Maybe this recipe does only work under Windows.
I've tried this on OS X (Python 2.6) ... it does not flush automatically. There's (at least) two ways to address this issue:
sys.stdout.flush()
after the print statementBoth ways work fine for me, though I find the second one a little bit more handy.
To run this under Python 3, a few changes are necessary:
size*i/count
will return a float, which won't work with string multiplication. Cast to int - OKprint
is a function now, the trailing comma to prevent a newline has been replaced by setting the keyword argumentend=''
And that's it. I've tested it on 3.1 (OS X 10.6), works fine there (not tested anywhere else).
Thanks for all the feedback. I updated the recipe to run under Python 2.x and 3.x on all platforms. I used
sys.stdout.write
instead ofprint
because it behaves in the same way on all versions of Python.std.stdout.flush()
does not hurt under Windows so I included it.(Tested with Python 2.6 and Python 3.1 under win32/x86.)
I adopted the iterator approach for PyPM's progress bar; re-usable via the applib package:
Link to textui.py: http://bitbucket.org/srid/applib/src/tip/applib/textui.py#cl-14
Tested on Windows, Linux and Mac. Also works on Python 3. Here's a sample screenshot:
Great I didn't you can do this so easy at the console. However, I'm not sure about the iterator stuff. A progress bar will be more useful when you can change the state of the progress bar when you make actual progress, not on regular intervals. You don't want the progress to advance on each step.
I had very good experience with this: http://developer.apple.com/mac/library/documentation/cocoa/reference/ApplicationKit/Classes/NSProgressIndicator_Class/Reference/Reference.html