Python Progress Bar

Как использовать индикатор выполнения, когда мой script выполняет некоторую задачу, которая может занять некоторое время?

Например, функция, которая занимает некоторое время для завершения и возвращает True по завершении. Как я могу отображать индикатор выполнения во время выполнения функции?

Обратите внимание, что мне нужно, чтобы это было в режиме реального времени, поэтому я не могу понять, что с этим делать. Мне нужен thread для этого? Я понятия не имею.

Сейчас я ничего не печатаю во время выполнения функции, однако индикатор выполнения будет приятным. Также меня больше интересует, как это можно сделать с кодовой точки зрения.

Ответ 1

Существуют определенные библиотеки (как здесь), но может быть что-то очень простое сделает:

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

Примечание. progressbar2 - это ответвление progressbar, которое не поддерживалось годами.

Ответ 2

С tqdm вы можете добавить индикатор прогресса в ваши циклы в секунду:

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]

Кроме того, существует графическая версия tqdm начиная с 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)

tqdm gui window

Но будьте осторожны, поскольку tqdm_gui может вызвать TqdmExperimentalWarning: GUI is experimental/alpha, вы можете проигнорировать его, используя warnings.simplefilter("ignore"), но после этого он будет игнорировать все предупреждения в вашем коде.

Ответ 3

Вышеприведенные предложения очень хороши, но я думаю, что большинство людей просто хотят готовое решение, без зависимости от внешних пакетов, но также можно использовать повторно.

Я получил лучшие точки всего вышеперечисленного и сделал его функцией, а также тестовые примеры.

Чтобы использовать его, просто скопируйте строки под "def update_progress (progress)", но не тест script. Не забудьте импортировать sys. Вызовите это, когда вам нужно отобразить или обновить индикатор выполнения.

Это работает, напрямую отправив символ "\ r" в консоль, чтобы переместить курсор в начало. "print" в python не выделяет вышеуказанный символ для этой цели, поэтому нам нужен "sys"

import time, sys

# update_progress() : Displays or updates a console progress bar
## Accepts a float between 0 and 1. Any int will be converted to a float.
## A value under 0 represents a 'halt'.
## A value at 1 or bigger represents 100%
def update_progress(progress):
    barLength = 10 # Modify this to change the length of the progress bar
    status = ""
    if isinstance(progress, int):
        progress = float(progress)
    if not isinstance(progress, float):
        progress = 0
        status = "error: progress var must be float\r\n"
    if progress < 0:
        progress = 0
        status = "Halt...\r\n"
    if progress >= 1:
        progress = 1
        status = "Done...\r\n"
    block = int(round(barLength*progress))
    text = "\rPercent: [{0}] {1}% {2}".format( "#"*block + "-"*(barLength-block), progress*100, status)
    sys.stdout.write(text)
    sys.stdout.flush()


# update_progress test script
print "progress : 'hello'"
update_progress("hello")
time.sleep(1)

print "progress : 3"
update_progress(3)
time.sleep(1)

print "progress : [23]"
update_progress([23])
time.sleep(1)

print ""
print "progress : -10"
update_progress(-10)
time.sleep(2)

print ""
print "progress : 10"
update_progress(10)
time.sleep(2)

print ""
print "progress : 0->1"
for i in range(100):
    time.sleep(0.1)
    update_progress(i/100.0)

print ""
print "Test completed"
time.sleep(10)

Вот что показывает результат теста script (последний анимированный индикатор выполнения):

