Barra de progresso do Python


307

Como uso uma barra de progresso quando meu script está executando alguma tarefa que provavelmente leva tempo?

Por exemplo, uma função que leva algum tempo para ser concluída e retorna Truequando concluída. Como posso exibir uma barra de progresso durante o tempo em que a função está sendo executada?

Observe que eu preciso que isso seja em tempo real, então não consigo descobrir o que fazer sobre isso. Preciso de um threadpara isso? Eu não faço ideia.

No momento, não estou imprimindo nada enquanto a função está sendo executada, no entanto, uma barra de progresso seria boa. Também estou mais interessado em como isso pode ser feito do ponto de vista do código.


Você está usando apenas um kit de ferramentas da GUI ou CLI?
Bobby

CLI. Mas eu posso usar uma biblioteca de terceiros, isso não é problema. Com a GUI, posso fazer isso, mas estava interessado na parte CLI.
User225312

1
Possível duplicata da barra de progresso do texto no console Observe que, embora essa pergunta tenha sido publicada três dias antes, a pergunta vinculada é exibida com mais frequência.
galho verde

Aqui está uma solução para dentro de um Notebook Jupyter: mikulskibartosz.name/...
Steven C. Howell

Publiquei um novo tipo de barra de progresso, que você pode imprimir, ver taxa de transferência e eta, até pausá-la, além das animações muito legais! Por favor, dê uma olhada: github.com/rsalmei/alive-progress ! viva-progress
rsalmei

Respostas:


185

Existem bibliotecas específicas ( como esta aqui ), mas talvez algo muito simples faria:

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

Nota: progressbar2 é uma bifurcação da progressbar que não é mantida há anos.


14
este não escala para muitos passos ... pypi.python.org/pypi/progress é muito mais fácil de usar
M13R

5
Eu tentei esse código e deu um NameError: name 'xrange' is not definederro. Estou faltando um módulo?
Mushroom Man

6
@ GokuMcSpock9733 Qual versão do Python você está usando? O Python 2 xrangeé o Python 3 range.
quapka

9
Esta não deve ser a resposta principal. A outra resposta (com tqdm) é muito melhor para mim, pelo menos.
Florian

1
Barra de progresso dos pobres em Python 3:print('■', end='', flush=True)
PatrickT

351

Com o tqdm, você pode adicionar um medidor de progresso aos seus loops em um segundo:

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]

Além disso, existe uma versão gráfica do tqdm since 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)

janela tqdm gui

Mas tenha cuidado, pois tqdm_guipode gerar a TqdmExperimentalWarning: GUI is experimental/alpha, você pode ignorá-lo usando warnings.simplefilter("ignore"), mas ele ignorará todos os avisos no seu código depois disso.


9
Esta é a única solução que eu encontrei para trabalhar com terminal, qtconsole e notebook
Ivelin

3
Funciona com qualquer iterável? Eu tive problemas para fazê-lo funcionar com uma lista de strings.
Josh usre

3
@ JoshUsre Sim, ele deve funcionar com qualquer iterável, no momento não vi nenhum iterável em que ele se engasgasse. No entanto, a exibição do ETA (tempo restante) exige que o iterável tenha uma __len__propriedade ou o usuário deve fornecer o totalargumento tqdm. Senão, a barra funcionará, mas sem ETA.
gaborous 30/05

6
@gaborous: Como é que essa não é a resposta mais votada? Esta solução simples funciona tanto no terminal quanto no notebook Jupyter, diferentemente da resposta principal.
EBE Isaac

6
para rodar em um notebook jupyter from tqdm import tqdm_notebook as tqdm. Caso contrário, não o escreverá em uma linha.
Jacques MALAPRADE 24/10

81

As sugestões acima são muito boas, mas acho que a maioria das pessoas quer apenas uma solução pronta, sem dependências de pacotes externos, mas também é reutilizável.

Consegui os melhores pontos de todas as opções acima e transformei-as em uma função, juntamente com um caso de teste.

Para usá-lo, basta copiar as linhas em "def update_progress (progress)", mas não o script de teste. Não se esqueça de importar o sistema. Ligue para isso sempre que precisar exibir ou atualizar a barra de progresso.

Isso funciona enviando diretamente o símbolo "\ r" para o console para mover o cursor de volta ao início. "print" em python não recongise o símbolo acima para esse fim, portanto precisamos de '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)

Isto é o que o resultado do script de teste mostra (a última barra de progresso é animada):

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
O teste animado (último) in range(101)não deve dizer 100, o progresso para em 99% e nunca é exibido.
Nick Humrich

41

Essa resposta não depende de pacotes externos , também acho que a maioria das pessoas quer apenas um pedaço de código pronto . O código abaixo pode ser adaptado para atender às suas necessidades, personalizando: símbolo de progresso da '#'barra size, barra , texto prefixetc.

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

Uso:

import time

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

Resultado:

