Python Progress Bar

后端 未结 30 2750
礼貌的吻别
礼貌的吻别 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: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!

提交回复
热议问题