Pasek postępu tekstu w konsoli [zamknięte]

435

Napisałem prostą aplikację konsolową do przesyłania i pobierania plików z serwera FTP za pomocą ftplib.

Chciałbym, aby aplikacja wyświetlała użytkownikowi wizualizację postępu pobierania / wysyłania; za każdym razem, gdy pobierany jest fragment danych, chciałbym, aby zapewniał on aktualizację postępu, nawet jeśli jest to tylko reprezentacja liczbowa jak procent.

Co ważne, chcę uniknąć kasowania całego tekstu, który został wydrukowany na konsoli w poprzednich liniach (tj. Nie chcę „wyczyścić” całego terminalu podczas drukowania zaktualizowanego postępu).

Wydaje się to dość powszechnym zadaniem - jak mogę zrobić pasek postępu lub podobną wizualizację, która wyświetla się na mojej konsoli, zachowując dane wyjściowe programu?

spławik205
źródło
Hmm, spójrz jak duplikat wczorajszego pytania: stackoverflow.com/questions/3160699/python-progress-bar/3162864 Więc powinieneś użyć fish pypi.python.org/pypi/fish
Etienne
29
„wystarczy użyć GUI” źle rozumie, że GUI są świetne w niektórych sytuacjach (krzywa szybkiego uczenia się, eksploracja ad-hoc lub działania interaktywne lub jednorazowe), podczas gdy narzędzia wiersza polecenia są świetne dla innych (eksperci, tworzący aplikacje ad-hoc na mucha, aby wiele razy wykonać dokładnie określoną operację).
Jonathan Hartley,
14
Głosowałem za ponownym otwarciem. Pytanie nie wydaje mi się zbyt szerokie.
Franck Dernoncourt
Myślę, że to, czego szukasz, to tqdm ... chociaż nie wiem również, dlaczego SO zachęca mnie do ponownego rozpatrzenia głosów na pytania od lat.
kungphu
Opublikowałem nowy rodzaj paska postępu, który możesz wydrukować, zobaczyć przepustowość i eta, a nawet wstrzymać go, oprócz bardzo fajnych animacji! Proszę spojrzeć: github.com/rsalmei/alive-progress ! alive-progress
rsalmei

Odpowiedzi:

464

Prosty, konfigurowalny pasek postępu

Oto podsumowanie wielu poniższych odpowiedzi, z których regularnie korzystam (import nie jest wymagany).

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

Uwaga: dotyczy Python 3; zobacz komentarze, aby uzyskać szczegółowe informacje na temat korzystania z tego w Python 2.

Przykładowe użycie

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)

Przykładowe dane wyjściowe:

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

Aktualizacja

W komentarzach była dyskusja na temat opcji, która pozwala dynamicznie dostosowywać pasek postępu do szerokości okna terminala. Chociaż nie polecam tego, oto podstawa, która implementuje tę funkcję (i zwraca uwagę na zastrzeżenia).

Greenstick
źródło
21
Ten fragment kodu działa świetnie! Zetknąłem się z kilkoma drobnymi problemami, więc wprowadziłem kilka drobnych zmian (PEP-8, domyślne kodowanie znaków innych niż ascii) i wrzuciłem je w skrócie
Aubricus
3
Warto zauważyć, że deklaracja UTF-8 nie jest konieczna, chyba że używasz Python 2 @Aubricus
Greenstick,
2
@MattClimbs To jest napisane dla Pythona 3, który domyślnie wykorzystuje kodowanie UTF-8. Możesz zmienić domyślny parametr wypełnienia funkcji, który jest znakiem UTF-8, lub użyć deklaracji UTF-8. Zobacz treść powyższego komentarza, aby zobaczyć, jak powinna wyglądać deklaracja UTF-8.
Greenstick,
1
Dzięki, miłe podsumowanie, również wykrycie wielkości terminala może być przydatne, ponieważ ta funkcja # Size of terminal rows, columns = [int(x) for x in os.popen('stty size', 'r').read().split()] columnspowinna zostać przekazana na długość, aby dostosować rozmiar paska postępu do okna terminala. Chociaż długość postępującej części taktu powinna zostać zmniejszona (o długość prefiksu, sufiksu, procentu i dodatkowych znaków w tym ciągu'\r%s |%s| %s%% %s'
Arleg
3
Aby to działało w niektórych IDE (np. PyCharm w systemie Windows), może być konieczna zmiana end = '\r'na end = ''.
thomas88wp,
312

