Python Progress Bar

307

Как использовать индикатор выполнения, когда мой сценарий выполняет какую-то задачу, которая может занять некоторое время?

Например, функция, которая требует некоторого времени для завершения и возвращает Trueпосле завершения. Как я могу отобразить индикатор выполнения во время выполнения функции?

Обратите внимание, что мне нужно, чтобы это было в режиме реального времени, поэтому я не могу понять, что с этим делать. Нужно ли threadдля этого? Я понятия не имею.

Прямо сейчас я ничего не печатаю во время выполнения функции, однако индикатор выполнения был бы неплох. Также меня больше интересует, как это можно сделать с точки зрения кода.

user225312
источник
Используете ли вы инструментарий GUI или только CLI?
Бобби
CLI. Но я могу использовать стороннюю библиотеку, это не проблема. С GUI я могу это сделать, но меня заинтересовала часть CLI.
user225312
1
Возможное дублирование текстовой строки прогресса в консоли. Обратите внимание, что, хотя этот вопрос был опубликован тремя днями ранее, связанный вопрос просматривается чаще.
Greenstick
Вот решение для Jupyter Notebook: mikulskibartosz.name/…
Стивен Хоуэлл
Я опубликовал новый вид индикатора выполнения, который вы можете распечатать, увидеть пропускную способность и т. Д., Даже приостановить его, кроме очень крутой анимации! Пожалуйста, посмотрите: github.com/rsalmei/alive-progress ! живой прогресс
rsalmei

Ответы:

185

Существуют определенные библиотеки ( например, здесь ), но может быть что-то очень простое:

import time
import sys

toolbar_width = 40

# setup toolbar
sys.stdout.write("[%s]" % (" " * toolbar_width))
sys.stdout.flush()
sys.stdout.write("\b" * (toolbar_width+1)) # return to start of line, after '['

for i in xrange(toolbar_width):
    time.sleep(0.1) # do real work here
    # update the bar
    sys.stdout.write("-")
    sys.stdout.flush()

sys.stdout.write("]\n") # this ends the progress bar

Примечание: progressbar2 - это ветвь ProgressBar, которая не поддерживалась годами.

ChristopheD
источник
14
это не масштабируется для многих шагов ... pypi.python.org/pypi/progress гораздо проще в использовании
m13r
5
Я попробовал этот код, и он бросил NameError: name 'xrange' is not definedошибку. Я пропускаю модуль?
Грибной Человек
6
@ GokuMcSpock9733 Какую версию Python вы используете? Питон 2 xrange- это Питон 3 range.
квапка
9
Это не должно быть лучшим ответом. Другой ответ (с tqdm) для меня намного лучше, по крайней мере.
Флориан,
1
Прогресс для бедных в Python 3:print('■', end='', flush=True)
PatrickT
352

С tqdm вы можете добавить индикатор прогресса в ваши циклы в секунду:

In [1]: import time

In [2]: from tqdm import tqdm

In [3]: for i in tqdm(range(10)):
   ....:     time.sleep(3)

 60%|██████    | 6/10 [00:18<00:12,  0.33 it/s]

Также существует графическая версия tqdm, поскольку v2.0.0( d977a0c):

In [1]: import time

In [2]: from tqdm import tqdm_gui

In [3]: for i in tqdm_gui(range(100)):
  ....:     time.sleep(3)

окно tqdm gui

Но будьте осторожны, поскольку вы tqdm_guiможете вызвать a TqdmExperimentalWarning: GUI is experimental/alpha, вы можете игнорировать его, используя warnings.simplefilter("ignore"), но он будет игнорировать все предупреждения в вашем коде после этого.

SCLS
источник
9
Это единственное решение, которое я нашел для работы с терминалом, qtconsole и ноутбуком
Ivelin
3
Работает ли это с любой итерацией? У меня были проблемы с получением его для работы со списком строк.
Джош Усре
3
@JoshUsre Да, он должен работать с любой итерацией, на данный момент я не видел ни одной итерации, которую он задушил. Однако отображение ETA (оставшегося времени) требует, чтобы итерация имела __len__свойство, или пользователь должен предоставить totalаргумент tqdm. Еще, бар будет работать, но без ETA.
Габорист
6
@gaborous: Почему это не самый популярный ответ? Это простое решение работает как в терминале, так и в ноутбуке Jupyter, в отличие от верхнего ответа.
Ébe Исаак
6
для работы в ноутбуке Jupyter использовать from tqdm import tqdm_notebook as tqdm. В противном случае не пишите это в одной строке.
Жак МАЛАПРАЙД
81

