Python Progress Bar

后端 未结 30 2219
礼貌的吻别
礼貌的吻别 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 07:05

    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

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

    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 yields 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:

    alive-progress

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

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

    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)
    
    0 讨论(0)
  • 2020-11-22 07:08

    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/

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

    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!

    0 讨论(0)
提交回复
热议问题