Pisanie „\ r” spowoduje przesunięcie kursora z powrotem na początek linii.

Wyświetla licznik procentowy:

import time
import sys

for i in range(100):
    time.sleep(1)
    sys.stdout.write("\r%d%%" % i)
    sys.stdout.flush()
Stephen
źródło
3
Wkleiłem to i pobiegłem. Za każdym razem drukuje do nowej linii. Chcę, aby numer był aktualizowany w tym samym wierszu. :)
bobber205
8
Ten przykład wytwarza również OBOB, którego ładowanie kończy się o godz.99%
Glenn Dayton,
10
@moose Oznacza „Off by one bug”
Glenn Dayton
3
printma endargument: stackoverflow.com/a/8436827/1959808
Ioannis Filippidis
3
Aby dodać do tego, co powiedział @IoannisFilippidis, printma także flushargument: docs.python.org/3/library/functions.html#print
Wso
113

Napisz \rdo konsoli. Jest to „powrót karetki”, który powoduje, że cały tekst jest powtarzany na początku wiersza. Coś jak:

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

co da ci coś takiego: [ ########## ] 100%

aviraldg
źródło
19
Zrób, \ra następnie napisz całą linię ponownie. Zasadniczo: print("\rProgress: [{0:50s}] {1:.1f}%".format('#' * int(amtDone * 50), amtDone * 100))gdzie liczba amtDonezmiennoprzecinkowa wynosi od 0 do 1.
Mike DeSimone
13
Lepszy w użyciu sys.stdout.writeniż print. Z printmam nowe linie.
Gill Bates,
14
dodaj dla mnie przecinek ,na końcu printprac.
Chunliang Lyu
10
w python3 zastosowania druku (...., end = '') i nie będzie miał żadnych nowych linii
Graywolf
7
Podsumowanie dla byłego języka Python3:, print("\rProgress: [{0:50s}] {1:.1f}%".format('#' * int(workdone * 50), workdone*100), end="", flush=True)gdzie liczba workdonezmiennoprzecinkowa wynosi od 0 do 1, np.workdone = parsed_dirs/total_dirs
khyox
70

Jest mniej niż 10 linii kodu.

Istota tutaj: 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

wprowadź opis zdjęcia tutaj

Vladimir Ignatyev
źródło
2
dodaje „sys.stdout.flush ()” na końcu funkcji.
romruben
dla mnie idzie w nowej linii
GM
@GM, jakiego systemu operacyjnego / platformy używasz?
Vladimir Ignatyev
Nie wiem dlaczego, jeśli uruchomię go ze spyder ide, to nie zadziała, ale jeśli uruchomię go z konsoli ipython, to zadziała!
GM
62

Wypróbuj bibliotekę kliknięć napisaną przez Mozarta z Python, Armin Ronacher.

$ pip install click # both 2 and 3 compatible

Aby utworzyć prosty pasek postępu:

import click

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

Tak to wygląda:

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

Dostosuj do swoich serc:

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

Niestandardowy wygląd:

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

Jest jeszcze więcej opcji, zobacz dokumentację 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)
The Unfun Cat
źródło
33

Zdaję sobie sprawę, że spóźniłem się na grę, ale tutaj napisałem nieco w stylu Yum (Red Hat), który napisałem (nie dążąc do 100% dokładności, ale jeśli używasz paska postępu dla tego poziomu dokładności, to i tak są NIEPRAWIDŁOWE):

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

