Textfortschrittsleiste in der Konsole [geschlossen]

435

Ich habe eine einfache Konsolen-App zum Hoch- und Herunterladen von Dateien von einem FTP-Server mithilfe der ftplib geschrieben.

Ich möchte, dass die App dem Benutzer eine Visualisierung des Download- / Upload-Fortschritts anzeigt. Jedes Mal, wenn ein Datenblock heruntergeladen wird, möchte ich, dass er eine Fortschrittsaktualisierung bereitstellt, auch wenn es sich nur um eine numerische Darstellung wie einen Prozentsatz handelt.

Wichtig ist, dass ich vermeiden möchte, den gesamten Text zu löschen, der in den vorherigen Zeilen auf der Konsole gedruckt wurde (dh ich möchte nicht das gesamte Terminal "löschen", während der aktualisierte Fortschritt gedruckt wird).

Dies scheint eine ziemlich häufige Aufgabe zu sein. Wie kann ich einen Fortschrittsbalken oder eine ähnliche Visualisierung erstellen, die auf meiner Konsole ausgegeben wird, während die vorherige Programmausgabe beibehalten wird?

bobber205
quelle
Hmm, sehen Sie aus wie ein Duplikat dieser Frage, die gestern gestellt wurde: stackoverflow.com/questions/3160699/python-progress-bar/3162864 Sie sollten also fish pypi.python.org/pypi/fish
Etienne
29
"Verwenden Sie einfach eine GUI" missversteht, dass GUIs in einigen Situationen großartig sind (schnelle Lernkurve, Ad-hoc-Erkundung oder interaktive oder einmalige Aktivitäten), während Befehlszeilentools für andere großartig sind (erfahrene Benutzer, die Ad-hoc-Anwendungen erstellen) die Fliege, um eine sorgfältig definierte Operation viele Male durchzuführen.)
Jonathan Hartley
14
Ich habe für die Wiedereröffnung gestimmt. Die Frage erscheint mir nicht zu weit gefasst.
Franck Dernoncourt
Ich denke, was Sie suchen, ist tqdm ... obwohl ich auch nicht weiß, warum SO mich dazu veranlasst, die Wiedereröffnungsabstimmungen zu jahrelangen Fragen zu überprüfen.
Kungphu
Ich habe eine neue Art von Fortschrittsbalken veröffentlicht, die Sie drucken, Durchsatz und Eta anzeigen und sogar pausieren können, abgesehen von den sehr coolen Animationen! Bitte werfen Sie einen Blick darauf: github.com/rsalmei/alive-progress ! lebendiger Fortschritt
rsalmei

Antworten:

464

Eine einfache, anpassbare Fortschrittsanzeige

Hier ist eine Zusammenfassung vieler der folgenden Antworten, die ich regelmäßig verwende (keine Importe erforderlich).

