Barre de progression Python

307

Comment utiliser une barre de progression lorsque mon script effectue une tâche susceptible de prendre du temps?

Par exemple, une fonction qui prend un certain temps à terminer et qui revient Truelorsqu'elle est terminée. Comment afficher une barre de progression pendant l'exécution de la fonction?

Notez que j'ai besoin que cela soit en temps réel, donc je ne sais pas quoi faire à ce sujet. Ai-je besoin d'un threadpour cela? Je n'ai aucune idée.

Pour le moment, je n'imprime rien pendant l'exécution de la fonction, mais une barre de progression serait bien. Je suis également plus intéressé par la façon dont cela peut être fait du point de vue du code.

user225312
la source
Utilisez-vous uniquement une boîte à outils GUI ou CLI?
Bobby
CLI. Mais je peux utiliser une bibliothèque tierce, ce n'est pas un problème. Avec l'interface graphique, je peux le faire, mais j'étais intéressé par la partie CLI.
user225312
1
Copie possible de la barre de progression du texte dans la console Notez que bien que cette question ait été publiée trois jours plus tôt, la question liée est plus fréquemment consultée.
Greenstick
Voici une solution pour dans un cahier Jupyter: mikulskibartosz.name/…
Steven C. Howell
J'ai publié un nouveau type de barre de progression, que vous pouvez imprimer, voir le débit et eta, même la mettre en pause, en plus des animations très cool! Veuillez jeter un œil: github.com/rsalmei/alive-progress ! alive-progress
rsalmei

Réponses:

185

Il existe des bibliothèques spécifiques ( comme celle-ci ici ) mais peut-être que quelque chose de très simple ferait l'affaire:

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

Remarque: progressbar2 est un fork de progressbar qui n'a pas été maintenu depuis des années.

ChristopheD
la source
14
cela ne s'adapte pas à de nombreuses étapes ... pypi.python.org/pypi/progress est beaucoup plus facile à utiliser
m13r
5
J'ai essayé ce code, et il a généré une NameError: name 'xrange' is not definederreur. Suis-je absent d'un module?
Mushroom Man
6
@ GokuMcSpock9733 Quelle version de Python utilisez-vous? Python 2 xrangeest Python 3 range.
quapka
9
Cela ne devrait pas être la meilleure réponse. L'autre réponse (avec tqdm) est beaucoup mieux pour moi au moins.
Florian
1
Barre de progression des pauvres en Python 3:print('■', end='', flush=True)
PatrickT
352

Avec tqdm, vous pouvez ajouter un indicateur de progression à vos boucles en une seconde:

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]

De plus, il existe une version graphique de tqdm depuis 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)

fenêtre tqdm gui

Mais soyez prudent, car tqdm_guipeut déclencher un TqdmExperimentalWarning: GUI is experimental/alpha, vous pouvez l'ignorer en utilisant warnings.simplefilter("ignore"), mais il ignorera tous les avertissements dans votre code après cela.

scls
la source
9
C'est la seule solution que j'ai trouvée pour travailler avec un terminal, une qtconsole et un ordinateur portable
Ivelin
3
Fonctionne-t-il avec un itérable? J'ai eu du mal à le faire fonctionner avec une liste de chaînes.
Josh Usre
3
@JoshUsre Oui, cela devrait fonctionner avec n'importe quel itérable, pour le moment je n'ai vu aucun itérable sur lequel il s'étoufferait. Cependant, l'affichage de l'ETA (temps restant) nécessite que l'itérable ait une __len__propriété ou l'utilisateur doit fournir l' totalargument à tqdm. Sinon, la barre fonctionnera mais sans ETA.
génial
6
@gaborous: Comment se fait-il que ce ne soit pas la réponse la plus votée? Cette solution simple fonctionne à la fois dans le terminal et dans le bloc-notes Jupyter contrairement à la réponse principale.
Ébe Isaac
6
pour fonctionner dans un ordinateur portable jupyter from tqdm import tqdm_notebook as tqdm. Sinon, ne l'écrit pas sur une seule ligne.
Jacques MALAPRADE
81

Les suggestions ci-dessus sont assez bonnes, mais je pense que la plupart des gens veulent juste une solution prête à l'emploi, sans dépendances sur les packages externes, mais est également réutilisable.