Computing: [################........................] 4/15
  • Não requer um segundo segmento . Algumas soluções / pacotes acima exigem. Um segundo encadeamento pode ser um problema jupyter notebook, por exemplo , para um .

  • Funciona com qualquer iterável , significa qualquer coisa que len()possa ser usada. A list, a dictde qualquer coisa, por exemplo['a', 'b', 'c' ... 'g']

Você também pode alterar a saída alterando o arquivo para, sys.stderrpor exemplo


Eu gosto desta solução, geradores irá lançar o seguinte erro:TypeError: object of type 'generator' has no len()
jabellcu

@jabellcu nesse caso ( generators) você precisa envolvê-lo com a list(). Gostofor i in progressbar(list(your_generator), "Computing: ", 40):
eusoubrasileiro

22

para uma aplicação semelhante (acompanhando o progresso em um loop), simplesmente usei a python-progressbar :

O exemplo deles é mais ou menos assim,

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

3
Para compatibilidade com Python 3, tente o progressbar2pacote. O código acima funcionará com ele.
D33tah 25/05

2
Você realmente acabou de usar import *?
eric

20

Experimente o progresso em 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()

O resultado será uma barra como a seguinte:

Processing |#############                   | 42/100

Apenas tentei isso. MUITO fácil de usar. Demorei 2 minutos (incluindo o progresso da instalação do pip) para ter uma barra de status em funcionamento.
Perelin

progressproduz barras agradáveis, mas falha se outro software estiver manipulando stderr. desculpe, mas não investiguei o problema exato.
Arthur

Ele imprime uma linha para cada progresso no meu console ubuntu, por exemplo, se max = 20, imprime 20 linhas ... Como faço para imprimir apenas uma linha?
Mundo de L

19

Acabei de fazer uma classe de progresso simples para minhas necessidades depois de procurar aqui uma solução equivalente. Eu pensei que poderia muito bem publicá-lo.

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)

Exemplo:

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

Irá imprimir o seguinte:

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


3
Incrível, obrigado por isso. BTW, você pode adicionar o progress.currentincremento no final de __call__para limitar ainda mais a interação com o objeto a partir do código principal.
Npit 13/08/19

Este código é simples, conciso e útil! Obrigado!
Ian Rehwinkel

15

Gosto da resposta de Brian Khuu por sua simplicidade e por não precisar de pacotes externos. Eu mudei um pouco, então estou adicionando minha versão aqui:

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)

Leva o número total de execuções ( total) e o número de execuções processadas até agora ( progress) assumindo total >= progress. O resultado fica assim:

[#####---------------] 27%

14

Você pode usar o 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)

Neste exemplo, a barra de progresso está em execução por 5 minutos e é mostrada assim:

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

Você pode alterá-lo e personalizá-lo como quiser.


11

Para usar qualquer estrutura de barra de progresso de uma maneira útil, ou seja, para obter uma porcentagem real de progresso e um ETA estimado, você precisa ser capaz de declarar quantas etapas ele terá.

Então, sua função de computação em outro encadeamento, você pode dividir em várias etapas lógicas? Você pode modificar o código?

Você não precisa refatorar ou dividir em métodos reais; basta colocar alguns yields estratégicos em alguns lugares dentro dele! Se a função cara tiver um loop for , basta colocar um. No final, você só deve saber quanto rendimento será obtido para obter melhores resultados.

Dessa forma, sua função pode ser algo como isto:

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

ou isto:

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

Com esse tipo de função, você pode instalar:

pip install alive-progress

E use-o como:

from alive_progress import alive_bar

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

Para obter uma barra de progresso legal!

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

Isenção de responsabilidade: eu sou o autor de alive_progress, mas isso deve resolver seu problema de maneira adequada. Leia a documentação em https://github.com/rsalmei/alive-progress , aqui está um exemplo do que ele pode fazer:

vivo-progresso


8

Eu realmente gosto da python-progressbar , pois é muito simples de usar.

Para o caso mais simples, é apenas:

import progressbar
import time

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

A aparência pode ser personalizada e pode exibir o tempo restante estimado. Por exemplo, use o mesmo código acima, mas com:

progress = progressbar.ProgressBar(widgets=[progressbar.Bar('=', '[', ']'), ' ',
                                            progressbar.Percentage(), ' ',
                                            progressbar.ETA()])

5

Se for um loop grande com uma quantidade fixa de iterações que está demorando muito tempo, você pode usar esta função que eu criei. Cada iteração de loop adiciona progresso. Onde count é a iteração atual do loop, total é o valor para o qual você está fazendo loop e size (int) é o tamanho que você deseja para a barra em incrementos de 10, isto é (tamanho 1 = 10 caracteres, tamanho 2 = 20 caracteres)

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

exemplo:

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

resultado:

i = 50
>> 050/100 [==========          ]


4

