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.

usuario225312
fuente
¿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.

ChristopheD
fuente
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.

scls
fuente
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
Brian Khuu
fuente
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

eusoubrasileiro
fuente
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
Massagran
fuente
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
Vladislav
fuente
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

Romuald Brunet
fuente
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%
Gabriel
fuente
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.

Eyal.D
fuente
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

rsalmei
fuente
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()])
luator
fuente
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 [==========          ]
jelde015
fuente
4

Use esta biblioteca: fish( GitHub ).

Uso:

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

¡Que te diviertas!

Etienne
fuente
Es posible. Debe preguntar al desarrollador o dejar el ticket: github.com/lericson/fish .
Etienne
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!

Niko
fuente
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
usuario1862895
fuente
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')
Anton Ivanov
fuente
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)
Jacques MALAPRADE
fuente
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.

bvanvugt
fuente
¿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.

Saeed Zahedian Abroodi
fuente
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%
Matheus Tavares
fuente
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)
étale-cohomology
fuente
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/

Bill Kudo
fuente
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()
aviso
fuente
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()
kakhkAtion
fuente
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")
Hacer hacer hacer
fuente
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.

johncip
fuente
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

Tung
fuente
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

Yarden Cohen
fuente
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%
Gustavo Barros
fuente
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)
Prasaanth Selvakumar
fuente