Barra de progreso de Python


307

¿Cómo uso una barra de progreso cuando mi script está realizando alguna tarea que probablemente tome tiempo?

Por ejemplo, una función que tarda un tiempo en completarse y vuelve Truecuando termina . ¿Cómo puedo mostrar una barra de progreso durante el tiempo que se ejecuta la función?

Tenga en cuenta que necesito que esto sea en tiempo real, por lo que no puedo entender qué hacer al respecto. ¿Necesito un threadpara esto? No tengo idea.

En este momento no estoy imprimiendo nada mientras se ejecuta la función, sin embargo, una barra de progreso estaría bien. También estoy más interesado en cómo se puede hacer esto desde el punto de vista del código.


¿Está utilizando un kit de herramientas GUI o CLI solamente?
Bobby

CLI Pero puedo usar una biblioteca de terceros, eso no es problema. Con GUI puedo hacer esto, pero estaba interesado en la parte de CLI.
user225312

1
Posible duplicado de la barra de progreso de texto en la consola Tenga en cuenta que si bien esta pregunta se publicó tres días antes, la pregunta vinculada se ve con más frecuencia.
Greenstick

Aquí hay una solución para dentro de un cuaderno de Jupyter: mikulskibartosz.name/…
Steven C. Howell

¡He publicado un nuevo tipo de barra de progreso, que puedes imprimir, ver el rendimiento y el eta, incluso pausarlo, además de las animaciones geniales! Por favor, eche un vistazo: github.com/rsalmei/alive-progress ! progreso vivo
rsalmei

Respuestas:


185

Hay bibliotecas específicas ( como esta aquí ) pero quizás algo muy simple haría:

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 es una bifurcación de barra de progreso que no se ha mantenido en años.


14
esto no escala para muchos pasos ... pypi.python.org/pypi/progress es mucho más fácil de usar
m13r

55
Intenté este código y arrojó un NameError: name 'xrange' is not definederror. ¿Me estoy perdiendo un módulo?
Mushroom Man

66
@ GokuMcSpock9733 ¿Qué versión de Python estás usando? Python 2 xrangees Python 3 range.
Quapka

99
Esta no debería ser la mejor respuesta. La otra respuesta (con tqdm) es mucho mejor para mí al menos.
Florian

1
Barra de progreso de los pobres en Python 3:print('■', end='', flush=True)
PatrickT

352

Con tqdm puedes agregar un medidor de progreso a tus bucles en un 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]

Además, hay una versión gráfica de tqdm ya que 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)

ventana tqdm gui

Pero tenga cuidado, ya que tqdm_guipuede elevar un TqdmExperimentalWarning: GUI is experimental/alpha, puede ignorarlo usando warnings.simplefilter("ignore"), pero ignorará todas las advertencias en su código después de eso.


99
Esta es la única solución que encontré para trabajar con terminal, qtconsole y notebook
Ivelin

3
¿Funciona con algún iterable? He tenido problemas para que funcione con una lista de cadenas.
Josh Usre

3
@JoshUsre Sí, debería funcionar con cualquier iterable, por el momento no vi ningún iterable con el que se atragantó. Sin embargo, la visualización de la ETA (tiempo restante) requiere que el iterable tenga una __len__propiedad o el usuario debe proporcionar el totalargumento tqdm. De lo contrario, el bar funcionará pero sin ETA.
Gaborous

66
@gaborous: ¿Cómo es que esta no es la respuesta más votada? Esta solución simple funciona tanto en la terminal como en la notebook Jupyter, a diferencia de la respuesta principal.
Ébe Isaac

66
para correr en un portátil jupyter from tqdm import tqdm_notebook as tqdm. De lo contrario, no lo escribe en una línea.
Jacques MALAPRADE

81

Las sugerencias anteriores son bastante buenas, pero creo que la mayoría de la gente solo quiere una solución preparada, sin dependencias de paquetes externos, pero también es reutilizable.

Obtuve los mejores puntos de todo lo anterior, y lo convertí en una función, junto con un caso de prueba.

Para usarlo, simplemente copie las líneas debajo de "def update_progress (progreso)" pero no el script de prueba. No olvides importar sys. Llame a esto siempre que necesite mostrar o actualizar la barra de progreso.

Esto funciona enviando directamente el símbolo "\ r" a la consola para mover el cursor de regreso al inicio. "imprimir" en python no reconoce el símbolo anterior para este propósito, por lo tanto, necesitamos '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)

Esto es lo que muestra el resultado del script de prueba (La última barra de progreso anima):

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
La prueba animada (la última) debería decir in range(101)no 100, el progreso se detiene en 99% y nunca se muestra hecho.
Nick Humrich

41