# Print iterations progress
def printProgressBar (iteration, total, prefix = '', suffix = '', decimals = 1, length = 100, fill = '█', printEnd = "\r"):
    """
    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)
        printEnd    - Optional  : end character (e.g. "\r", "\r\n") (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 = printEnd)
    # Print New Line on Complete
    if iteration == total: 
        print()

Hinweis: Dies ist für Python 3; Weitere Informationen zur Verwendung in Python 2 finden Sie in den Kommentaren.

Beispielnutzung

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)

Beispielausgabe:

Progress: |█████████████████████████████████████████████-----| 90.0% Complete

Aktualisieren

In den Kommentaren wurde eine Option diskutiert, mit der der Fortschrittsbalken dynamisch an die Breite des Terminalfensters angepasst werden kann. Obwohl ich dies nicht empfehle, ist hier ein Kern , der diese Funktion implementiert (und die Vorbehalte beachtet ).

Greenstick
quelle
21
Dieses Snippet funktioniert großartig! Ich bin auf ein paar kleinere Probleme gestoßen, also habe ich einige kleinere Änderungen vorgenommen (PEP-8, Standardcodierung für Nicht-ASCII-Zeichen) und sie hier zusammengefasst: gist.github.com/aubricus/f91fb55dc6ba5557fbab06119420dd6a
Aubricus
3
Beachten Sie, dass die UTF-8-Deklaration nur erforderlich ist, wenn Sie Python 2 @Aubricus
Greenstick
2
@MattClimbs Dies ist für Python 3 geschrieben, das standardmäßig die UTF-8-Codierung verwendet. Sie können entweder den Standardfüllparameter der Funktion ändern, bei dem es sich um ein UTF-8-Zeichen handelt, oder die UTF-8-Deklaration verwenden. Im Kern des obigen Kommentars finden Sie ein Beispiel dafür, wie eine UTF-8-Deklaration aussehen sollte.
Greenstick
1
Vielen Dank, schöne Zusammenfassung, auch die Erkennung der Terminalgröße könnte nützlich sein, da diese Funktion # Size of terminal rows, columns = [int(x) for x in os.popen('stty size', 'r').read().split()] columnsan die Länge übergeben werden sollte, um die Größe des Fortschrittsbalkens an das Terminalfenster anzupassen. Obwohl die Länge des fortschreitenden Teils des Balkens verringert werden sollte (nach Länge des Präfixes, des Suffix, des '\r%s |%s| %s%% %s'
Prozentsatzes
2
Um dies in einigen IDEs an der Arbeit (zB PyCharm unter Windows) können Sie ändern müssen end = '\r'zu end = ''.
Thomas88wp
312

Wenn Sie '\ r' schreiben, bewegt sich der Cursor zurück zum Zeilenanfang.

Dies zeigt einen Prozentzähler an:

import time
import sys

for i in range(100):
    time.sleep(1)
    sys.stdout.write("\r%d%%" % i)
    sys.stdout.flush()
Stephen
quelle
3
Klebte das ein und rannte. Es wird jedes Mal in eine neue Zeile gedruckt. Ich möchte, dass die Nummer in derselben Zeile aktualisiert wird. :)
Bobber205
8
Dieses Beispiel erzeugt auch ein OBOB, das am99%
Glenn Dayton,
10
@ Moose Es steht für "Off by One Bug"
Glenn Dayton
3
printhat ein endArgument: stackoverflow.com/a/8436827/1959808
Ioannis Filippidis
3
Um zu dem hinzuzufügen, was @IoannisFilippidis gesagt hat, printhat auch ein flushArgument: docs.python.org/3/library/functions.html#print
Wso
113

Schreiben Sie eine \ran die Konsole. Dies ist ein "Wagenrücklauf", bei dem der gesamte nachfolgende Text am Zeilenanfang wiedergegeben wird. Etwas wie:

def update_progress(progress):
    print '\r[{0}] {1}%'.format('#'*(progress/10), progress)

das gibt dir so etwas wie: [ ########## ] 100%

aviraldg
quelle
19
Mach \rund schreibe dann die ganze Zeile noch einmal aus. Grundsätzlich: print("\rProgress: [{0:50s}] {1:.1f}%".format('#' * int(amtDone * 50), amtDone * 100))Wo amtDoneist ein Float zwischen 0 und 1.
Mike DeSimone
13
Besser zu bedienen sys.stdout.writeals print. Mit habe printich Zeilenumbrüche.
Gill Bates
14
füge mir ,am Ende der printArbeiten ein Komma hinzu .
Chunliang Lyu
10
in python3 benutze print (...., end = '') und du wirst keine newlines haben
greywolf
7
Zusammenfassend für Python3 frühere Beiträge : print("\rProgress: [{0:50s}] {1:.1f}%".format('#' * int(workdone * 50), workdone*100), end="", flush=True), wo workdoneist ein Float zwischen 0 und 1, zBworkdone = parsed_dirs/total_dirs
khyox
70

Es sind weniger als 10 Codezeilen.

Das Wesentliche hier: https://gist.github.com/vladignatyev/06860ec2040cb497f0f3

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

Geben Sie hier die Bildbeschreibung ein

Vladimir Ignatyev
quelle
2
fügt am Ende der Funktion "sys.stdout.flush ()" hinzu.
Romruben
für mich geht es in einer neuen Zeile
GM
@ GM welches Betriebssystem / welche Plattform benutzt du?
Vladimir Ignatyev
Ich weiß nicht, warum es nicht funktioniert, wenn ich es von spyder ide aus starte, aber wenn ich es von der ipython-Konsole aus starte, funktioniert es!
GM
62

Probieren Sie die Klickbibliothek von Mozart of Python, Armin Ronacher.

$ pip install click # both 2 and 3 compatible

So erstellen Sie einen einfachen Fortschrittsbalken:

import click

with click.progressbar(range(1000000)) as bar:
    for i in bar:
        pass 

So sieht es aus:

# [###-------------------------------]    9%  00:01:14

Passen Sie nach Herzenslust an:

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

Benutzerdefinierter Look:

(_(_)===================================D(_(_| 100000/100000 00:00:02

Es gibt noch mehr Optionen, siehe API-Dokumente :

 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)
Die Unfun Cat
quelle
33

Mir ist klar, dass ich zu spät zum Spiel komme, aber hier ist ein leicht Yum-artiger (Red Hat), den ich geschrieben habe (hier wird keine 100% ige Genauigkeit angestrebt, aber wenn Sie einen Fortschrittsbalken für diese Genauigkeitsstufe verwenden, dann Sie sind sowieso FALSCH):

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

Sollte so etwas hervorbringen:

Percent: [##############      ] 69%

... wo die Klammern stehen bleiben und nur die Hashes zunehmen.

Dies könnte als Dekorateur besser funktionieren. Für einen anderen Tag...

JoeLinux
quelle
2
Tolle Lösung! Funktioniert perfekt! Vielen Dank!
Vasilije Bursac
18

Überprüfen Sie diese Bibliothek: clint

Es hat viele Funktionen, einschließlich eines Fortschrittsbalkens:

from time import sleep  
from random import random  
from clint.textui import progress  
if __name__ == '__main__':
    for i in progress.bar(range(100)):
        sleep(random() * 0.2)

    for i in progress.dots(range(100)):
        sleep(random() * 0.2)

Dieser Link bietet einen schnellen Überblick über die Funktionen

Skripte
quelle
12

Hier ist ein schönes Beispiel für einen in Python geschriebenen Fortschrittsbalken: http://nadiana.com/animated-terminal-progress-bar-in-python

Aber wenn du es selbst schreiben willst. Sie könnten das cursesModul verwenden, um die Dinge einfacher zu machen :)

[Bearbeiten] Vielleicht einfacher ist nicht das Wort für Flüche. Aber wenn Sie ein ausgewachsenes Cui kreieren möchten, dann kümmern sich Flüche um eine Menge Dinge für Sie.

[Bearbeiten] Da der alte Link tot ist, habe ich meine eigene Version einer Python-Fortschrittsleiste erstellt. Diese finden Sie hier: https://github.com/WoLpH/python-progressbar

Wolph
quelle
14
curses? Einfacher? Hmmm ....
aviraldg
Ein ausgezeichneter Artikel, ich wollte einen Link dazu geben, konnte ihn aber nicht in meinen Lesezeichen finden :)
Andy Mikhaylenko
@ Viral Dasgupta: Fair genug, einfacher könnte hier nicht das richtige Wort sein. Es kann Ihnen zwar viel Arbeit ersparen, aber es hängt wirklich davon ab, wonach Sie suchen.
Wolph
Ich suche nichts in der Nähe, aber trotzdem danke. :)
Bobber205
2
Toter Link, das ist der Preis, wenn Sie den verlinkten Inhalt nicht in Ihrer Antwort veröffentlichen -__-
ThorSummoner
11
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()

Ausgabe

[29%] ===================

ashish2py
quelle
7

Und um den Stapel zu erweitern, hier ist ein Objekt, das Sie verwenden können

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 __name__ == "__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"

Ergebnisse in:

starting things:
  100% [=================================================================]
done

Dies wird am häufigsten als "übertrieben" angesehen, ist jedoch praktisch, wenn Sie es häufig verwenden

FraggaMuffin
quelle
Danke dafür. Kleine Korrektur, die plotProgress-Methode sollte die Zeile sys.stdout.flush () verwenden, da sonst der Fortschrittsbalken möglicherweise erst nach Abschluss der Aufgabe gezeichnet wird (wie im Mac-Terminal).
Osnoz
Ich liebe es!!! Ziemlich einfach zu bedienen !!! Thankyou
Microos
7

Installieren Sie tqdm. ( pip install tqdm) Und verwenden Sie es wie folgt:

import time
from tqdm import tqdm
for i in tqdm(range(1000)):
    time.sleep(0.01)

Das ist ein 10-Sekunden-Fortschrittsbalken, der ungefähr Folgendes ausgibt:

47%|██████████████████▊                     | 470/1000 [00:04<00:05, 98.61it/s]
Smoking
quelle
6

Führen Sie dies in der Python-Befehlszeile aus ( nicht in einer IDE oder Entwicklungsumgebung):

>>> import threading
>>> for i in range(50+1):
...   threading._sleep(0.5)
...   print "\r%3d" % i, ('='*i)+('-'*(50-i)),

Funktioniert gut auf meinem Windows-System.

PaulMcG
quelle
4

Ich benutze den Fortschritt von reddit . Ich mag es, weil es den Fortschritt für jedes Element in einer Zeile drucken kann und Ausdrucke nicht aus dem Programm löschen sollte.

Bearbeiten: fester Link

Ib33X
quelle
1
Ihr Link ist defekt - die eigentliche Zeile im Quellcode ist 1274., nicht die 1124.! Der richtige Link ist also dieser: github.com/reddit/reddit/blob/master/r2/r2/lib/utils/…
Vladimir Ignatyev
Diese Variante hat das beste Design für meinen Geschmack: Sie verwendet Iteratoren und funktioniert möglicherweise mit jeder Art von messbarer Arbeit. Sie zeigt die verstrichene Zeit.
Vladimir Ignatyev
3

Aufgrund der obigen Antworten und anderer ähnlicher Fragen zum CLI-Fortschrittsbalken habe ich eine allgemeine Antwort auf alle Fragen erhalten. Überprüfen Sie es bei https://stackoverflow.com/a/15860757/2254146

Zusammenfassend lautet der Code wie folgt:

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

Sieht aus wie

Prozent: [##########] 99,0%

Brian Khuu
quelle
3

Ich empfehle die Verwendung von tqdm - https://pypi.python.org/pypi/tqdm - was es einfach macht, iterierbare Elemente oder Prozesse in einen Fortschrittsbalken umzuwandeln und alle Probleme mit den benötigten Terminals zu lösen.

Aus der Dokumentation: "tqdm kann problemlos Rückrufe / Hooks und manuelle Updates unterstützen. Hier ein Beispiel mit 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)
Malcolm Box
quelle
3

Versuchen Sie, dieses Paket zu installieren: pip install progressbar2:

import time
import progressbar

for i in progressbar.progressbar(range(100)):
    time.sleep(0.02)

progresssbar github: https://github.com/WoLpH/python-progressbar

Chris Cui
quelle
3

Eine sehr einfache Lösung besteht darin, diesen Code in Ihre Schleife einzufügen:

Fügen Sie dies in den Text (dh oben) Ihrer Datei ein:

import sys

Fügen Sie dies in den Körper Ihrer Schleife ein:

sys.stdout.write("-") # prints a dash for each iteration of loop
sys.stdout.flush() # ensures bar is displayed incrementally
Richard Hayman-Joyce
quelle
2
import sys
def progresssbar():
         for i in range(100):
            time.sleep(1)
            sys.stdout.write("%i\r" % i)

progressbar()

HINWEIS: Wenn Sie dies in einem interaktiven Interepter ausführen, werden zusätzliche Nummern ausgedruckt

Ramchandra Apte
quelle
2

lol ich habe gerade eine ganze Sache geschrieben, hier ist der Code. Denken Sie daran, dass Sie keinen Unicode verwenden können, wenn Sie Block ASCII ausführen. Ich verwende 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()

und du nennst es so

print "loading something awesome"
load("|", "|", 10, .01)

so sieht es also aus

loading something awesome
|█████     |
Ryan
quelle
2

Mit den oben genannten tollen Ratschlägen arbeite ich den Fortschrittsbalken aus.

Ich möchte jedoch auf einige Mängel hinweisen

  1. Jedes Mal, wenn der Fortschrittsbalken geleert wird, beginnt er in einer neuen Zeile

    print('\r[{0}]{1}%'.format('#' * progress* 10, progress))  

    wie folgt :
    [] 0%
    [#] 10
    %
    [##] 20% [###] 30%

2.Die eckige Klammer ']' und die Prozentzahl auf der rechten Seite verschieben sich nach rechts, wenn die '###' länger wird.
3. Ein Fehler tritt auf, wenn der Ausdruck 'progress / 10' keine Ganzzahl zurückgeben kann.

Der folgende Code behebt das oben genannte Problem.

def update_progress(progress, total):  
    print('\r[{0:10}]{1:>2}%'.format('#' * int(progress * 10 /total), progress), end='')
Sturmaugen
quelle
1

Code für den Fortschrittsbalken des Python-Terminals

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()
emd_22
quelle
1

Ich habe einen einfachen Fortschrittsbalken geschrieben:

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)

Wie Sie sehen können, hat es: Länge der Leiste, Präfix und Suffix, Füllzeichen, Leerzeichen, Text in der Leiste zu 100% (oncomp) und Ränder

hier ein Beispiel:

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)

out in progress:

30% [######              ]

out on complete:

100% [   done in 9 sec   ] 
Jenkins
quelle
1

Stellen Sie einige der Ideen zusammen, die ich hier gefunden habe, und fügen Sie die geschätzte verbleibende Zeit hinzu:

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)
Ivan Chaer
quelle
1

Für 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 "")
Rodrigo López
quelle
0

Nun, hier ist Code, der funktioniert und ich habe ihn vor dem Posten getestet:

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

Vorteile:

  • 20 Zeichenleiste (1 Zeichen pro 5 (zahlenmäßig))
  • Benutzerdefinierte Füllzeichen
  • Benutzerdefinierte leere Zeichen
  • Halt (beliebige Zahl unter 0)
  • Fertig (100 und eine beliebige Zahl über 100)
  • Fortschrittszahl (0-100 (unten und oben für Sonderfunktionen))
  • Prozentzahl neben dem Balken, und es ist eine einzelne Zeile

Nachteile:

  • Unterstützt nur Ganzzahlen (Es kann jedoch geändert werden, um sie zu unterstützen, indem die Division zu einer Ganzzahldivision gemacht wird. Wechseln Sie also einfach prog2 = prog/5zu prog2 = int(prog/5))
Kalter Diamondz
quelle
0

Hier ist meine Python 3-Lösung:

import time
for i in range(100):
    time.sleep(1)
    s = "{}% Complete".format(i)
    print(s,end=len(s) * '\b')

'\ b' ist ein Backslash für jedes Zeichen in Ihrer Zeichenfolge. Dies funktioniert nicht im Windows-Cmd-Fenster.

Matt-the-Bat
quelle
0

Funktion von Greenstick für 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()
Edmond de Martimprey
quelle
0

Die Fortschrittsanzeige des Python-Moduls ist eine gute Wahl. Hier ist mein typischer Code:

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()
Aimin Huang
quelle