Python Progress Bar

后端 未结 30 2222
礼貌的吻别
礼貌的吻别 2020-11-22 06:13

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

相关标签:
30条回答
  • 2020-11-22 06:59

    I used format() method to make a load bar. Here is my solution:

    import time
    
    loadbarwidth = 23
    
    for i in range(1, loadbarwidth + 1):
        time.sleep(0.1) 
    
        strbarwidth = '[{}{}] - {}\r'.format(
            (i * '#'),
            ((loadbarwidth - i) * '-'),
            (('{:0.2f}'.format(((i) * (100/loadbarwidth))) + '%'))
        )
    
        print(strbarwidth ,end = '')
    
    print()
    

    Output:

    [#######################] - 100.00%
    
    0 讨论(0)
  • 2020-11-22 07:00

    This answer doesn't rely on external packages, I also think that most people just want a ready-made piece of code. The code below can be adapted to fit your needs by customizing: bar progress symbol '#', bar size, text prefix etc.

    import sys
    
    def progressbar(it, prefix="", size=60, file=sys.stdout):
        count = len(it)
        def show(j):
            x = int(size*j/count)
            file.write("%s[%s%s] %i/%i\r" % (prefix, "#"*x, "."*(size-x), j, count))
            file.flush()        
        show(0)
        for i, item in enumerate(it):
            yield item
            show(i+1)
        file.write("\n")
        file.flush()
    

    Usage:

    import time
    
    for i in progressbar(range(15), "Computing: ", 40):
        time.sleep(0.1) # any calculation you need
    

    Output:

    Computing: [################........................] 4/15
    
    • Doesn't require a second thread. Some solutions/packages above require. A second thread can be a problem, for a jupyter notebook, for example.

    • Works with any iterable it means anything that len() can be used on. A list, a dict of anything for example ['a', 'b', 'c' ... 'g']

    • Works with generators only have to wrap it with a list(). For example for i in progressbar(list(your_generator), "Computing: ", 40):

    You can also change output by changing file to sys.stderr for example

    0 讨论(0)
  • 2020-11-22 07:01

    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(101):
        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: [##########] 100% Done...
    Test completed
    
    0 讨论(0)
  • 2020-11-22 07:01

    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 [==========          ]
    
    0 讨论(0)
  • 2020-11-22 07:02

    @Massagran: It works well in my programs. Furthermore, we need to add a counter to indicate the loop times. This counter plays as the argument of the method update. For example: read all lines of a test file and treat them on something. Suppose that the function dosth() do not concern in the variable i.

    lines = open(sys.argv[1]).readlines()
    i = 0
    widgets=[Percentage(), Bar()]
    pbar = ProgressBar(widgets=widgets,maxval=len(lines)).start()
    pbar.start()
    for line in lines:<pre>
        dosth();
        i += 1
        pbar.update(i)</pre>
    pbar.finish()
    

    The variable i controls the status of pbar via the method update

    0 讨论(0)
  • 2020-11-22 07:03

    Try progress from https://pypi.python.org/pypi/progress.

    from progress.bar import Bar
    
    bar = Bar('Processing', max=20)
    for i in range(20):
        # Do some work
        bar.next()
    bar.finish()
    

    The result will be a bar like the following:

    Processing |#############                   | 42/100
    
    0 讨论(0)
提交回复
热议问题