progress : 'hello'
Percent: [----------] 0% error: progress var must be float
progress : 3
Percent: [##########] 100% Done...
progress : [23]
Percent: [----------] 0% error: progress var must be float

progress : -10
Percent: [----------] 0% Halt...

progress : 10
Percent: [##########] 100% Done...

progress : 0->1
Percent: [##########] 99.0%
Test completed

Ответ 4

Этот ответ не зависит от внешних пакетов, я также думаю, что большинство людей просто хотят готовый кусок кода. Приведенный ниже код может быть адаптирован к вашим потребностям путем настройки: символ хода строки '#', size строки, prefix текста и т.д.

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

Использование:

import time

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

Выход:

Computing: [################........................] 4/15
  • Не требует второго потока. Некоторые решения/пакеты выше требуют. Второй поток может быть проблемой, например, для jupyter notebook.

  • Работает с любой итерацией, это означает, что можно использовать len(). list, dict чего-либо, например ['a', 'b', 'c'... 'g']

Вы также можете изменить вывод, например, изменив файл на sys.stderr

Ответ 5

для аналогичного приложения (отслеживание хода в цикле) Я просто использовал python-progressbar:

В их примере идет что-то вроде этого,

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

Ответ 6

Попробуйте выполнить 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()

В результате будет отображаться следующая строка:

Processing |#############                   | 42/100

Ответ 7

Я просто сделал простой класс прогресса для своих нужд после поиска здесь эквивалентного решения. Я думал, что могу хорошо это записать.

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)

Пример:

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

Распечатайте следующее:

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

Ответ 8

Мне нравится Брайан Хуу ответить за его простоту и не нуждается в внешних пакетах. Я немного изменил его, поэтому добавляю свою версию здесь:

import sys
import time


def updt(total, progress):
    """
    Displays or updates a console progress bar.

    Original source: /questions/27978/python-progress-bar/205178#205178
    """
    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)

Требуется общее количество прогонов (total) и количество прогонов, обработанных до сих пор (progress), предполагая total >= progress. Результат выглядит следующим образом:

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

Ответ 9

Вы можете использовать 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)

В этом примере индикатор выполнения работает в течение 5 минут, и он показан так:

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

Вы можете изменить его и настроить по своему усмотрению.

Ответ 10

Мне очень нравится python-progressbar, так как он очень прост в использовании.

Для самого простого случая это просто:

import progressbar
import time

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

Внешний вид может быть настроен, и он может отображать приблизительное оставшееся время. Для примера используйте тот же код, что и выше, но с:

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

Ответ 11

Если это большой цикл с фиксированным количеством итераций, который занимает много времени, вы можете использовать эту функцию, которую я сделал. Каждая итерация цикла добавляет прогресс. Если count - текущая итерация цикла, общее значение - это значение, которое вы зацикливаете, а размер (int) - это то, насколько вы хотите, чтобы полоса с шагом 10, т.е. (Размер 1 = 10 символов, размер 2 = 20 символов)

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

пример:

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

вывод:

i = 50
>> 050/100 [==========          ]

Ответ 12

Используйте эту библиотеку: fish (GitHub).

Использование:

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

Удачи!

Ответ 13

Код ниже является довольно общим решением, а также имеет время, прошедшее и оставшееся время. Вы можете использовать любой итеративный вариант. Индикатор выполнения имеет фиксированный размер в 25 символов, но он может показывать обновления с шагом 1% с использованием полных, половинных и четверть блоков символов. Результат выглядит следующим образом:

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

Код с примером:

import sys, time
from numpy import linspace

def ProgressBar(iterObj, refreshTime=10):
  #refreshTime=10: refresh the time estimate at least every 10 sec.
  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(np.linspace(0,L,  min(100,L),endpoint=False), 
                                     np.linspace(0,100,min(100,L),endpoint=False))}
  qSteps  = ['', u'\u258E',u'\u258C',u'\u258A'] # quarter and half block chars
  startT  = endT = time.time()
  timeStr = ' [0:00:00, -:--:--]'
  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+timeStr); sys.stdout.flush()
    elif time.time()-endT > refreshTime:
      endT    = time.time()
      timeStr = ' [%s, %s]'%(SecToStr(endT-startT), SecToStr((endT-startT)*(L/float(nn)-1)))
      sys.stdout.write('\r'+barStr+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 op in ProgressBar(list('Disassemble and reassemble this string')):
  time.sleep(0.5)
  s += op
print s

Предложения по улучшению или другие комментарии приветствуются. Повеселись.

Ответ 14

Это довольно просто в 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')

Ответ 15

При работе в ноутбуках Jupyter использование обычного tqdm не работает, так как записывает вывод в несколько строк. Используйте это вместо:

import time
from tqdm import tqdm_notebook as tqdm

for i in tqdm(range(100))
    time.sleep(0.5)

Ответ 16

Мне нравится эта страница.

Начинается с простого примера и переходит на многопоточную версию. Работает из коробки. Не требуется сторонних пакетов.

Код будет выглядеть примерно так:

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)

Или вот пример использования потоков для запуска вращающейся загрузочной панели во время работы программы:

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

Ответ 17

Мне нравится Gabriel, но я изменил его, чтобы быть гибким. Вы можете отправить длину бара функции и получить свой индикатор выполнения любой длины, которую вы хотите. И вы не можете иметь индикатор выполнения с нулевой или отрицательной длиной. Кроме того, вы можете использовать эту функцию, например, Gabriel (см. Пример №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)

Результат:

Это простой индикатор выполнения.

Пример # 1

Прогресс: [### -------] 30%

Пример # 2

Прогресс: [||||||||||||........] 60%

Готово.

Ответ 18

Если ваша работа не может быть разбита на измеримые куски, вы можете вызвать свою функцию в новом потоке и времени, сколько времени потребуется:

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"

Вы можете, очевидно, увеличить точность синхронизации.

Ответ 19

Здесь короткое решение, которое программно создает панель загрузки (вы должны решить, сколько времени вы хотите).

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)

Ответ 20

Попробуйте PyProg. PyProg - это библиотека с открытым исходным кодом для Python для создания супер настраиваемых индикаторов и индикаторов прогресса.

В настоящее время он находится в версии 1.0.2; он размещен на Github и доступен на PyPI (ссылки ниже). Он совместим с Python 3 и 2, и его также можно использовать с Qt Console.

