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

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
查看更多
素衣白纱
3楼-- · 2018-12-31 18:45

Here's a short solution that builds the loading bar programmatically (you must decide how long you want it).

import time

n = 33  # or however many loading slots you want to have
load = 0.01  # artificial loading time!
loading = '.' * n  # for strings, * is the repeat operator

for i in range(n+1):
    # this loop replaces each dot with a hash!
    print('\r%s Loading at %3d percent!' % (loading, i*100/n), end='')
    loading = loading[:i] + '#' + loading[i+1:]
    time.sleep(load)
查看更多
只靠听说
4楼-- · 2018-12-31 18:46

It is quite straightforward in Python3:

   import time
   import math

    def show_progress_bar(bar_length, completed, total):
        bar_length_unit_value = (total / bar_length)
        completed_bar_part = math.ceil(completed / bar_length_unit_value)
        progress = "*" * completed_bar_part
        remaining = " " * (bar_length - completed_bar_part)
        percent_done = "%.2f" % ((completed / total) * 100)
        print(f'[{progress}{remaining}] {percent_done}%', end='\r')

    bar_length = 30
    total = 100
    for i in range(0, total + 1):
        show_progress_bar(bar_length, i, total)
        time.sleep(0.1)

    print('\n')
查看更多
唯独是你
5楼-- · 2018-12-31 18:46

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/

查看更多
柔情千种
6楼-- · 2018-12-31 18:48

Many of the answers above rely on external packages, but I also think (as some above stated) that most people just want a ready-made solution. The code below can be adapted to fit your needs by customizing the string part.

It is simpler and works without the need of a second thread to update the bar. Some packages above do that. A second thread can be a problem, for an ipython notebook, for example.

The code below only works with iterators that provide a length (i.e. len(iterator) must be defined).

import sys

def progressbar(it, prefix="", size=60):
    count = len(it)
    def _show(_i):
        x = int(size*_i/count)
        sys.stdout.write("%s[%s%s] %i/%i\r" % (prefix, "#"*x, "."*(size-x), _i, count))
        sys.stdout.flush()

    _show(0)
    for i, item in enumerate(it):
        yield item
        _show(i+1)
    sys.stdout.write("\n")
    sys.stdout.flush()

Example:

import time

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

Output:

Computing: [........................................] 0/15

...

Computing: [########................................] 3/15

...

Computing: [########################################] 15/15

it can be any iterable object with a len, e.g. ['a', 'b', 'c']` works just fine.

查看更多
初与友歌
7楼-- · 2018-12-31 18:50

You should link the progress bar to the task at hand (so that it measures the progress :D). For example, if you are FTPing a file, you can tell ftplib to grab a certain size buffer, let's say 128K, and then you add to your progress bar whatever percentage of the filesize 128k represents. If you are using the CLI, and your progress meter is 20 characters long, you would add one character when 1/20th of the file had transferred.

查看更多
登录 后发表回答