Powinny produkować coś takiego:

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

... gdzie wsporniki pozostają nieruchome, a tylko krzyki rosną.

To może działać lepiej jako dekorator. Na kolejny dzień ...

JoeLinux
źródło
2
Świetne rozwiązanie! Działa świetnie! Dziękuję Ci bardzo!
Vasilije Bursac
18

Sprawdź tę bibliotekę: clint

ma wiele funkcji, w tym pasek postępu:

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)

ten link zapewnia szybki przegląd jego funkcji

skrypty
źródło
12

Oto ładny przykład paska postępu napisanego w Pythonie: http://nadiana.com/animated-terminal-progress-bar-in-python

Ale jeśli chcesz to napisać sam. Możesz użyć cursesmodułu, aby ułatwić sobie życie :)

[edytuj] Być może łatwiejsze nie jest słowo na przekleństwa. Ale jeśli chcesz stworzyć pełnowymiarowe cui, przekleństwa zajmą się wieloma sprawami.

[edytuj] Ponieważ stary link jest martwy, uruchomiłem własną wersję paska postępu Pythona, pobierz go tutaj: https://github.com/WoLpH/python-progressbar

Wolph
źródło
14
curses? Łatwiej? Hmmm ....
aviraldg
Doskonały artykuł, chciałem podać link do niego, ale nie mogłem znaleźć w moich zakładkach :)
Andy Mikhaylenko
@Aviral Dasgupta: w porządku, łatwiej może nie być tutaj dobrym słowem. Może jednak zaoszczędzić dużo pracy, ale tak naprawdę zależy od tego, czego szukasz.
Wolph
Nie szukam niczego w pobliżu tego, ale i tak dziękuję. :)
bobber205
2
Martwy link, to cena za nie publikowanie treści z linkami w odpowiedzi -__-
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()

wynik

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

ashish2py
źródło
7

i, aby dodać do stosu, oto obiekt, którego możesz użyć

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"

prowadzi do:

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

Najczęściej uważa się to za „przesadne”, ale jest to przydatne, gdy często go używasz

FraggaMuffin
źródło
Dzięki za to. Mała poprawka, metoda plotProgress powinna używać linii sys.stdout.flush (), w przeciwnym razie pasek postępu może nie zostać narysowany, dopóki zadanie nie zostanie ukończone (jak ma to miejsce w terminalu mac).
osnoz
Uwielbiam to!!! Dość łatwy w użyciu !!! Dziękuję
Microos
7

Zainstaluj tqdm. ( pip install tqdm) I użyj go w następujący sposób:

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

To 10-sekundowy pasek postępu, który wyświetli coś takiego:

47%|██████████████████▊                     | 470/1000 [00:04<00:05, 98.61it/s]
Smoking
źródło
6

Uruchom to w wierszu polecenia Python ( nie w żadnym środowisku IDE ani środowisku programistycznym):

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

Działa dobrze w moim systemie Windows.

PaulMcG
źródło
4

Korzystam z postępu od reddit . Podoba mi się, ponieważ może drukować postęp dla każdego elementu w jednym wierszu i nie powinien usuwać wydruków z programu.

Edycja: naprawiono link

Ib33X
źródło
1
Twój link jest zepsuty - rzeczywista linia w kodzie źródłowym to 1274, a nie 1124! Tak więc właściwy link to ten: github.com/reddit/reddit/blob/master/r2/r2/lib/utils/…
Vladimir Ignatyev
Ten wariant ma najlepszy projekt według mojego gustu: wykorzystuje iteratory i może pracować z dowolną mierzalną pracą, pokazuje upływ czasu.
Vladimir Ignatyev
4

Spróbuj zainstalować ten pakiet 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
źródło
3

w oparciu o powyższe odpowiedzi i inne podobne pytania dotyczące paska postępu CLI, myślę, że mam ogólną wspólną odpowiedź na wszystkie z nich. Sprawdź to na https://stackoverflow.com/a/15860757/2254146