J'ai obtenu les meilleurs points de tout ce qui précède, et en ai fait une fonction, avec des cas de test.

Pour l'utiliser, copiez simplement les lignes sous "def update_progress (progress)" mais pas le script de test. N'oubliez pas d'importer sys. Appelez cela chaque fois que vous devez afficher ou mettre à jour la barre de progression.

Cela fonctionne en envoyant directement le symbole "\ r" à la console pour ramener le curseur au début. "print" en python ne recongise pas le symbole ci-dessus à cet effet, donc nous avons besoin 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)

Voici ce que montre le résultat du script de test (la dernière barre de progression s'anime):

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
la source
10
Le test animé (le dernier) devrait dire in range(101)non 100, la progression s'arrête à 99% et ne s'affiche jamais.
Nick Humrich
41

Cette réponse ne repose pas sur des packages externes , je pense également que la plupart des gens veulent juste un morceau de code prêt à l'emploi . Le code ci-dessous peut être adapté à vos besoins en personnalisant: symbole de progression de la '#'barre size, barre , texte 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()

Usage:

import time

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

Production:

Computing: [################........................] 4/15
  • Ne nécessite pas de deuxième thread . Certaines solutions / packages ci-dessus nécessitent. Un deuxième thread peut être un problème jupyter notebook, par exemple pour a.

  • Fonctionne avec tout itérable, cela signifie tout ce qui len()peut être utilisé. A list, un dictde n'importe quoi par exemple['a', 'b', 'c' ... 'g']

Vous pouvez également modifier la sortie en changeant le fichier sys.stderrpar exemple

eusoubrasileiro
la source
J'aime cette solution, les générateurs TypeError: object of type 'generator' has no len()
lèveront l'
@jabellcu dans ce cas ( generators) vous devez l'envelopper avec un list(). J'aimefor i in progressbar(list(your_generator), "Computing: ", 40):
eusoubrasileiro
22

pour une application similaire (en gardant une trace de la progression dans une boucle) j'ai simplement utilisé la barre de progression python :

Leur exemple va quelque chose comme ça,

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
la source
3
Pour la compatibilité avec Python 3, essayez le progressbar2package. Le code ci-dessus fonctionnera avec lui.
d33tah
2
Avez-vous vraiment utilisé import *?
Eric
20

Essayez la progression depuis 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()

Le résultat sera une barre comme celle-ci:

Processing |#############                   | 42/100
Vladislav
la source
Je viens d'essayer ça. TRÈS facile à utiliser. Cela m'a pris environ 2 minutes (y compris la progression de l'installation de pip) pour avoir une barre d'état opérationnelle.
perelin
progressfait de belles barres, mais il échoue si d'autres logiciels manipulent stderr. désolé, mais je n'ai pas enquêté sur le problème exact.
Arthur
Il imprime une ligne pour chaque progression dans ma console ubuntu, par exemple, si max = 20, il imprime 20 lignes ... Comment faire pour qu'il imprime une seule ligne?
L's World
19

Je viens de créer une classe de progression simple pour mes besoins après avoir recherché ici une solution équivalente. J'ai pensé que je pourrais bien le poster.

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)

Exemple :

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

Imprime ce qui suit:

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

Romuald Brunet
la source
3
Génial, merci pour ça. BTW, vous pouvez ajouter l' progress.currentincrémentation à la fin de __call__pour limiter encore plus l'interaction avec l'objet du code principal.
npit
Ce code est simple, concis et utile! Je vous remercie!
Ian Rehwinkel
15

J'aime la réponse de Brian Khuu pour sa simplicité et ne pas avoir besoin de packages externes. Je l'ai un peu changé donc j'ajoute ma version ici:

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)

Cela prend le nombre total de runs ( total) et le nombre de runs traités jusqu'à présent ( progress) en supposant total >= progress. Le résultat ressemble à ceci:

[#####---------------] 27%
Gabriel
la source
14

Vous pouvez utiliser 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)

Dans cet exemple, la barre de progression s'exécute pendant 5 minutes et elle s'affiche comme suit:

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

Vous pouvez le modifier et le personnaliser à votre guise.

Eyal.D
la source
11

Pour utiliser n'importe quel cadre de barre de progression de manière utile, c'est-à-dire pour obtenir un pourcentage de progression réel et un ETA estimé, vous devez être en mesure de déclarer le nombre d'étapes qu'il aura.

Donc, votre fonction de calcul dans un autre thread, pouvez-vous la diviser en plusieurs étapes logiques? Pouvez-vous modifier son code?

Vous n'avez pas besoin de le refactoriser ou de le diviser en méthodes réelles, vous pouvez simplement mettre des stratégies yieldà certains endroits à l'intérieur! Si la fonction coûteuse a une boucle for , il suffit d'en mettre une. Vous ne devez savoir qu'à la fin combien de rendements seront réalisés, pour obtenir les meilleurs résultats.

De cette façon, votre fonction pourrait ressembler à ceci:

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

ou ca:

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

Avec ce genre de fonction, vous pouvez installer:

pip install alive-progress

Et utilisez-le comme:

from alive_progress import alive_bar

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

Pour obtenir une barre de progression sympa!

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

Avertissement: je suis l'auteur de alive_progress, mais cela devrait bien résoudre votre problème. Lisez la documentation sur https://github.com/rsalmei/alive-progress , voici un exemple de ce qu'il peut faire:

progrès-vivant

rsalmei
la source
8

J'aime vraiment la barre de progression python , car elle est très simple à utiliser.

Pour le cas le plus simple, c'est juste:

import progressbar
import time

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

L'aspect peut être personnalisé et il peut afficher le temps restant estimé. Pour un exemple, utilisez le même code que ci-dessus mais avec:

progress = progressbar.ProgressBar(widgets=[progressbar.Bar('=', '[', ']'), ' ',
                                            progressbar.Percentage(), ' ',
                                            progressbar.ETA()])
luator
la source
5

Si c'est une grosse boucle avec un nombre fixe d'itérations qui prend beaucoup de temps, vous pouvez utiliser cette fonction que j'ai faite. Chaque itération de boucle ajoute de la progression. Où count est l'itération actuelle de la boucle, total est la valeur vers laquelle vous bouclez et la taille (int) est la taille que vous voulez pour la barre par incréments de 10, c'est-à-dire (taille 1 = 10 caractères, taille 2 = 20 caractères)

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

exemple:

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

production:

i = 50
>> 050/100 [==========          ]
jelde015
la source
4

Utilisez cette bibliothèque: fish( GitHub ).

Usage:

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

S'amuser!

Etienne
la source
C'est possible. Vous devriez demander au développeur ou laisser un ticket: github.com/lericson/fish .
Etienne
4

Le code ci-dessous est une solution assez générale et a également une estimation du temps écoulé et du temps restant. Vous pouvez utiliser n'importe quel itérable avec lui. La barre de progression a une taille fixe de 25 caractères, mais elle peut afficher les mises à jour par étapes de 1% en utilisant des caractères de bloc complet, demi et quart de bloc. La sortie ressemble à ceci:

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

Code avec exemple:

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)