Он очень прост в использовании. Следующий код:

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

будет производить:

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

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

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

Я действительно сделал PyProg, потому что мне нужна простая, но супер настраиваемая библиотека индикаторов выполнения. Вы можете легко установить его с помощью: pip install pyprog.

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

Ответ 21

Вы также можете использовать просвет. Главное преимущество - вы можете входить в систему одновременно, не перезаписывая индикатор выполнения.

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

Он также обрабатывает несколько индикаторов выполнения.

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

Ответ 22

Чтобы использовать любые рамки индикаторов прогресса полезным способом, например, чтобы получить фактический процент прогресса и предполагаемое ETA, вы должны иметь возможность объявить, сколько шагов у него будет.

Итак, ваша вычислительная функция в другом потоке, вы можете разделить ее на несколько логических шагов? Можете ли вы изменить его код?

Вам не нужно его реорганизовывать или разделять на реальные методы, вы можете просто поместить стратегический yield в некоторые места внутри него! Если в дорогой функции есть цикл for, просто поместите его в нее. В конце вы должны знать только, сколько будет получено урожая, чтобы получить наилучшие результаты.

Таким образом, ваша функция может выглядеть примерно так:

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

или это:

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

С помощью такой функции вы можете установить:

pip install alive-progress

И используйте это как:

from alive_progress import alive_bar

with alive_bar(3) as bar:
    for i in compute():
        bar()

Чтобы получить крутой прогресс-бар!

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

Отказ от ответственности: я являюсь автором alive_bar, но это должно хорошо решить вашу проблему. Прочитайте документацию на https://github.com/rsalmei/alive-progress, вот пример того, что он может сделать:

alive-progress

Ответ 23

Вы должны привязать индикатор выполнения к задаче под рукой (чтобы она оценивала прогресс: D). Например, если вы FTP файл, вы можете сказать, что ftplib захватывает буфер определенного размера, скажем 128K, а затем вы добавляете в панель выполнения любой процент от размера файла 128k. Если вы используете CLI, а ваш индикатор прогресса составляет 20 символов, вы должны добавить один символ, когда 1/20 из файла были переданы.

Ответ 24

@Massagran: он хорошо работает в моих программах. Кроме того, нам нужно добавить счетчик, чтобы указать время цикла. Этот счетчик играет роль аргумента метода update. Например: прочитайте все строки тестового файла и обработайте их на что-то. Предположим, что функция dosth() не относится к переменной 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()

Переменная i управляет состоянием pbar с помощью метода update

Ответ 25

немного более общий ответ jelde015 (кредит ему, конечно)

Для обновления полосы загрузки вручную будет:

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

и называя это:

loadingBar(7, 220, 40)

приведет к:

007/220 [=                                       ]  

просто вызывайте его, когда хотите, с текущим значением i.

установите size как количество символов в баре

Ответ 26

используйте os_sys lib:

Я использую его для многих типов баров, например:

from os_sys.progress import bar as Bar
bar = Bar('progresing: ', max=20)
for i in range(20):
    #do somthing
    bar.next()
bar.finish()

ваш вывод будет:

procesing:  |######                          | 2/10

подробнее читайте в описании os_sys

Ответ 27

Думаю, я немного опоздал, но это должно работать для людей, работающих с текущими версиями Python 3, так как здесь используются "f-strings", как представлено в Python 3.6 PEP 498:

Код

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

пример

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

Выход

Downloading: [########------------] 8/20 40.00%

Ответ 28

Это простой способ создать индикатор

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)

Ответ 29

На индикаторе выполнения отображаются баллы за каждые 2 процента выполнения и цифры за каждые 10 процентов выполнения.

import sys

def ProgressBar (num, total, nextPercent, nextPoint):
    num = float (num)
    total = float (total) - 1
    if not nextPoint:
        nextPoint = 0.0
    if not nextPercent:
        nextPoint += 2.0
        sys.stdout.write ("[0%")
        nextPercent = 10
    elif num == total:
        sys.stdout.write ("100%]\n")
        nextPercent += 10
    elif not nextPoint:
        nextPoint = 0.0
    elif num / total * 100 >= nextPercent:
        sys.stdout.write (str(int (nextPercent)) + "%")
        nextPercent += 10
    elif num / total * 100 >= nextPoint:
        sys.stdout.write (":")
        nextPoint += 2
    return (nextPercent, nextPoint)

nextPercent, nextPoint = 0, 0
total = 1000

for num in range (total):
    nextPercent, nextPoint = ProgressBar (num, total, nextPercent, nextPoint)

Результаты:

>>> 
[0%::::10%:::::20%:::::30%:::::40%:::::50%:::::60%:::::70%:::::80%:::::90%:::::100%]
>>> 

Ответ 30

Я использовал метод format() для создания полосы загрузки. Вот мое решение:

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

Выход:

[#######################] - 100.00%