Python Progress Bar

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

    You can use tqdm:

    from tqdm import tqdm
    
    with tqdm(total=100, desc="Adding Users", bar_format="{l_bar}{bar} [ time left: {remaining} ]") as pbar:
        for i in range(100):
            time.sleep(3)
            pbar.update(1)
    

    In this example the progress bar is running for 5 minutes and it is shown like that:

    Adding Users:   3%|█████▊                                     [ time left: 04:51 ]                                                                                                        
    

    You can change it and customize it as you like.

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

    You can also use enlighten. The main advantage is you can log at the same time without overwriting your progress bar.

    import time
    import enlighten
    
    manager = enlighten.Manager()
    pbar = manager.counter(total=100)
    
    for num in range(1, 101):
        time.sleep(0.05)
        print('Step %d complete' % num)
        pbar.update()
    

    It also handles multiple progress bars.

    import time
    import enlighten
    
    manager = enlighten.Manager()
    odds = manager.counter(total=50)
    evens = manager.counter(total=50)
    
    for num in range(1, 101):
        time.sleep(0.05)
        if num % 2:
            odds.update()
        else:
            evens.update()
    
    0 讨论(0)
  • 2020-11-22 06:57

    Guess i'm a little late but this should work for people working with the current versions of python 3, since this uses "f-strings", as introduced in Python 3.6 PEP 498:

    Code

    from numpy import interp
    
    class Progress:
        def __init__(self, value, end, title='Downloading',buffer=20):
            self.title = title
            #when calling in a for loop it doesn't include the last number
            self.end = end -1
            self.buffer = buffer
            self.value = value
            self.progress()
    
        def progress(self):
            maped = int(interp(self.value, [0, self.end], [0, self.buffer]))
            print(f'{self.title}: [{"#"*maped}{"-"*(self.buffer - maped)}]{self.value}/{self.end} {((self.value/self.end)*100):.2f}%', end='\r')
    

    Example

    #some loop that does perfroms a task
    for x in range(21)  #set to 21 to include until 20
        Progress(x, 21)
    

    Output

    Downloading: [########------------] 8/20 40.00%
    
    0 讨论(0)
  • 2020-11-22 06:58

    I've just made a simple progress class for my needs after searching here for a equivalent solution. I thought I might a well post it.

    from __future__ import print_function
    import sys
    import re
    
    
    class ProgressBar(object):
        DEFAULT = 'Progress: %(bar)s %(percent)3d%%'
        FULL = '%(bar)s %(current)d/%(total)d (%(percent)3d%%) %(remaining)d to go'
    
        def __init__(self, total, width=40, fmt=DEFAULT, symbol='=',
                     output=sys.stderr):
            assert len(symbol) == 1
    
            self.total = total
            self.width = width
            self.symbol = symbol
            self.output = output
            self.fmt = re.sub(r'(?P<name>%\(.+?\))d',
                r'\g<name>%dd' % len(str(total)), fmt)
    
            self.current = 0
    
        def __call__(self):
            percent = self.current / float(self.total)
            size = int(self.width * percent)
            remaining = self.total - self.current
            bar = '[' + self.symbol * size + ' ' * (self.width - size) + ']'
    
            args = {
                'total': self.total,
                'bar': bar,
                'current': self.current,
                'percent': percent * 100,
                'remaining': remaining
            }
            print('\r' + self.fmt % args, file=self.output, end='')
    
        def done(self):
            self.current = self.total
            self()
            print('', file=self.output)
    

    Example :

    from time import sleep
    
    progress = ProgressBar(80, fmt=ProgressBar.FULL)
    
    for x in xrange(progress.total):
        progress.current += 1
        progress()
        sleep(0.1)
    progress.done()
    

    Will print the following:

    [======== ] 17/80 ( 21%) 63 to go

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

    Use the progress library!

    pip install progress
    

    Here is a custom subclass I wrote to format the ETA/Elapsed times into a better readable format:

    import datetime
    from progress.bar import IncrementalBar
    
    
    class ProgressBar(IncrementalBar):
        '''
        My custom progress bar that:
           - Show %, count, elapsed, eta
           - Time is shown in H:M:S format
        '''
    
        message = 'Progress'
        suffix  = '%(percent).1f%% (%(index)d/%(max)d) -- %(elapsed_min)s (eta: %(eta_min)s)'
    
        def formatTime(self, seconds):
            return str(datetime.timedelta(seconds=seconds))
    
        @property
        def elapsed_min(self):
            return self.formatTime(self.elapsed)
    
        @property
        def eta_min(self):
            return self.formatTime(self.eta)
    
    if __name__=='__main__':
        counter = 120
        bar     = ProgressBar('Processing', max=counter)
    
        for i in range(counter):
            bar.next()
            time.sleep(1)
    
        bar.finish()
    
    0 讨论(0)
  • 2020-11-22 06:59

    I like Gabriel answer, but i changed it to be flexible. You can send bar-length to the function and get your progress bar with any length that you want. And you can't have a progress bar with zero or negative length. Also, you can use this function like Gabriel answer (Look at the Example #2).

    import sys
    import time
    
    def ProgressBar(Total, Progress, BarLength=20, ProgressIcon="#", BarIcon="-"):
        try:
            # You can't have a progress bar with zero or negative length.
            if BarLength <1:
                BarLength = 20
            # Use status variable for going to the next line after progress completion.
            Status = ""
            # Calcuting progress between 0 and 1 for percentage.
            Progress = float(Progress) / float(Total)
            # Doing this conditions at final progressing.
            if Progress >= 1.:
                Progress = 1
                Status = "\r\n"    # Going to the next line
            # Calculating how many places should be filled
            Block = int(round(BarLength * Progress))
            # Show this
            Bar = "[{}] {:.0f}% {}".format(ProgressIcon * Block + BarIcon * (BarLength - Block), round(Progress * 100, 0), Status)
            return Bar
        except:
            return "ERROR"
    
    def ShowBar(Bar):
        sys.stdout.write(Bar)
        sys.stdout.flush()
    
    if __name__ == '__main__':
        print("This is a simple progress bar.\n")
    
        # Example #1:
        print('Example #1')
        Runs = 10
        for i in range(Runs + 1):
            progressBar = "\rProgress: " + ProgressBar(10, i, Runs)
            ShowBar(progressBar)
            time.sleep(1)
    
        # Example #2:
        print('\nExample #2')
        Runs = 10
        for i in range(Runs + 1):
            progressBar = "\rProgress: " + ProgressBar(10, i, 20, '|', '.')
            ShowBar(progressBar)
            time.sleep(1)
    
        print('\nDone.')
    
    # Example #2:
    Runs = 10
    for i in range(Runs + 1):
        ProgressBar(10, i)
        time.sleep(1)
    

    Result:

    This is a simple progress bar.

    Example #1

    Progress: [###-------] 30%

    Example #2

    Progress: [||||||||||||........] 60%

    Done.

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