Podsumowując, kod jest następujący:

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

Wygląda jak

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

Brian Khuu
źródło
3

Polecam użycie tqdm - https://pypi.python.org/pypi/tqdm - co ułatwia przekształcenie dowolnej iterowalnej lub przetworzonej w pasek postępu i obsługuje wszystkie problemy związane z potrzebnymi terminalami.

Z dokumentacji: „tqdm może z łatwością obsługiwać połączenia zwrotne / przechwytywania i aktualizacje ręczne. Oto przykład z 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
źródło
3

Bardzo prostym rozwiązaniem jest umieszczenie tego kodu w pętli:

Umieść to w treści (tj. U góry) pliku:

import sys

Umieść to w ciele swojej pętli:

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

progressbar()

UWAGA: jeśli uruchomisz to w interaktywnym interpreterie, wydrukowane zostaną dodatkowe liczby

Ramchandra Apte
źródło
2

lol właśnie napisałem całą sprawę dla tego kodu, pamiętaj, że nie możesz używać Unicode podczas wykonywania bloku ascii i używam 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()

i tak to nazywacie

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

więc tak to wygląda

loading something awesome
|█████     |
Ryan
źródło
2

Z powyższymi świetnymi radami opracowuję pasek postępu.

Chciałbym jednak wskazać pewne niedociągnięcia

  1. Za każdym razem, gdy pasek postępu jest opróżniany, zaczyna się od nowej linii

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

    jak to:
    [] 0%
    [#] 10%
    [##] 20%
    [###] 30%

2. Nawias kwadratowy „]” i liczba procentowa po prawej stronie przesuwają się w prawo, gdy cyfra „###” wydłuża się.
3. Błąd wystąpi, jeśli wyrażenie „progress / 10” nie może zwrócić liczby całkowitej.

Poniższy kod naprawi powyższy problem.

def update_progress(progress, total):  
    print('\r[{0:10}]{1:>2}%'.format('#' * int(progress * 10 /total), progress), end='')
Storm-Eyes
źródło
1

Kod paska postępu terminala 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()
emd_22
źródło
1

napisałem prosty pasek postępu:

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)

jak widać, ma: długość paska, prefiks i sufiks, wypełniacz, spację, tekst w pasku na 100% (oncomp) i obramowania

tutaj przykład:

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)

w toku:

30% [######              ]

obecnie zakończone:

100% [   done in 9 sec   ] 
Jenkins
źródło
1

Zestawienie niektórych pomysłów, które tu znalazłem, i dodanie szacowanego pozostałego czasu:

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
źródło
1

Dla 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
źródło
0

Oto kod, który działa i przetestowałem go przed opublikowaniem:

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

Plusy:

  • Pasek 20 znaków (1 znak na każde 5 (pod względem liczbowym))
  • Niestandardowe znaki wypełniania
  • Niestandardowe puste znaki
  • Zatrzymaj (dowolna liczba poniżej 0)
  • Gotowe (100 i dowolna liczba powyżej 100)
  • Liczba postępów (0-100 (poniżej i powyżej używane dla funkcji specjalnych))
  • Liczba procentowa obok paska i jest to pojedyncza linia

Cons:

  • Obsługuje tylko liczby całkowite (można je zmodyfikować, aby je obsługiwały, zmieniając podział na całkowity, więc po prostu zmień prog2 = prog/5na prog2 = int(prog/5))
Zimny ​​Diamondz
źródło
0

Oto moje rozwiązanie Python 3:

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

„\ b” jest odwrotnym ukośnikiem dla każdego znaku w ciągu. To nie działa w oknie cmd systemu Windows.

Matt-the-Bat
źródło
0

funkcja z Greenstick dla 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
źródło
0

Pasek postępu modułu python jest dobrym wyborem. Oto mój typowy kod:

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
źródło