Приведенные выше предложения довольно хороши, но я думаю, что большинство людей просто хотят получить готовое решение, не зависящее от внешних пакетов, но также пригодное для повторного использования.

Я получил лучшие из всего вышеперечисленного и превратил его в функцию вместе с контрольными примерами.

Чтобы использовать его, просто скопируйте строки в «def update_progress (progress)», но не тестовый скрипт. Не забудьте импортировать sys. Вызывайте это всякий раз, когда вам нужно отобразить или обновить индикатор выполнения.

Это работает путем прямой отправки символа "\ r" на консоль, чтобы переместить курсор назад к началу. «print» в python не относится к вышеуказанному символу для этой цели, поэтому нам нужен '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)

Вот что показывает результат тестового скрипта (анимация последнего индикатора выполнения):

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
Брайан Хуу
источник
10
Анимированный тест (последний) должен in range(101)показывать не 100, прогресс останавливается на 99% и никогда не показывается.
Ник Хамрих
41

Этот ответ не зависит от внешних пакетов , я также думаю, что большинство людей просто хотят готовый кусок кода . Приведенный ниже код можно адаптировать к вашим потребностям, настроив: символ прогресса '#'строки size, строку , текст prefixи т. Д.

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()

Использование:

import time

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

Вывод:

Computing: [################........................] 4/15
  • Не требует второго потока . Некоторые решения / пакеты выше требуют. Второй поток может быть проблемой, jupyter notebookнапример, для.

  • Работает с любой итерацией, это означает все, что len()можно использовать. A list, dictо чем-нибудь, например['a', 'b', 'c' ... 'g']

Вы также можете изменить вывод, изменив файл, sys.stderrнапример, на

eusoubrasileiro
источник
Мне нравится это решение, генераторы будут TypeError: object of type 'generator' has no len()
выдавать
@jabellcu в этом случае ( generators) вы должны обернуть его с list(). Likefor i in progressbar(list(your_generator), "Computing: ", 40):
eusoubrasileiro
22

для аналогичного приложения (отслеживание прогресса в цикле) я просто использовал python-progressbar :

Их пример выглядит примерно так:

from progressbar import *               # just a simple progress bar


widgets = ['Test: ', Percentage(), ' ', Bar(marker='0',left='[',right=']'),
           ' ', ETA(), ' ', FileTransferSpeed()] #see docs for other options

pbar = ProgressBar(widgets=widgets, maxval=500)
pbar.start()

for i in range(100,500+1,50):
    # here do something long at each iteration
    pbar.update(i) #this adds a little symbol at each iteration
pbar.finish()
print
Massagran
источник
3
Для совместимости с Python 3 попробуйте progressbar2пакет. Код выше будет работать с ним.
d33tah
2
Вы действительно только что использовали import *?
Эриком
20

Попробуйте прогресс с 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()

Результатом будет строка, подобная следующей:

Processing |#############                   | 42/100
Владислав
источник
Просто попробовал это. ОЧЕНЬ прост в использовании. Мне потребовалось 2 минуты (включая процесс установки pip), чтобы строка состояния была запущена и работала.
Перелин
progressделает хорошие бары, но терпит неудачу , если другое программное обеспечение манипулирует stderr. извините, но я не исследовал точную проблему.
Артур
Он печатает одну строку для каждого прогресса в моей консоли Ubuntu, например, если max = 20, он печатает 20 строк ... Как мне сделать так, чтобы он печатал только одну строку?
L's World
19

Я только что сделал простой класс прогресса для своих нужд после поиска здесь эквивалентного решения. Я подумал, что могу опубликовать это.

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)

Пример :

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()

Напечатает следующее:

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