Esta respuesta no se basa en paquetes externos , también creo que la mayoría de las personas solo quieren un código listo . El código a continuación se puede adaptar para satisfacer sus necesidades personalizando: símbolo de progreso de '#'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

Salida:

Computing: [################........................] 4/15
  • No requiere un segundo hilo . Algunas soluciones / paquetes anteriores requieren. Un segundo hilo puede ser un problema jupyter notebook, por ejemplo , para un .

  • Funciona con cualquier iterable , significa cualquier cosa que len()pueda usarse. A list, a dictde cualquier cosa, por ejemplo['a', 'b', 'c' ... 'g']

También puede cambiar la salida cambiando el archivo a, sys.stderrpor ejemplo


Me gusta esta solución, los generadores arrojarán el siguiente error:TypeError: object of type 'generator' has no len()
jabellcu

@jabellcu en ese caso ( generators) tienes que envolverlo con a list(). Me gustafor i in progressbar(list(your_generator), "Computing: ", 40):
eusoubrasileiro

22

para una aplicación similar (hacer un seguimiento del progreso en un bucle) simplemente usé la barra de progreso de python :

Su ejemplo es algo como esto,

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 compatibilidad con Python 3, pruebe el progressbar2paquete. El código anterior funcionará con él.
d33tah

2
¿Realmente acabas de usar import *?
Eric

20

Pruebe el progreso desde 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()

El resultado será una barra como la siguiente:

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

Solo intenté esto. MUY fácil de usar. Me tomó como 2 minutos (incluido el progreso de instalación de pip) para tener una barra de estado en funcionamiento.
perelin

progresshace buenas barras, pero falla si otro software está manipulando stderr. lo siento, pero no he investigado el problema exacto.
Arthur

Imprime una línea para cada progreso en mi consola ubuntu, por ejemplo, si max = 20, imprime 20 líneas ... ¿Cómo hago que imprima solo una línea?
L's World

19

Acabo de hacer una clase de progreso simple para mis necesidades después de buscar aquí una solución equivalente. Pensé que podría publicarlo bien.

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)

Ejemplo:

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

Imprimirá lo siguiente:

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


3
Impresionante, gracias por esto. Por cierto, puede agregar el progress.currentincremento al final __call__para limitar aún más la interacción con el objeto desde el código principal.
npit

¡Este código es simple, conciso y útil! ¡Gracias!
Ian Rehwinkel

15

Me gusta la respuesta de Brian Khuu por su simplicidad y por no necesitar paquetes externos. Lo cambié un poco, así que agrego mi versión aquí:

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)

Toma el número total de ejecuciones ( total) y el número de ejecuciones procesadas hasta ahora ( progress) suponiendo total >= progress. El resultado se ve así:

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

14

Puedes usar 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)

En este ejemplo, la barra de progreso se ejecuta durante 5 minutos y se muestra así:

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

Puede cambiarlo y personalizarlo a su gusto.


11

Para utilizar los marcos de la barra de progreso de una manera útil, es decir, para obtener un porcentaje de progreso real y una ETA estimada, debe poder declarar cuántos pasos tendrá.

Entonces, su función de cálculo en otro hilo, ¿puede dividirla en varios pasos lógicos? ¿Puedes modificar su código?

No necesita refactorizarlo o dividirlo en métodos reales, ¡simplemente podría poner algunas estrategias estratégicas yielden algunos lugares dentro de él! Si la función costosa tiene un bucle for , simplemente ponga uno en él. Solo debe saber al final cuántos rendimientos se harán, para obtener los mejores resultados.

De esa manera, su función podría ser algo como esto:

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

o esto:

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

Con ese tipo de función, puede instalar:

pip install alive-progress

Y úsalo 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 obtener una barra de progreso genial!

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

Descargo de responsabilidad: soy el autor de alive_progress, pero debería resolver su problema muy bien. Lea la documentación en https://github.com/rsalmei/alive-progress , aquí hay un ejemplo de lo que puede hacer:

progreso vivo


8

Realmente me gusta la barra de progreso de Python , ya que es muy simple de usar.

Para el caso más simple, es solo:

import progressbar
import time

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

La apariencia se puede personalizar y puede mostrar el tiempo restante estimado. Por ejemplo, use el mismo código que el anterior pero con:

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

5

Si es un gran bucle con una cantidad fija de iteraciones que está tomando mucho tiempo, puede usar esta función que hice. Cada iteración del ciclo agrega progreso. Donde count es la iteración actual del bucle, total es el valor al que está haciendo el bucle y el tamaño (int) es qué tan grande quiere la barra en incrementos de 10, es decir (tamaño 1 = 10 caracteres, tamaño 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 + ']')

ejemplo:

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

salida:

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