Des suggestions d'amélioration ou d'autres commentaires sont appréciés. À votre santé!

Niko
la source
3

J'aime cette page .

Commence par un exemple simple et passe à une version multi-thread. Fonctionne hors de la boîte. Aucun forfait tiers n'est requis.

Le code ressemblera à ceci:

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 voici un exemple d'utilisation de threads afin d'exécuter la barre de chargement en rotation pendant l'exécution du programme:

import sys
import time
import threading

class progress_bar_loading(threading.Thread):

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

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

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


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

try:
    #anything you want to run. 
    time.sleep(1)
    stop = True
except KeyboardInterrupt or EOFError:
         kill = True
         stop = True
user1862895
la source
3

C'est assez simple 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
la source
3

Lors de l'exécution dans des blocs-notes jupyter, l'utilisation de tqdm normal ne fonctionne pas, car il écrit la sortie sur plusieurs lignes. Utilisez-le à la place:

import time
from tqdm import tqdm_notebook as tqdm

for i in tqdm(range(100))
    time.sleep(0.5)
Jacques MALAPRADE
la source
2

Si votre travail ne peut pas être décomposé en morceaux mesurables, vous pouvez appeler votre fonction dans un nouveau thread et chronométrer combien de temps cela prend:

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"

Vous pouvez évidemment augmenter la précision de synchronisation au besoin.

