Python Progress Bar

2018-12-31 18:26发布

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 True when done. How can I display a progress bar during the time the function is being executed?

Note that I need this to be in real time, so I can't figure out what to do about it. Do I need a thread for this? I have no idea.

Right now I am not printing anything while the function is being executed, however a progress bar would be nice. Also I am more interested in how this can be done from a code point of view.

标签: python
27条回答
笑指拈花
2楼-- · 2018-12-31 18:57

for a similar application (keeping track of the progress in a loop) I simply used the python-progressbar:

Their example goes something like this,

from progressbar import *               # just a simple progress bar


widgets = ['Test: ', Percentage(), ' ', Bar(marker='0',left='[',right=']'),
           ' ', ETA(), ' ', FileTransferSpeed()] #see docs for other options

pbar = ProgressBar(widgets=widgets, maxval=500)
pbar.start()

for i in range(100,500+1,50):
    # here do something long at each iteration
    pbar.update(i) #this adds a little symbol at each iteration
pbar.finish()
print
查看更多
大哥的爱人
3楼-- · 2018-12-31 18:58

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)
查看更多
零度萤火
4楼-- · 2018-12-31 18:59

The above suggestions are pretty good, but I think most people just want a ready made solution, with no dependencies on external packages, but is also reusable.

I got the best points of all the above, and made it into a function, along with a test cases.

To use it, just copy the lines under "def update_progress(progress)" but not the test script. Don't forget to import sys. Call this whenever you need to display or update the progress bar.

This works by directly sending the "\r" symbol to console to move cursor back to the start. "print" in python does not recongise the above symbol for this purpose, hence we need 'sys'

import time, sys

# update_progress() : Displays or updates a console progress bar
## Accepts a float between 0 and 1. Any int will be converted to a float.
## A value under 0 represents a 'halt'.
## A value at 1 or bigger represents 100%
def update_progress(progress):
    barLength = 10 # Modify this to change the length of the progress bar
    status = ""
    if isinstance(progress, int):
        progress = float(progress)
    if not isinstance(progress, float):
        progress = 0
        status = "error: progress var must be float\r\n"
    if progress < 0:
        progress = 0
        status = "Halt...\r\n"
    if progress >= 1:
        progress = 1
        status = "Done...\r\n"
    block = int(round(barLength*progress))
    text = "\rPercent: [{0}] {1}% {2}".format( "#"*block + "-"*(barLength-block), progress*100, status)
    sys.stdout.write(text)
    sys.stdout.flush()


# update_progress test script
print "progress : 'hello'"
update_progress("hello")
time.sleep(1)

print "progress : 3"
update_progress(3)
time.sleep(1)

print "progress : [23]"
update_progress([23])
time.sleep(1)

print ""
print "progress : -10"
update_progress(-10)
time.sleep(2)

print ""
print "progress : 10"
update_progress(10)
time.sleep(2)

print ""
print "progress : 0->1"
for i in range(100):
    time.sleep(0.1)
    update_progress(i/100.0)

print ""
print "Test completed"
time.sleep(10)

This is what the result of the test script shows (The last progress bar animates):

progress : 'hello'
Percent: [----------] 0% error: progress var must be float
progress : 3
Percent: [##########] 100% Done...
progress : [23]
Percent: [----------] 0% error: progress var must be float

progress : -10
Percent: [----------] 0% Halt...

progress : 10
Percent: [##########] 100% Done...

progress : 0->1
Percent: [##########] 99.0%
Test completed
查看更多
君临天下
5楼-- · 2018-12-31 19:00

If it is a big loop with a fixed amount of iterations that is taking a lot of time you can use this function I made. Each iteration of loop adds progress. Where count is the current iteration of the loop, total is the value you are looping to and size(int) is how big you want the bar in increments of 10 i.e. (size 1 =10 chars, size 2 =20 chars)

import sys
def loadingBar(count,total,size):
    percent = float(count)/float(total)*100
    sys.stdout.write("\r" + str(int(count)).rjust(3,'0')+"/"+str(int(total)).rjust(3,'0') + ' [' + '='*int(percent/10)*size + ' '*(10-int(percent/10))*size + ']')

example:

for i in range(0,100):
     loadingBar(i,100,2)
     #do some code 

output:

i = 50
>> 050/100 [==========          ]
查看更多
何处买醉
6楼-- · 2018-12-31 19:00
梦该遗忘
7楼-- · 2018-12-31 19:02

There are specific libraries (like this one here) but maybe something very simple would do:

import time
import sys

toolbar_width = 40

# setup toolbar
sys.stdout.write("[%s]" % (" " * toolbar_width))
sys.stdout.flush()
sys.stdout.write("\b" * (toolbar_width+1)) # return to start of line, after '['

for i in xrange(toolbar_width):
    time.sleep(0.1) # do real work here
    # update the bar
    sys.stdout.write("-")
    sys.stdout.flush()

sys.stdout.write("\n")

Note: this progressbar is a fork of progressbar which hasn't been maintained in years.

查看更多
登录 后发表回答