O código abaixo é uma solução bastante geral e também tem um tempo decorrido e uma estimativa de tempo restante. Você pode usar qualquer iterável com ele. A barra de progresso tem um tamanho fixo de 25 caracteres, mas pode mostrar atualizações em etapas de 1% usando caracteres completos, meio e trimestre. A saída é assim:

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

Código com exemplo:

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)

Sugestões de melhorias ou outros comentários são bem-vindos. Felicidades!


3

Eu gosto desta página .

Começa com um exemplo simples e passa para uma versão multiencadeada. Trabalha fora da caixa. Não são necessários pacotes de terceiros.

O código será algo como isto:

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)

Ou aqui está um exemplo para usar threads para executar a barra de carregamento giratória enquanto o programa está sendo executado:

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

3

É bastante direto no 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

Ao executar em notebooks jupyter, o uso do tqdm normal não funciona, pois grava a saída em várias linhas. Use isto:

import time
from tqdm import tqdm_notebook as tqdm

for i in tqdm(range(100))
    time.sleep(0.5)

2

Se seu trabalho não puder ser dividido em partes mensuráveis, você poderá chamar sua função em um novo thread e tempo quanto tempo leva:

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"

Obviamente, você pode aumentar a precisão do tempo, conforme necessário.


Onde alguém faria o trabalho para ser medido no código em resposta?
Unseen_rider 15/10

2

Eu gosto da resposta do Gabriel , mas mudei para ser flexível. Você pode enviar o comprimento da barra para a função e obter a barra de progresso com o tamanho que desejar. E você não pode ter uma barra de progresso com comprimento zero ou negativo. Além disso, você pode usar esta função como a resposta do Gabriel (veja o exemplo 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)

Resultado:

Esta é uma barra de progresso simples.

Exemplo 1

Progresso: [### -------] 30%

Exemplo 2

Progresso: [|||||||||||| ........] 60%

Feito.


2

Eu usei o format()método para fazer uma barra de carga. Aqui está a minha solução:

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

Resultado:

[#######################] - 100.00%

1

Aqui está uma solução curta que cria a barra de carregamento programaticamente (você deve decidir quanto tempo deseja).

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

Experimente o PyProg. PyProg é uma biblioteca de código aberto para Python para criar barras e indicadores de progresso super personalizáveis.

Atualmente, está na versão 1.0.2; está hospedado no Github e disponível no PyPI (links abaixo). É compatível com Python 3 e 2 e também pode ser usado com o Qt Console.

É realmente fácil de usar. O código a seguir:

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

vai produzir:

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

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

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

Na verdade, eu criei o PyProg porque precisava de uma biblioteca de barras de progresso simples, mas super personalizável. Você pode facilmente instalá-lo com: pip install pyprog.

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


1

Você também pode usar o esclarecer . A principal vantagem é que você pode fazer logon ao mesmo tempo sem substituir sua barra de progresso.

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

Ele também lida com várias barras de progresso.

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

Use a biblioteca de progresso !

pip install progress

Aqui está uma subclasse personalizada que escrevi para formatar os tempos ETA / Decorridos para um formato melhor legível:

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

1

Esta é a minha solução simples:

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

0

Você deve vincular a barra de progresso à tarefa em questão (para medir o progresso: D). Por exemplo, se você estiver enviando um arquivo por FTP, você pode dizer ao ftplib para pegar um determinado tamanho de buffer, digamos 128K, e depois adicionar à sua barra de progresso qualquer porcentagem do tamanho do arquivo que 128k representa. Se você estiver usando a CLI e seu medidor de progresso tiver 20 caracteres, você adicionará um caractere quando 1/20 do arquivo for transferido.


No meu caso, estou usando uma API e ela não fornece facilidades para obter partes específicas. Obrigado pela ideia, é bom.
user225312

0

@ Massagran: Funciona bem nos meus programas. Além disso, precisamos adicionar um contador para indicar os tempos de loop. Este contador funciona como o argumento do método update. Por exemplo: leia todas as linhas de um arquivo de teste e trate-as em algo. Suponha que a função dosth()não se preocupe na variável 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()

A variável icontrola o status de pbaratravés do métodoupdate


0

uma resposta um pouco mais genérica de jelde015 (crédito para ele, é claro)

para atualizar a barra de carregamento manualmente será:

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

e chamando por:

loadingBar(7, 220, 40)

resultará:

007/220 [=                                       ]  

basta chamá-lo sempre que quiser com o ivalor atual .

defina sizecomo o número de caracteres que a barra deve ser


0

Acho que estou um pouco atrasado, mas isso deve funcionar para as pessoas que trabalham com as versões atuais do python 3 , pois ele usa "f-strings" , conforme apresentado no Python 3.6 PEP 498 :

Código

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

Exemplo

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

Resultado

Downloading: [########------------] 8/20 40.00%

0

Esta é uma maneira simples de criar uma barra de progresso

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)
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.