4

El siguiente código es una solución bastante general y también tiene un tiempo transcurrido y el tiempo restante estimado. Puede usar cualquier iterable con él. La barra de progreso tiene un tamaño fijo de 25 caracteres, pero puede mostrar actualizaciones en pasos del 1% utilizando caracteres de bloque completo, medio y cuarto. El resultado se ve así:

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

Código con ejemplo:

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)

Se agradecen las sugerencias de mejoras u otros comentarios. ¡Salud!


3

Me gusta esta página .

Comienza con un ejemplo simple y pasa a una versión multiproceso. Funciona fuera de la caja. No se requieren paquetes de terceros.

El código se verá así:

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)

O aquí hay un ejemplo para usar hilos para ejecutar la barra de carga giratoria mientras se ejecuta el programa:

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

Es bastante sencillo en 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

Cuando se ejecuta en portátiles jupyter, el uso de tqdm normal no funciona, ya que escribe la salida en varias líneas. Use esto en su lugar:

import time
from tqdm import tqdm_notebook as tqdm

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

2

Si su trabajo no se puede dividir en fragmentos medibles, puede llamar a su función en un nuevo hilo y determinar cuánto tiempo lleva:

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, puede aumentar la precisión de sincronización según sea necesario.


¿Dónde haría uno el trabajo a medir en el código en respuesta?
unseen_rider

2

Me gusta la respuesta de Gabriel , pero la cambié para que sea flexible. Puede enviar la longitud de la barra a la función y obtener su barra de progreso con la longitud que desee. Y no puede tener una barra de progreso con longitud cero o negativa. Además, puede usar esta función como respuesta de Gabriel (Mire el Ejemplo # 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 es una barra de progreso simple.

Ejemplo 1

Progreso: [### -------] 30%

Ejemplo # 2

Progreso: [|||||||||||| ........] 60%

Hecho.


2

Usé el format()método para hacer una barra de carga. Aquí está mi solución:

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

Salida:

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

1

Aquí hay una solución corta que construye la barra de carga mediante programación (debe decidir cuánto tiempo la quiere).

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

Prueba PyProg. PyProg es una biblioteca de código abierto para Python para crear indicadores y barras de progreso súper personalizables.

Actualmente se encuentra en la versión 1.0.2; está alojado en Github y está disponible en PyPI (enlaces a continuación). Es compatible con Python 3 y 2 y también se puede usar con Qt Console.

Es realmente fácil de usar. El siguiente código:

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

Producirá:

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

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

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

Realmente hice PyProg porque necesitaba una biblioteca de barra de progreso simple pero súper personalizable. Se puede instalar fácilmente con: pip install pyprog.

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


1

También puedes usar enlighten . La principal ventaja es que puede iniciar sesión al mismo tiempo sin sobrescribir su barra de progreso.

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

También maneja múltiples barras de progreso.

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

¡Usa la biblioteca de progreso !

pip install progress

Aquí hay una subclase personalizada que escribí para formatear los tiempos ETA / Transcurridos en un formato mejor legible:

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 es mi solución simple:

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

Debe vincular la barra de progreso a la tarea en cuestión (para que mida el progreso: D). Por ejemplo, si está enviando un archivo por FTP, puede decirle a ftplib que tome un búfer de cierto tamaño, digamos 128K, y luego agregue a su barra de progreso cualquier porcentaje del tamaño de archivo de 128k. Si está utilizando la CLI y su medidor de progreso tiene 20 caracteres, agregará un carácter cuando se haya transferido 1/20 del archivo.


En mi caso, estoy usando una API y no proporciona ninguna facilidad para obtener fragmentos específicos. Gracias por la idea, sin embargo, es agradable.
user225312

0

@Massagran: Funciona bien en mis programas. Además, necesitamos agregar un contador para indicar los tiempos de bucle. Este contador juega como argumento del método update. Por ejemplo: lea todas las líneas de un archivo de prueba y trátelas en algo. Suponga que la función dosth()no concierne en la variable 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()

La variable icontrola el estado a pbartravés del métodoupdate


0

una respuesta un poco más genérica de jelde015 (crédito para él, por supuesto)

para actualizar la barra de carga 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)
                     + ']')

y llamándolo por:

loadingBar(7, 220, 40)

resultará:

007/220 [=                                       ]  

solo llámalo cuando quieras con el actual i valor .

establecer sizecomo el número de caracteres que debe ser la barra


0

Supongo que llego un poco tarde, pero esto debería funcionar para las personas que trabajan con las versiones actuales de python 3 , ya que utiliza "cadenas f" , como se introdujo en 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')

Ejemplo

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

Salida

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

0

Esta es una manera simple de crear una barra de progreso

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)
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.