Ромуальд Брюне
источник
3
Здорово, спасибо тебе за это. Кстати, вы можете добавить progress.currentинкремент в конце, __call__чтобы еще больше ограничить взаимодействие с объектом из основного кода.
npit
Этот код прост, лаконичен и полезен! Спасибо!
Ян Ревинкель
15

Мне нравится ответ Брайана Хуу за его простоту и отсутствие необходимости во внешних пакетах. Я немного изменил его, поэтому добавляю свою версию здесь:

import sys
import time


def updt(total, progress):
    """
    Displays or updates a console progress bar.

    Original source: https://stackoverflow.com/a/15860757/1391441
    """
    barLength, status = 20, ""
    progress = float(progress) / float(total)
    if progress >= 1.:
        progress, status = 1, "\r\n"
    block = int(round(barLength * progress))
    text = "\r[{}] {:.0f}% {}".format(
        "#" * block + "-" * (barLength - block), round(progress * 100, 0),
        status)
    sys.stdout.write(text)
    sys.stdout.flush()


runs = 300
for run_num in range(runs):
    time.sleep(.1)
    updt(runs, run_num + 1)

Требуется общее количество запусков ( total) и количество обработанных запусков ( progress) total >= progress. Результат выглядит так:

[#####---------------] 27%
Габриель
источник
14

Вы можете использовать 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)

В этом примере индикатор выполнения работает в течение 5 минут, и он показан так:

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

Вы можете изменить его и настроить как вам угодно.

Eyal.D
источник
11

Чтобы использовать любые рамки индикаторов прогресса полезным способом, то есть получить фактический процент прогресса и предполагаемое ETA, вы должны быть в состоянии объявить, сколько шагов у него будет.

Итак, ваша вычислительная функция в другом потоке, вы можете разделить ее на несколько логических шагов? Можете ли вы изменить его код?

Вам не нужно реорганизовывать его или разделять на реальные методы, вы можете просто поместить некоторые стратегические yieldэлементы в некоторые места внутри него! Если в дорогой функции есть цикл for , просто поместите его в нее. Вы должны знать только в конце, сколько будет сделано урожая, чтобы получить лучшие результаты.

Таким образом, ваша функция может выглядеть примерно так:

def compute():
    time.sleep(1)  # some processing here
    yield  # insert these
    time.sleep(1)
    yield
    time.sleep(1)
    yield

или это:

def compute():
    for i in range(1000):
        time.sleep(.1)  # some processing here
        yield  # insert these

С такой функцией вы можете установить:

pip install alive-progress

И используйте это как:

from alive_progress import alive_bar

with alive_bar(3) as bar:  # or a 1000 in the loop example.
    for i in compute():
        bar()

Получить крутой прогресс-бар!

|█████████████▎                          | ▅▃▁ 1/3 [33%] in 1s (1.0/s, eta: 2s)

Отказ от ответственности: я являюсь автором alive_progress, но он должен хорошо решить вашу проблему. Прочитайте документацию по адресу https://github.com/rsalmei/alive-progress , вот пример того, что он может сделать:

жив-прогресс

rsalmei
источник
8

Мне очень нравится python-progressbar , так как он очень прост в использовании.

Для самого простого случая это просто:

import progressbar
import time

progress = progressbar.ProgressBar()
for i in progress(range(80)):
    time.sleep(0.01)

Внешний вид может быть настроен, и он может отображать приблизительное оставшееся время. Для примера используйте тот же код, что и выше, но с:

progress = progressbar.ProgressBar(widgets=[progressbar.Bar('=', '[', ']'), ' ',
                                            progressbar.Percentage(), ' ',
                                            progressbar.ETA()])
luator
источник
5

Если это большой цикл с фиксированным количеством итераций, занимающий много времени, вы можете использовать эту функцию, которую я сделал. Каждая итерация цикла добавляет прогресс. Где count - это текущая итерация цикла, total - это значение, к которому вы обращаетесь, а size (int) - насколько вы хотите, чтобы бар был с шагом 10, т. Е. (Размер 1 = 10 символов, размер 2 = 20 символов)

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 + ']')

пример:

for i in range(0,100):
     loadingBar(i,100,2)
     #do some code 

вывод:

i = 50
>> 050/100 [==========          ]
jelde015
источник
4

Используйте эту библиотеку: fish( GitHub ).

Использование:

>>> import fish
>>> while churning:
...     churn_churn()
...     fish.animate()

Радоваться, веселиться!

Etienne
источник
Это возможно. Вы должны спросить разработчика или оставить билет: github.com/lericson/fish .
Этьен
4

Приведенный ниже код является довольно общим решением, а также имеет оценку времени и оставшегося времени. Вы можете использовать любую итерацию с ним. Индикатор выполнения имеет фиксированный размер 25 символов, но он может отображать обновления с шагом 1%, используя символы полного, половины и четверти блока. Вывод выглядит так:

 18% |████▌                    | \ [0:00:01, 0:00:06]

Код с примером:

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)

Предложения по улучшению или другие комментарии приветствуются. Ура!

Niko
источник
3

Мне нравится эта страница .

Начинается с простого примера и переходит на многопоточную версию. Работает из коробки. Никаких сторонних пакетов не требуется.

Код будет выглядеть примерно так:

import time
import sys

def do_task():
    time.sleep(1)

def example_1(n):
    for i in range(n):
        do_task()
        print '\b.',
        sys.stdout.flush()
    print ' Done!'

print 'Starting ',
example_1(10)

Или вот пример использования потоков для запуска вращающейся полосы загрузки во время работы программы:

import sys
import time
import threading

class progress_bar_loading(threading.Thread):

    def run(self):
            global stop
            global kill
            print 'Loading....  ',
            sys.stdout.flush()
            i = 0
            while stop != True:
                    if (i%4) == 0: 
                        sys.stdout.write('\b/')
                    elif (i%4) == 1: 
                        sys.stdout.write('\b-')
                    elif (i%4) == 2: 
                        sys.stdout.write('\b\\')
                    elif (i%4) == 3: 
                        sys.stdout.write('\b|')

                    sys.stdout.flush()
                    time.sleep(0.2)
                    i+=1

            if kill == True: 
                print '\b\b\b\b ABORT!',
            else: 
                print '\b\b done!',


kill = False      
stop = False
p = progress_bar_loading()
p.start()

try:
    #anything you want to run. 
    time.sleep(1)
    stop = True
except KeyboardInterrupt or EOFError:
         kill = True
         stop = True
user1862895
источник
3

Это довольно просто в 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')
Антон Иванов
источник
3

При работе в ноутбуках Jupyter использование обычного tqdm не работает, так как записывает вывод в несколько строк. Используйте это вместо:

import time
from tqdm import tqdm_notebook as tqdm

for i in tqdm(range(100))
    time.sleep(0.5)
Жак МАЛАПРАД
источник
2

Если ваша работа не может быть разбита на измеримые куски, вы можете вызвать вашу функцию в новом потоке и узнать, сколько времени это займет:

import thread
import time
import sys

def work():
    time.sleep( 5 )

def locked_call( func, lock ):
    lock.acquire()
    func()
    lock.release()

lock = thread.allocate_lock()
thread.start_new_thread( locked_call, ( work, lock, ) )

# This part is icky...
while( not lock.locked() ):
    time.sleep( 0.1 )

while( lock.locked() ):
    sys.stdout.write( "*" )
    sys.stdout.flush()
    time.sleep( 1 )
print "\nWork Done"

Очевидно, вы можете увеличить точность синхронизации по мере необходимости.

bvanvugt
источник
Где можно выполнить работу, измеряемую в ответном коде?
unseen_rider
2

Мне нравится Габриэль ответ, но я изменил его, чтобы быть гибким. Вы можете отправить длину строки в функцию и получить индикатор выполнения с любой длиной, которую вы хотите. И вы не можете иметь индикатор выполнения с нулевой или отрицательной длиной. Кроме того, вы можете использовать эту функцию, как Габриэль ответ (см. Пример № 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)

Результат:

Это простой индикатор выполнения.

Пример № 1

