How do I use a progress bar when my script is doing some task that is likely to take time?
For example, a function which takes some time to complete and returns
a little more generic answer of jelde015 (credit to him of course)
for updating the loading bar manually will be:
import sys
from math import *
def loadingBar(i, N, size):
percent = float(i) / float(N)
sys.stdout.write("\r"
+ str(int(i)).rjust(3, '0')
+"/"
+str(int(N)).rjust(3, '0')
+ ' ['
+ '='*ceil(percent*size)
+ ' '*floor((1-percent)*size)
+ ']')
and calling it by:
loadingBar(7, 220, 40)
will result:
007/220 [= ]
just call it whenever you want with the current i
value.
set the size
as the number of chars the bar should be
To use any progress-bar frameworks in a useful manner, to get an actual progress percent and an estimated ETA, you need to be able to declare how many steps it will have.
So, your compute function in another thread, are you able to split it in a number of logical steps? Can you modify its code?
You don't need to refactor or split it in any way, you could just put some strategic yield
s in some places or if it has a for loop, just one!
That way, your function will look something like this:
def compute():
for i in range(1000):
time.sleep(.1) # process items
yield # insert this and you're done!
Then just install:
pip install alive-progress
And use it like:
from alive_progress import alive_bar
with alive_bar(1000) as bar:
for i in compute():
bar()
To get a cool progress-bar!
|█████████████▎ | ▅▃▁ 321/1000 [32%] in 8s (40.1/s, eta: 16s)
Disclaimer: I'm the author of alive-progress, but it should solve your problem nicely. Read the documentation at https://github.com/rsalmei/alive-progress, here is an example of what it can do:
I really like the python-progressbar, as it is very simple to use.
For the most simple case, it is just:
import progressbar
import time
progress = progressbar.ProgressBar()
for i in progress(range(80)):
time.sleep(0.01)
The appearance can be customized and it can display the estimated remaining time. For an example use the same code as above but with:
progress = progressbar.ProgressBar(widgets=[progressbar.Bar('=', '[', ']'), ' ',
progressbar.Percentage(), ' ',
progressbar.ETA()])
When running in jupyter notebooks use of normal tqdm doesn't work, as it writes output on multiple lines. Use this instead:
import time
from tqdm import tqdm_notebook as tqdm
for i in tqdm(range(100))
time.sleep(0.5)
Try PyProg. PyProg is an open-source library for Python to create super customizable progress indicators & bars.
It is currently at version 1.0.2; it is hosted on Github and available on PyPI (Links down below). It is compatible with Python 3 & 2 and it can also be used with Qt Console.
It is really easy to use. The following code:
import pyprog
from time import sleep
# Create Object
prog = pyprog.ProgressBar(" ", "", 34)
# Update Progress Bar
prog.update()
for i in range(34):
# Do something
sleep(0.1)
# Set current status
prog.set_stat(i + 1)
# Update Progress Bar again
prog.update()
# Make the Progress Bar final
prog.end()
will produce:
Initial State:
Progress: 0% --------------------------------------------------
When half done:
Progress: 50% #########################-------------------------
Final State:
Progress: 100% ##################################################
I actually made PyProg because I needed a simple but super customizable progress bar library. You can easily install it with: pip install pyprog
.
PyProg Github: https://github.com/Bill13579/pyprog
PyPI: https://pypi.python.org/pypi/pyprog/
The code below is a quite general solution and also has a time elapsed and time remaining estimate. You can use any iterable with it. The progress bar has a fixed size of 25 characters but it can show updates in 1% steps using full, half, and quarter block characters. The output looks like this:
18% |████▌ | \ [0:00:01, 0:00:06]
Code with example:
import sys, time
from numpy import linspace
def ProgressBar(iterObj):
def SecToStr(sec):
m, s = divmod(sec, 60)
h, m = divmod(m, 60)
return u'%d:%02d:%02d'%(h, m, s)
L = len(iterObj)
steps = {int(x):y for x,y in zip(linspace(0, L, min(100,L), endpoint=False),
linspace(0, 100, min(100,L), endpoint=False))}
qSteps = ['', u'\u258E', u'\u258C', u'\u258A'] # quarter and half block chars
startT = time.time()
timeStr = ' [0:00:00, -:--:--]'
activity = [' -',' \\',' |',' /']
for nn,item in enumerate(iterObj):
if nn in steps:
done = u'\u2588'*int(steps[nn]/4.0)+qSteps[int(steps[nn]%4)]
todo = ' '*(25-len(done))
barStr = u'%4d%% |%s%s|'%(steps[nn], done, todo)
if nn>0:
endT = time.time()
timeStr = ' [%s, %s]'%(SecToStr(endT-startT),
SecToStr((endT-startT)*(L/float(nn)-1)))
sys.stdout.write('\r'+barStr+activity[nn%4]+timeStr); sys.stdout.flush()
yield item
barStr = u'%4d%% |%s|'%(100, u'\u2588'*25)
timeStr = ' [%s, 0:00:00]\n'%(SecToStr(time.time()-startT))
sys.stdout.write('\r'+barStr+timeStr); sys.stdout.flush()
# Example
s = ''
for c in ProgressBar(list('Disassemble and reassemble this string')):
time.sleep(0.2)
s += c
print(s)
Suggestions for improvements or other comments are appreciated. Cheers!