bvanvugt
la source
Où ferait-on le travail à mesurer dans le code en réponse?
unseen_rider
2

J'aime la réponse de Gabriel , mais je l'ai changé pour être flexible. Vous pouvez envoyer une longueur de barre à la fonction et obtenir votre barre de progression avec la longueur que vous souhaitez. Et vous ne pouvez pas avoir de barre de progression avec une longueur nulle ou négative. En outre, vous pouvez utiliser cette fonction comme la réponse de Gabriel (regardez l'exemple # 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)

Résultat:

Il s'agit d'une simple barre de progression.

Exemple 1

Progression: [### -------] 30%

Exemple # 2

Progrès: [|||||||||||| ........] 60%

Terminé.

Saeed Zahedian Abroodi
la source
2

J'ai utilisé la format()méthode pour créer une barre de charge. Voici ma solution:

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

Production:

[#######################] - 100.00%
Matheus Tavares
la source
1

Voici une courte solution qui construit la barre de chargement par programme (vous devez décider combien de temps vous le souhaitez).

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-cohomologie
la source
1

Essayez PyProg. PyProg est une bibliothèque open-source pour Python pour créer des indicateurs de progression et des barres super personnalisables.

Il est actuellement à la version 1.0.2; il est hébergé sur Github et disponible sur PyPI (liens ci-dessous). Il est compatible avec Python 3 & 2 et peut également être utilisé avec Qt Console.

C'est vraiment simple à utiliser. Le code suivant:

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

produira:

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

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

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

J'ai fait PyProg parce que j'avais besoin d'une bibliothèque de barre de progression simple mais super personnalisable. Vous pouvez facilement l' installer avec: pip install pyprog.

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

Bill Kudo
la source
1

Vous pouvez également utiliser enlighten . Le principal avantage est que vous pouvez vous connecter en même temps sans écraser votre barre de progression.

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

Il gère également plusieurs barres de progression.

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
la source
1

Utilisez la bibliothèque de progression !

pip install progress

Voici une sous-classe personnalisée que j'ai écrite pour formater les temps ETA / Elapsed dans un format mieux lisible:

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
la source
1

Voici ma solution 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")
dododo
la source
0

Vous devez lier la barre de progression à la tâche en cours (afin qu'elle mesure la progression: D). Par exemple, si vous transférez un fichier par FTP, vous pouvez dire à ftplib de récupérer une certaine taille de tampon, disons 128 Ko, puis vous ajoutez à votre barre de progression le pourcentage de la taille de fichier que 128 Ko représente. Si vous utilisez l'interface CLI et que votre indicateur de progression comporte 20 caractères, vous ajouterez un caractère lorsque 1 / 20e du fichier aura été transféré.

johncip
la source
Dans mon cas, j'utilise une API et elle ne fournit aucune facilité pour obtenir des morceaux spécifiques. Merci pour l'idée, c'est sympa.
user225312
0

@Massagran: Cela fonctionne bien dans mes programmes. De plus, nous devons ajouter un compteur pour indiquer les temps de boucle. Ce compteur joue comme argument de la méthode update. Par exemple: lisez toutes les lignes d'un fichier de test et traitez-les sur quelque chose. Supposons que la fonction dosth()ne concerne pas 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 icontrôle l'état de pbarvia la méthodeupdate

Tung
la source
0

une réponse un peu plus générique de jelde015 (crédit à lui bien sûr)

pour mettre à jour la barre de chargement manuellement sera:

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

et en l'appelant par:

loadingBar(7, 220, 40)

résultera:

007/220 [=                                       ]  

il suffit de l'appeler à tout moment avec la ivaleur actuelle .

définir le sizenombre de caractères que la barre doit être

Yarden Cohen
la source
0

Je suppose que je suis un peu en retard, mais cela devrait fonctionner pour les personnes travaillant avec les versions actuelles de python 3 , car cela utilise des "f-strings" , comme introduit dans Python 3.6 PEP 498 :

Code

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

Exemple

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

Production

Downloading: [########------------] 8/20 40.00%
Gustavo Barros
la source
0

C'est un moyen simple de créer une barre de progression

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
la source