Y at-il un bon moyen de faire ce qui suit?
J'ai écrit une application de console simple pour télécharger et télécharger des fichiers à partir d'un serveur FTP à l'aide de ftplib.
Chaque fois que des morceaux de données sont téléchargés, je souhaite mettre à jour une barre de progression du texte, même s'il ne s'agit que d'un nombre.
Mais je ne veux pas effacer tout le texte qui a été imprimé sur la console. (Effectuer un "effacer" puis imprimer le pourcentage mis à jour.)
Voici un ensemble des nombreuses réponses ci-dessous que j'utilise régulièrement (aucune importation requise).
# Print iterations progress
def printProgressBar (iteration, total, prefix = '', suffix = '', decimals = 1, length = 100, fill = '█'):
"""
Call in a loop to create terminal progress bar
@params:
iteration - Required : current iteration (Int)
total - Required : total iterations (Int)
prefix - Optional : prefix string (Str)
suffix - Optional : suffix string (Str)
decimals - Optional : positive number of decimals in percent complete (Int)
length - Optional : character length of bar (Int)
fill - Optional : bar fill character (Str)
"""
percent = ("{0:." + str(decimals) + "f}").format(100 * (iteration / float(total)))
filledLength = int(length * iteration // total)
bar = fill * filledLength + '-' * (length - filledLength)
print('\r%s |%s| %s%% %s' % (prefix, bar, percent, suffix), end = '\r')
# Print New Line on Complete
if iteration == total:
print()
Remarque: Ceci est pour Python 3; voir les commentaires pour plus de détails sur son utilisation dans Python 2.
import time
# A List of Items
items = list(range(0, 57))
l = len(items)
# Initial call to print 0% progress
printProgressBar(0, l, prefix = 'Progress:', suffix = 'Complete', length = 50)
for i, item in enumerate(items):
# Do stuff...
time.sleep(0.1)
# Update Progress Bar
printProgressBar(i + 1, l, prefix = 'Progress:', suffix = 'Complete', length = 50)
Exemple de sortie:
Progress: |█████████████████████████████████████████████-----| 90.0% Complete
Il a été question dans les commentaires d’une option permettant à la barre de progression de s’ajuster de manière dynamique à la largeur de la fenêtre du terminal. Bien que je ne le recommande pas, voici un Gist qui implémente cette fonctionnalité (et note les mises en garde).
En écrivant '\ r', le curseur reviendra au début de la ligne.
Ceci affiche un compteur de pourcentage:
import time
import sys
for i in range(100):
time.sleep(1)
sys.stdout.write("\r%d%%" % i)
sys.stdout.flush()
tqdm: ajoute un indicateur de progression à vos boucles en une seconde :
>>> import time
>>> from tqdm import tqdm
>>> for i in tqdm(range(100)):
... time.sleep(1)
...
|###-------| 35/100 35% [elapsed: 00:35 left: 01:05, 1.00 iters/sec]
Ecrivez un \r
sur la console. C'est un "retour de chariot" qui provoque l'écho de tout le texte qui le suit au début de la ligne. Quelque chose comme:
def update_progress(progress):
print '\r[{0}] {1}%'.format('#'*(progress/10), progress)
qui vous donnera quelque chose comme: [ ########## ] 100%
C'est moins de 10 lignes de code.
The Gist ici: https://Gist.github.com/vladignatyev/06860ec2040cb497f0f
import sys
def progress(count, total, suffix=''):
bar_len = 60
filled_len = int(round(bar_len * count / float(total)))
percents = round(100.0 * count / float(total), 1)
bar = '=' * filled_len + '-' * (bar_len - filled_len)
sys.stdout.write('[%s] %s%s ...%s\r' % (bar, percents, '%', suffix))
sys.stdout.flush() # As suggested by Rom Ruben
Essayez la bibliothèque click écrite par Mozart of Python, Armin Ronacher.
$ pip install click # both 2 and 3 compatible
Pour créer une barre de progression simple:
import click
with click.progressbar(range(1000000)) as bar:
for i in bar:
pass
Voici à quoi ça ressemble:
# [###-------------------------------] 9% 00:01:14
Personnalisez au contenu de votre coeur:
import click, sys
with click.progressbar(range(100000), file=sys.stderr, show_pos=True, width=70, bar_template='(_(_)=%(bar)sD(_(_| %(info)s', fill_char='=', empty_char=' ') as bar:
for i in bar:
pass
Look personnalisé:
(_(_)===================================D(_(_| 100000/100000 00:00:02
Il y a encore plus d'options, voir le docs de l'API :
click.progressbar(iterable=None, length=None, label=None, show_eta=True, show_percent=None, show_pos=False, item_show_func=None, fill_char='#', empty_char='-', bar_template='%(label)s [%(bar)s] %(info)s', info_sep=' ', width=36, file=None, color=None)
Je me rends compte que je suis en retard pour le jeu, mais voici un scénario légèrement à la Yum (Red Hat) que je vous ai écrit (sans aller pour une précision de 100% ici, mais si vous utilisez une barre de progression pour ce niveau de précision, alors vous sommes faux de toute façon):
import sys
def cli_progress_test(end_val, bar_length=20):
for i in xrange(0, end_val):
percent = float(i) / end_val
hashes = '#' * int(round(percent * bar_length))
spaces = ' ' * (bar_length - len(hashes))
sys.stdout.write("\rPercent: [{0}] {1}%".format(hashes + spaces, int(round(percent * 100))))
sys.stdout.flush()
Devrait produire quelque chose qui ressemble à ceci:
Percent: [############## ] 69%
... où les supports restent immobiles et que seuls les hachages augmentent.
Cela pourrait mieux fonctionner en tant que décorateur. Pour un autre jour ...
Vérifiez cette bibliothèque: clint
il a beaucoup de fonctionnalités, y compris une barre de progression:
from time import sleep
from random import random
from clint.textui import progress
if __== '__main__':
for i in progress.bar(range(100)):
sleep(random() * 0.2)
for i in progress.dots(range(100)):
sleep(random() * 0.2)
this link fournit un aperçu rapide de ses fonctionnalités
Voici un bel exemple de barre de progression écrite en Python: http://nadiana.com/animated-terminal-progress-bar-in-python
Mais si vous voulez l'écrire vous-même. Vous pouvez utiliser le module curses
pour simplifier les choses :)
[edit] Peut-être que ce n'est pas plus facile, ce n'est pas la Parole pour les malédictions. Mais si vous voulez créer un cui complet, les malédictions s’occupent de beaucoup de choses pour vous.
[edit] Puisque l'ancien lien est mort, j'ai mis en place ma propre version d'un Python Progressbar, obtenez-le ici: https://github.com/WoLpH/python-progressbar =
import time,sys
for i in range(100+1):
time.sleep(0.1)
sys.stdout.write(('='*i)+(''*(100-i))+("\r [ %d"%i+"% ] "))
sys.stdout.flush()
sortie
[29%] ====================
et, juste pour ajouter à la pile, voici un objet que vous pouvez utiliser
import sys
class ProgressBar(object):
DEFAULT_BAR_LENGTH = 65
DEFAULT_CHAR_ON = '='
DEFAULT_CHAR_OFF = ' '
def __init__(self, end, start=0):
self.end = end
self.start = start
self._barLength = self.__class__.DEFAULT_BAR_LENGTH
self.setLevel(self.start)
self._plotted = False
def setLevel(self, level):
self._level = level
if level < self.start: self._level = self.start
if level > self.end: self._level = self.end
self._ratio = float(self._level - self.start) / float(self.end - self.start)
self._levelChars = int(self._ratio * self._barLength)
def plotProgress(self):
sys.stdout.write("\r %3i%% [%s%s]" %(
int(self._ratio * 100.0),
self.__class__.DEFAULT_CHAR_ON * int(self._levelChars),
self.__class__.DEFAULT_CHAR_OFF * int(self._barLength - self._levelChars),
))
sys.stdout.flush()
self._plotted = True
def setAndPlot(self, level):
oldChars = self._levelChars
self.setLevel(level)
if (not self._plotted) or (oldChars != self._levelChars):
self.plotProgress()
def __add__(self, other):
assert type(other) in [float, int], "can only add a number"
self.setAndPlot(self._level + other)
return self
def __sub__(self, other):
return self.__add__(-other)
def __iadd__(self, other):
return self.__add__(other)
def __isub__(self, other):
return self.__add__(-other)
def __del__(self):
sys.stdout.write("\n")
if __== "__main__":
import time
count = 150
print "starting things:"
pb = ProgressBar(count)
#pb.plotProgress()
for i in range(0, count):
pb += 1
#pb.setAndPlot(i + 1)
time.sleep(0.01)
del pb
print "done"
résulte en:
starting things:
100% [=================================================================]
done
Cela serait généralement considéré comme "excessif", mais il est pratique lorsque vous l'utilisez beaucoup
Installez tqdm
. (pip install tqdm
) et utilisez-le comme suit:
import time
from tqdm import tqdm
for i in tqdm(range(1000)):
time.sleep(0.01)
C'est une barre de progression de 10 secondes qui produira quelque chose comme ceci:
47%|██████████████████▊ | 470/1000 [00:04<00:05, 98.61it/s]
Exécutez ceci à la Python ligne de commande (pas dans n’importe quel IDE ou environnement de développement):
>>> import threading
>>> for i in range(50+1):
... threading._sleep(0.5)
... print "\r%3d" % i, ('='*i)+('-'*(50-i)),
Fonctionne bien sur mon système Windows.
J'utilise progrès de reddit . Je l’aime bien parce qu’il peut imprimer la progression de chaque élément d’une ligne et qu’il ne devrait pas effacer les impressions du programme.
Edit: lien fixe
Et beaucoup de tutoriels en attente d'être googlé.
sur la base des réponses ci-dessus et d’autres questions similaires sur la barre de progression de la CLI, je pense avoir obtenu une réponse commune à chacune d’elles. Vérifiez-le à https://stackoverflow.com/a/15860757/2254146
En résumé, le code est le suivant:
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()
Ressemble à
Pourcentage: [##########] 99,0%
Je recommande d'utiliser tqdm - https://pypi.python.org/pypi/tqdm - ce qui facilite la transformation de tout processus itérable ou itératif en barre de progression et gère tout le fouillis avec les terminaux nécessaires.
Dans la documentation: "tqdm peut facilement prendre en charge les callbacks/hooks et les mises à jour manuelles. Voici un exemple avec urllib"
import urllib
from tqdm import tqdm
def my_hook(t):
"""
Wraps tqdm instance. Don't forget to close() or __exit__()
the tqdm instance once you're done with it (easiest using `with` syntax).
Example
-------
>>> with tqdm(...) as t:
... reporthook = my_hook(t)
... urllib.urlretrieve(..., reporthook=reporthook)
"""
last_b = [0]
def inner(b=1, bsize=1, tsize=None):
"""
b : int, optional
Number of blocks just transferred [default: 1].
bsize : int, optional
Size of each block (in tqdm units) [default: 1].
tsize : int, optional
Total size (in tqdm units). If [default: None] remains unchanged.
"""
if tsize is not None:
t.total = tsize
t.update((b - last_b[0]) * bsize)
last_b[0] = b
return inner
eg_link = 'http://www.doc.ic.ac.uk/~cod11/matryoshka.Zip'
with tqdm(unit='B', unit_scale=True, miniters=1,
desc=eg_link.split('/')[-1]) as t: # all optional kwargs
urllib.urlretrieve(eg_link, filename='/dev/null',
reporthook=my_hook(t), data=None)
Essayez d'installer ce paquet: pip install progressbar2
:
import time
import progressbar
for i in progressbar.progressbar(range(100)):
time.sleep(0.02)
barre de progression github: https://github.com/WoLpH/python-progressbar
lol je viens d'écrire tout un truc pour cette heres le code garder à l'esprit que vous ne pouvez pas utiliser Unicode lorsque vous faites bloquer ascii j'utilise cp437
import os
import time
def load(left_side, right_side, length, time):
x = 0
y = ""
print "\r"
while x < length:
space = length - len(y)
space = " " * space
z = left + y + space + right
print "\r", z,
y += "█"
time.sleep(time)
x += 1
cls()
et vous l'appelez comme si
print "loading something awesome"
load("|", "|", 10, .01)
alors ça ressemble à ça
loading something awesome
|█████ |
Avec les bons conseils ci-dessus, je travaille sur la barre de progression.
Cependant, je voudrais souligner certaines lacunes
Chaque fois que la barre de progression est vidée, elle commence sur une nouvelle ligne.
print('\r[{0}]{1}%'.format('#' * progress* 10, progress))
comme ça:
[] 0%
[#]dix%
[##] 20%
[###] 30%
2.Le crochet ']' et le nombre pour cent sur le côté droit se décalent à droite, tandis que '###' s'allonge.
3. Une erreur se produira si l'expression 'progress/10' ne peut pas renvoyer un entier.
Et le code suivant résoudra le problème ci-dessus.
def update_progress(progress, total):
print('\r[{0:10}]{1:>2}%'.format('#' * int(progress * 10 /total), progress), end='')
import sys
def progresssbar():
for i in range(100):
time.sleep(1)
sys.stdout.write("%i\r" % i)
progressbar()
NOTE: si vous utilisez ceci dans un interpréteur interactif, vous obtenez des numéros supplémentaires imprimés
Une solution très simple consiste à mettre ce code dans votre boucle:
Mettez ceci dans le corps (c'est-à-dire en haut) de votre fichier:
import sys
Mettez ceci dans le corps de votre boucle:
sys.stdout.write("-") # prints a dash for each iteration of loop
sys.stdout.flush() # ensures bar is displayed incrementally
Réunissant certaines des idées que j'ai trouvées ici et en ajoutant le temps estimé qui reste:
import datetime, sys
start = datetime.datetime.now()
def print_progress_bar (iteration, total):
process_duration_samples = []
average_samples = 5
end = datetime.datetime.now()
process_duration = end - start
if len(process_duration_samples) == 0:
process_duration_samples = [process_duration] * average_samples
process_duration_samples = process_duration_samples[1:average_samples-1] + [process_duration]
average_process_duration = sum(process_duration_samples, datetime.timedelta()) / len(process_duration_samples)
remaining_steps = total - iteration
remaining_time_estimation = remaining_steps * average_process_duration
bars_string = int(float(iteration) / float(total) * 20.)
sys.stdout.write(
"\r[%-20s] %d%% (%s/%s) Estimated time left: %s" % (
'='*bars_string, float(iteration) / float(total) * 100,
iteration,
total,
remaining_time_estimation
)
)
sys.stdout.flush()
if iteration + 1 == total:
print
# Sample usage
for i in range(0,300):
print_progress_bar(i, 300)
Code pour la barre de progression du terminal python
import sys
import time
max_length = 5
at_length = max_length
empty = "-"
used = "%"
bar = empty * max_length
for i in range(0, max_length):
at_length -= 1
#setting empty and full spots
bar = used * i
bar = bar+empty * at_length
#\r is carriage return(sets cursor position in terminal to start of line)
#\0 character escape
sys.stdout.write("[{}]\0\r".format(bar))
sys.stdout.flush()
#do your stuff here instead of time.sleep
time.sleep(1)
sys.stdout.write("\n")
sys.stdout.flush()
Voici ma solution Python 3:
import time
for i in range(100):
time.sleep(1)
s = "{}% Complete".format(i)
print(s,end=len(s) * '\b')
'\ b' est une barre oblique inverse pour chaque caractère de votre chaîne. Cela ne fonctionne pas dans la fenêtre de commande Windows.
https://pypi.python.org/pypi/progressbar2/3.30.2
Progressbar2 est une bonne bibliothèque pour la barre de progression ascii pour la barre de progression de l'importation de la ligne de commande
bar = progressbar.ProgressBar()
for i in bar(range(100)):
time.sleep(0.02)
bar.finish()
https://pypi.python.org/pypi/tqdm
tqdm est une alternative de progressbar2 et je pense l'utiliser dans pip3 mais je ne suis pas sûr de cela
from tqdm import tqdm
for i in tqdm(range(10000)):
...
Eh bien voici le code qui fonctionne et je l’ai testé avant de poster:
import sys
def prg(prog, fillchar, emptchar):
fillt = 0
emptt = 20
if prog < 100 and prog > 0:
prog2 = prog/5
fillt = fillt + prog2
emptt = emptt - prog2
sys.stdout.write("\r[" + str(fillchar)*fillt + str(emptchar)*emptt + "]" + str(prog) + "%")
sys.stdout.flush()
Elif prog >= 100:
prog = 100
prog2 = prog/5
fillt = fillt + prog2
emptt = emptt - prog2
sys.stdout.write("\r[" + str(fillchar)*fillt + str(emptchar)*emptt + "]" + str(prog) + "%" + "\nDone!")
sys.stdout.flush()
Elif prog < 0:
prog = 0
prog2 = prog/5
fillt = fillt + prog2
emptt = emptt - prog2
sys.stdout.write("\r[" + str(fillchar)*fillt + str(emptchar)*emptt + "]" + str(prog) + "%" + "\nHalted!")
sys.stdout.flush()
Avantages:
Les inconvénients:
prog2 = prog/5
en prog2 = int(prog/5)
)fonction de Greenstick pour 2.7:
def printProgressBar (iteration, total, prefix = '', suffix = '',decimals = 1, length = 100, fill = '#'):
percent = ("{0:." + str(decimals) + "f}").format(100 * (iteration / float(total)))
filledLength = int(length * iteration // total)
bar = fill * filledLength + '-' * (length - filledLength)
print'\r%s |%s| %s%% %s' % (prefix, bar, percent, suffix),
sys.stdout.flush()
# Print New Line on Complete
if iteration == total:
print()
Pour python 3:
def progress_bar(current_value, total):
increments = 50
percentual = ((current_value/ total) * 100)
i = int(percentual // (100 / increments ))
text = "\r[{0: <{1}}] {2}%".format('=' * i, increments, percentual)
print(text, end="\n" if percentual == 100 else "")
Le module python barre de progression est un bon choix. Voici mon code typique:
import time
import progressbar
widgets = [
' ', progressbar.Percentage(),
' ', progressbar.SimpleProgress(format='(%(value_s)s of %(max_value_s)s)'),
' ', progressbar.Bar('>', fill='.'),
' ', progressbar.ETA(format_finished='- %(seconds)s -', format='ETA: %(seconds)s', ),
' - ', progressbar.DynamicMessage('loss'),
' - ', progressbar.DynamicMessage('error'),
' '
]
bar = progressbar.ProgressBar(redirect_stdout=True, widgets=widgets)
bar.start(100)
for i in range(100):
time.sleep(0.1)
bar.update(i + 1, loss=i / 100., error=i)
bar.finish()
j'ai écrit une barre de progression simple:
def bar(total, current, length=10, prefix="", filler="#", space=" ", oncomp="", border="[]", suffix=""):
if len(border) != 2:
print("parameter 'border' must include exactly 2 symbols!")
return None
print(prefix + border[0] + (filler * int(current / total * length) +
(space * (length - int(current / total * length)))) + border[1], suffix, "\r", end="")
if total == current:
if oncomp:
print(prefix + border[0] + space * int(((length - len(oncomp)) / 2)) +
oncomp + space * int(((length - len(oncomp)) / 2)) + border[1], suffix)
if not oncomp:
print(prefix + border[0] + (filler * int(current / total * length) +
(space * (length - int(current / total * length)))) + border[1], suffix)
comme vous pouvez le voir, il a: longueur de la barre, préfixe et suffixe, remplissage, espace, texte en barre sur 100% (oncomp) et bordures
voici un exemple:
from time import sleep, time
start_time = time()
for i in range(10):
pref = str((i+1) * 10) + "% "
complete_text = "done in %s sec" % str(round(time() - start_time))
sleep(1)
bar(10, i + 1, length=20, prefix=pref, oncomp=complete_text)
en cours:
30% [###### ]
out on complete:
100% [ done in 9 sec ]