Прогресс: [### -------] 30%

Пример № 2

Прогресс: [|||||||||||| ........] 60%

Готово.

Саид Захедян Абруди
источник
2

Я использовал format()метод, чтобы сделать бар нагрузки. Вот мое решение:

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()

Вывод:

[#######################] - 100.00%
Матеус Таварес
источник
1

Вот краткое решение, которое строит загрузочную полосу программно (вы должны решить, как долго вы этого хотите).

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)
этальна-когомология
источник
1

Попробуйте PyProg. PyProg - это библиотека с открытым исходным кодом для Python, позволяющая создавать супер настраиваемые индикаторы и индикаторы выполнения.

Это в настоящее время в версии 1.0.2; он размещен на Github и доступен на PyPI (ссылки внизу). Он совместим с Python 3 и 2, а также может использоваться с Qt Console.

Это действительно легко использовать. Следующий код:

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()

будет производить:

Initial State:
Progress: 0% --------------------------------------------------

When half done:
Progress: 50% #########################-------------------------

Final State:
Progress: 100% ##################################################

Я на самом деле сделал PyProg, потому что мне нужна простая, но супер настраиваемая библиотека индикатора выполнения. Вы можете легко установить с помощью : pip install pyprog.

PyProg Github: https://github.com/Bill13579/pyprog
PyPI: https://pypi.python.org/pypi/pyprog/

Билл Кудо
источник
1

Вы также можете использовать просветить . Основным преимуществом является то, что вы можете одновременно входить в систему, не перезаписывая свой индикатор выполнения.

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()

Он также обрабатывает несколько индикаторов выполнения.

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()
авизо
источник
1

Используйте библиотеку прогресса !

pip install progress

Вот пользовательский подкласс, который я написал, чтобы отформатировать ETA / Elapsed times в лучший читаемый формат:

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()
kakhkAtion
источник
1

Это мое простое решение:

import time

def progress(_cur, _max):
    p = round(100*_cur/_max)
    b = f"Progress: {p}% - ["+"."*int(p/5)+" "*(20-int(p/5))+"]"
    print(b, end="\r")

# USAGE:
for i in range(0,101):
    time.sleep(0.1) 
    progress(i,100)

print("..."*5, end="\r")
print("Done")
dododo
источник
0

Вы должны связать индикатор выполнения с поставленной задачей (чтобы он измерял прогресс: D). Например, если вы отправляете файл по FTP, вы можете указать ftplib захватить буфер определенного размера, скажем, 128 КБ, а затем добавить в свой индикатор выполнения любой процент от размера файла 128 КБ. Если вы используете CLI, а ваш индикатор прогресса имеет длину 20 символов, вы добавили бы один символ, когда была передана 1/20 файла.

johncip
источник
В моем случае я использую API, и он не предоставляет возможности для получения определенных кусков. Спасибо за идею, хотя, это приятно.
user225312
0

@Massagran: Это хорошо работает в моих программах. Кроме того, нам нужно добавить счетчик, чтобы указать время цикла. Этот счетчик играет роль аргумента метода update. Например: прочитать все строки тестового файла и обработать их на чем-нибудь. Предположим, что функция dosth()не относится к переменной 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()

Переменная iконтролирует состояние pbarчерез методupdate

Tung
источник
0

немного более общий ответ jelde015 (кредит ему, конечно)

Для обновления полосы загрузки вручную будет:

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)
                     + ']')

и называя это:

loadingBar(7, 220, 40)

приведет к:

007/220 [=                                       ]  

просто вызывайте его, когда хотите, с текущим iзначением.

установить sizeколичество символов в баре

Ярден Коэн
источник
0

Думаю, я немного опоздал, но это должно работать для людей, работающих с текущими версиями Python 3 , так как здесь используются "f-strings" , как представлено в Python 3.6 PEP 498 :

Код

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')

пример

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

Вывод

Downloading: [########------------] 8/20 40.00%
Густаво Баррос
источник
0

Это простой способ создать индикатор

import time,sys
toolbar_width = 50
# setting up toolbar [-------------------------------------]
sys.stdout.write("[%s]"%(("-")*toolbar_width))
sys.stdout.flush()
# each hash represents 2 % of the progress
for i in range(toolbar_width):
    sys.stdout.write("\r") # return to start of line
    sys.stdout.flush()
    sys.stdout.write("[")#Overwrite over the existing text from the start 
    sys.stdout.write("#"*(i+1))# number of # denotes the progress completed 
    sys.stdout.flush()
    time.sleep(0.1)
Прасант Селвакумар
источник