una progressbar progreso print notebook hacer como barra bar python

progressbar - Barra de progreso de Python



tqdm print (21)

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

Por ejemplo, una función que tarda un tiempo en completarse y devuelve True cuando termina. ¿Cómo puedo visualizar una barra de progreso durante el tiempo que se está ejecutando la función?

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

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


@Massagran: Funciona bien en mis programas. Además, necesitamos agregar un contador para indicar los tiempos de ciclo. Este contador juega como el argumento de la update método. Por ejemplo: lea todas las líneas de un archivo de prueba y trátelas en algo. Supongamos que la función dosth() no se refiere a 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 i controla el estado de pbar través de la update método


Acabo de hacer una clase de progreso simple para mis necesidades después de buscar aquí una solución equivalente. Es difícil que pueda publicarlo.

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

Se imprimirá lo siguiente:

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


Aquí hay una solución corta que construye la barra de carga programáticamente (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)


Con tqdm , puede agregar un medidor de progreso a sus bucles en un segundo:

In [20]: import time In [21]: from tqdm import tqdm In [23]: for i in tqdm(range(10)): ....: time.sleep(3) 60%|██████ | 6/10 [00:18<00:12, 0.33 it/s]


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


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

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

Código con un ejemplo:

import sys, time from numpy import linspace def LoopWithProgressBar(iterObj, refreshTime=10): #refreshTime=10: refresh the time estimate at least every 10 sec. L = len(iterObj) startT = time.time(); endT = startT steps = {int(x):(int(y/4.0),int(y%4)) for x,y in zip(linspace(0,L-1,min(101,L)), linspace(0,100,min(101,L)))} timeStr = '' [0:00:00, -:--:--]'' # [time elapsed, time remaining] qSteps = ('''', u''/u258E'',u''/u258C'',u''/u258A'') # quarter and half block chars def SecToStr(sec): m, s = divmod(sec, 60) h, m = divmod(m, 60) return u''%d:%02d:%02d'' %(h,m,s) for nn,op in enumerate(iterObj): if nn in steps: done = u''/u2588''*(steps[nn][0])+qSteps[steps[nn][1]] todo = '' ''*(25-len(done)) barStr = ''%4d%% |%s%s|'' %((nn)/(L-1.0)*100.0, done, todo) if nn>0: barStr = ''/r''+barStr endT = time.time() timeStr = '' [%s, %s]''%(SecToStr(endT-startT), SecToStr((endT-startT)*(L/(nn+1.0)-1))) if nn == L-1: timeStr += ''/n'' sys.stdout.write((barStr+timeStr).encode(''utf-8'')); sys.stdout.flush() elif time.time()-endT > refreshTime: endT = time.time() timeStr = '' [%s, %s]''%(SecToStr(endT-startT), SecToStr((endT-startT)*(L/(nn+1.0)-1))) sys.stdout.write((''/r''+barStr+timeStr).encode(''utf-8'')); sys.stdout.flush() yield op # Example s = '''' for op in LoopWithProgressBar(list(''Disassemble and reassemble this string'')): time.sleep(0.5) s += op print s

Sugerencias de mejoras u otros comentarios son bienvenidos. Que te diviertas.


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


Hay bibliotecas específicas ( como esta aquí ) pero tal vez 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")

Nota: esta barra de progreso es una bifurcación de la barra de progressbar que no se ha mantenido en años.


Las sugerencias anteriores son bastante buenas, pero creo que la mayoría de la gente solo quiere una solución preparada, sin dependencias en 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 en "def update_progress (progress)" pero no en el script de prueba. No olvides importar sys. Llámalo cuando necesites visualizar o actualizar la barra de progreso.

Esto funciona enviando directamente el símbolo "/ r" a la consola para mover el cursor de nuevo al inicio. "print" 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(100): time.sleep(0.1) update_progress(i/100.0) print "" print "Test completed" time.sleep(10)

Esto es lo que muestra el resultado del guión de prueba (la última barra de progreso se 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: [##########] 99.0% Test completed


Me gusta esta page

Comienza con un ejemplo simple y se mueve a una versión de subprocesos múltiples. Funciona de la caja. No se requieren paquetes de terceros.

El código se verá más o menos 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 subprocesos para ejecutar la barra de carga giratoria mientras el programa se está ejecutando:

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


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

import sys import time def updt(total, progress): """ Displays or updates a console progress bar. Original source: https://.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 el momento ( progress ) asumiendo total >= progress . El resultado es así:

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


Me gusta la respuesta de Gabriel , pero la cambié para ser flexible. Puede enviar una barra de longitud 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 utilizar esta función como la respuesta de Gabriel (Mire el ejemplo n. ° 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 n. ° 2

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

Hecho.


Muchas de las respuestas anteriores se basan en paquetes externos, pero también creo (como se dijo anteriormente) que la mayoría de la gente solo quiere una solución preparada. El código de abajo se puede adaptar a sus necesidades personalizando la parte de la cadena.

Es más simple y funciona sin la necesidad de un segundo hilo para actualizar la barra. Algunos paquetes anteriores hacen eso. Un segundo hilo puede ser un problema, por ejemplo, para un cuaderno ipython.

El siguiente código solo funciona con iteradores que proporcionan una longitud (es decir, se debe definir len (iterador)).

import sys def progressbar(it, prefix="", size=60): count = len(it) def _show(_i): x = int(size*_i/count) sys.stdout.write("%s[%s%s] %i/%i/r" % (prefix, "#"*x, "."*(size-x), _i, count)) sys.stdout.flush() _show(0) for i, item in enumerate(it): yield item _show(i+1) sys.stdout.write("/n") sys.stdout.flush()

Ejemplo:

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

Salida:

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

...

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

...

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

puede ser cualquier objeto iterable con un len , por ejemplo [''a'', ''b'', ''c''] `funciona bien.


Prueba PyProg. PyProg es una biblioteca de código abierto para que Python cree 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 abajo). 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% ##################################################

De hecho, hice PyProg porque necesitaba una biblioteca de barra de progreso simple pero súper personalizable. Puedes instalarlo fácilmente con: pip install pyprog .

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


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


Realmente me gusta la python-progressbar , ya que es muy simple de usar.

Para el caso más simple, es simplemente:

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. Para un ejemplo use el mismo código que arriba pero con:

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


Si se trata de un gran bucle con una cantidad fija de iteraciones que lleva 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á pasando el bucle y el tamaño (int) es el tamaño que desea 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 [========== ]


Si su trabajo no se puede dividir en trozos medibles, podría 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.


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


Usa esta biblioteca: fish ( GitHub ).

Uso:

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

¡Que te diviertas!


para una aplicación similar (haciendo un seguimiento del progreso en un bucle) simplemente utilicé la python-progressbar :

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