Bilah Kemajuan Python

307

Bagaimana cara menggunakan bilah kemajuan saat skrip saya melakukan beberapa tugas yang mungkin akan memakan waktu?

Misalnya, fungsi yang membutuhkan waktu untuk diselesaikan dan kembali Truesaat selesai. Bagaimana saya bisa menampilkan bilah kemajuan selama fungsi dijalankan?

Perhatikan bahwa saya perlu ini dalam waktu nyata, jadi saya tidak tahu apa yang harus saya lakukan. Apakah saya memerlukan threadini? Saya tidak punya ide.

Saat ini saya tidak sedang mencetak apa-apa saat fungsi sedang dieksekusi, tetapi progress bar akan lebih baik. Saya juga lebih tertarik pada bagaimana hal ini dapat dilakukan dari sudut pandang kode.

pengguna225312
sumber
Apakah Anda menggunakan GUI toolkit atau CLI saja?
Bobby
CLI. Tapi saya bisa menggunakan perpustakaan pihak ketiga, itu tidak masalah. Dengan GUI saya bisa melakukan ini, tetapi saya tertarik pada bagian CLI.
user225312
1
Kemungkinan duplikat Bilah Kemajuan Teks di Konsol. Perhatikan bahwa sementara pertanyaan ini diposting tiga hari sebelumnya, pertanyaan terkait lebih sering dilihat.
Greenstick
Berikut ini adalah solusi untuk dalam Jupyter Notebook: mikulskibartosz.name/…
Steven C. Howell
Saya telah menerbitkan jenis progress bar baru, yang dapat Anda cetak, lihat throughput dan eta, bahkan menghentikannya, di samping animasi yang sangat keren! Silakan lihat: github.com/rsalmei/alive-progress ! hidup-kemajuan
rsalmei

Jawaban:

185

Ada perpustakaan tertentu ( seperti ini di sini ) tetapi mungkin sesuatu yang sangat sederhana akan dilakukan:

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

Catatan: progressbar2 adalah cabang dari progressbar yang belum dipelihara selama bertahun-tahun.

ChristopheD
sumber
14
ini tidak skala untuk banyak langkah ... pypi.python.org/pypi/progress jauh lebih mudah digunakan
m13r
5
Saya mencoba kode ini, dan itu melemparkan NameError: name 'xrange' is not definedkesalahan. Apakah saya kehilangan modul?
Mushroom Man
6
@ GokuMcSpock9733 Versi Python mana yang Anda gunakan? Python 2 xrangeadalah Python 3 range.
quapka
9
Ini seharusnya bukan jawaban atas. Jawaban lain (dengan tqdm) jauh lebih baik bagi saya setidaknya.
Florian
1
Progress bar of poor di Python 3:print('■', end='', flush=True)
PatrickT
351

Dengan tqdm Anda dapat menambahkan pengukur kemajuan ke loop Anda dalam sedetik:

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]

Juga, ada versi grafis tqdm sejak 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)

jendela tqdm gui

Tapi hati-hati, karena tqdm_guidapat meningkatkan TqdmExperimentalWarning: GUI is experimental/alpha, Anda dapat mengabaikannya dengan menggunakan warnings.simplefilter("ignore"), tetapi itu akan mengabaikan semua peringatan dalam kode Anda setelah itu.

scls
sumber
9
Ini adalah satu-satunya solusi yang saya temukan untuk bekerja dengan terminal, qtconsole dan notebook
Ivelin
3
Apakah itu berhasil dengan iterable? Saya kesulitan membuatnya bekerja dengan daftar string.
Josh Usre
3
@ JoshUsre Ya itu harus bekerja dengan iterable, untuk saat ini saya tidak melihat iterable tersendat. Namun, tampilan ETA (sisa waktu) mengharuskan iterable untuk memiliki __len__properti atau pengguna harus memberikan totalargumen tqdm. Selain itu, bilah akan berfungsi tetapi tanpa ETA.
Gaborous
6
@ Gaborous: Kenapa ini bukan jawaban yang terpilih? Solusi sederhana ini berfungsi baik di terminal maupun di notebook Jupyter tidak seperti jawaban teratas.
Ébe Isaac
6
untuk berjalan dalam penggunaan notebook jupyter from tqdm import tqdm_notebook as tqdm. Kalau tidak, jangan tulis di satu baris.
Jacques MALAPRADE
81

Saran di atas cukup bagus, tapi saya pikir kebanyakan orang hanya ingin solusi yang sudah jadi, tanpa ketergantungan pada paket eksternal, tetapi juga dapat digunakan kembali.

Saya mendapatkan poin terbaik dari semua di atas, dan membuatnya menjadi fungsi, bersama dengan test case.

Untuk menggunakannya, cukup salin baris di bawah "def update_progress (progress)" tetapi bukan skrip pengujian. Jangan lupa untuk mengimpor sys. Sebut ini setiap kali Anda perlu menampilkan atau memperbarui bilah progres.

Ini berfungsi dengan mengirim simbol "\ r" langsung ke konsol untuk memindahkan kursor kembali ke awal. "print" dengan python tidak mengembalikan simbol di atas untuk tujuan ini, maka kita perlu 'sys'

import time, sys

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


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

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

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

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

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

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

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

Inilah yang ditunjukkan hasil skrip uji (Bilah progres terakhir menjiwai):

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

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

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

progress : 0->1
Percent: [##########] 100% Done...
Test completed
Brian Khuu
sumber
10
Tes animasi (yang terakhir) seharusnya mengatakan in range(101)tidak 100, progres berhenti pada 99% dan tidak pernah menampilkan selesai.
Nick Humrich
41

Jawaban ini tidak bergantung pada paket eksternal , saya juga berpikir bahwa kebanyakan orang hanya ingin sepotong kode yang sudah jadi . Kode di bawah ini dapat diadaptasi agar sesuai dengan kebutuhan Anda dengan menyesuaikan: simbol progres '#'bar size, bar , teks prefixdll.

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

Pemakaian:

import time

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

Keluaran:

Computing: [################........................] 4/15
  • Tidak memerlukan utas kedua . Beberapa solusi / paket di atas memerlukan. Utas kedua dapat menjadi masalah, jupyter notebookmisalnya, misalnya.

  • Bekerja dengan semua iterable itu berarti apa saja yang len()dapat digunakan. A list, dictapa pun misalnya['a', 'b', 'c' ... 'g']

Anda juga dapat mengubah output dengan mengubah file ke sys.stderrmisalnya

eusoubrasileiro
sumber
Saya suka solusi ini, generator akan melempar kesalahan berikut:TypeError: object of type 'generator' has no len()
jabellcu
@ jabellcu dalam kasus itu ( generators) Anda harus membungkusnya dengan a list(). Sepertifor i in progressbar(list(your_generator), "Computing: ", 40):
eusoubrasileiro
22

untuk aplikasi yang serupa (melacak kemajuan dalam satu lingkaran) Saya cukup menggunakan python-progressbar :

Contoh mereka seperti ini,

from progressbar import *               # just a simple progress bar


widgets = ['Test: ', Percentage(), ' ', Bar(marker='0',left='[',right=']'),
           ' ', ETA(), ' ', FileTransferSpeed()] #see docs for other options

pbar = ProgressBar(widgets=widgets, maxval=500)
pbar.start()

for i in range(100,500+1,50):
    # here do something long at each iteration
    pbar.update(i) #this adds a little symbol at each iteration
pbar.finish()
print
Massagran
sumber
3
Untuk kompatibilitas Python 3, coba progressbar2paket. Kode di atas akan bekerja dengannya.
d33tah
2
Apakah Anda benar-benar hanya menggunakan import *?
eric
20

Coba kemajuan dari 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()

Hasilnya akan menjadi bar seperti berikut:

Processing |#############                   | 42/100
Vladislav
sumber
Baru saja mencoba ini. SANGAT mudah digunakan. Butuh waktu 2 menit (termasuk progres pemasangan pip) untuk menjalankan dan menjalankan status bar.
perelin
progressmembuat bilah yang bagus, tetapi gagal jika perangkat lunak lain memanipulasi stderr. maaf, tapi saya belum menyelidiki masalah sebenarnya.
Arthur
Ia mencetak satu baris untuk setiap kemajuan di konsol ubuntu saya, misalnya, jika maks = 20, ia mencetak 20 baris ... Bagaimana cara membuatnya mencetak hanya satu baris?
L's World
19

Saya baru saja membuat kelas kemajuan sederhana untuk kebutuhan saya setelah mencari di sini untuk solusi yang setara. Saya pikir saya mungkin mempostingnya.

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)

Contoh:

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

Akan mencetak yang berikut:

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

Romuald Brunet
sumber
3
Luar biasa, terima kasih untuk ini. BTW, Anda dapat menambahkan progress.currenttambahan di akhir __call__untuk membatasi interaksi dengan objek dari kode utama lebih.
npit
Kode ini sederhana, ringkas dan bermanfaat! Terima kasih!
Ian Rehwinkel
15

Saya suka jawaban Brian Khuu karena kesederhanaannya dan tidak membutuhkan paket eksternal. Saya mengubahnya sedikit jadi saya menambahkan versi saya di sini:

import sys
import time


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

    Original source: https://stackoverflow.com/a/15860757/1391441
    """
    barLength, status = 20, ""
    progress = float(progress) / float(total)
    if progress >= 1.:
        progress, status = 1, "\r\n"
    block = int(round(barLength * progress))
    text = "\r[{}] {:.0f}% {}".format(
        "#" * block + "-" * (barLength - block), round(progress * 100, 0),
        status)
    sys.stdout.write(text)
    sys.stdout.flush()


runs = 300
for run_num in range(runs):
    time.sleep(.1)
    updt(runs, run_num + 1)

Dibutuhkan jumlah total run ( total) dan jumlah run yang diproses sejauh ini ( progress) dengan asumsi total >= progress. Hasilnya terlihat seperti ini:

[#####---------------] 27%
Gabriel
sumber
14

Anda dapat menggunakan 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)

Dalam contoh ini bilah kemajuan berjalan selama 5 menit dan ditampilkan seperti itu:

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

Anda dapat mengubahnya dan menyesuaikannya sesuka Anda.

Eyal.D
sumber
11

Untuk menggunakan kerangka bilah kemajuan apa pun dengan cara yang bermanfaat, yaitu untuk mendapatkan persentase kemajuan aktual dan perkiraan ETA, Anda harus dapat mendeklarasikan berapa banyak langkah yang harus dilakukan.

Jadi, fungsi komputasi Anda di utas lain, apakah Anda dapat membaginya dalam beberapa langkah logis? Bisakah Anda memodifikasi kodenya?

Anda tidak perlu memperbarui atau memecahnya dalam metode aktual, Anda bisa meletakkan beberapa strategi yielddi beberapa tempat di dalamnya! Jika fungsi yang mahal memiliki for loop , cukup masukkan satu di dalamnya. Anda hanya harus tahu pada akhirnya berapa banyak hasil yang akan dilakukan, untuk mendapatkan hasil terbaik.

Dengan begitu, fungsi Anda bisa seperti ini:

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

atau ini:

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

Dengan fungsi semacam itu, Anda dapat menginstal:

pip install alive-progress

Dan gunakan seperti:

from alive_progress import alive_bar

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

Untuk mendapatkan progress-bar yang keren!

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

Penafian: Saya penulis Live_Progress, tetapi harus menyelesaikan masalah Anda dengan baik. Baca dokumentasi di https://github.com/rsalmei/alive-progress , berikut adalah contoh apa yang dapat dilakukannya:

kemajuan hidup

rsalmei
sumber
8

Saya sangat suka python-progressbar , karena sangat mudah digunakan.

Untuk kasus yang paling sederhana, itu hanya:

import progressbar
import time

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

Penampilannya dapat disesuaikan dan dapat menampilkan perkiraan sisa waktu. Sebagai contoh, gunakan kode yang sama seperti di atas tetapi dengan:

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

Jika itu adalah loop besar dengan jumlah iterasi tetap yang membutuhkan banyak waktu Anda dapat menggunakan fungsi ini saya buat. Setiap iterasi loop menambahkan kemajuan. Di mana hitungan adalah iterasi saat ini dari loop, total adalah nilai yang Anda looping ke dan ukuran (int) adalah seberapa besar Anda ingin bar dalam penambahan 10 yaitu (ukuran 1 = 10 karakter, ukuran 2 = 20 karakter)

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

contoh:

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

keluaran:

i = 50
>> 050/100 [==========          ]
jelde015
sumber
4

Gunakan perpustakaan ini: fish( GitHub ).

Pemakaian:

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

Selamat bersenang-senang!

Etienne
sumber
Itu mungkin. Anda harus bertanya kepada pengembang atau meninggalkan tiket: github.com/lericson/fish .
Etienne
4

Kode di bawah ini adalah solusi yang cukup umum dan juga memiliki waktu yang berlalu dan perkiraan sisa waktu. Anda bisa menggunakan iterable dengannya. Bilah progres memiliki ukuran tetap 25 karakter tetapi dapat menampilkan pembaruan dalam langkah 1% menggunakan karakter blok penuh, setengah, dan seperempat. Outputnya terlihat seperti ini:

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

Kode dengan contoh:

import sys, time
from numpy import linspace

def ProgressBar(iterObj):
  def SecToStr(sec):
    m, s = divmod(sec, 60)
    h, m = divmod(m, 60)
    return u'%d:%02d:%02d'%(h, m, s)
  L = len(iterObj)
  steps = {int(x):y for x,y in zip(linspace(0, L, min(100,L), endpoint=False),
                                   linspace(0, 100, min(100,L), endpoint=False))}
  qSteps = ['', u'\u258E', u'\u258C', u'\u258A'] # quarter and half block chars
  startT = time.time()
  timeStr = '   [0:00:00, -:--:--]'
  activity = [' -',' \\',' |',' /']
  for nn,item in enumerate(iterObj):
    if nn in steps:
      done = u'\u2588'*int(steps[nn]/4.0)+qSteps[int(steps[nn]%4)]
      todo = ' '*(25-len(done))
      barStr = u'%4d%% |%s%s|'%(steps[nn], done, todo)
    if nn>0:
      endT = time.time()
      timeStr = ' [%s, %s]'%(SecToStr(endT-startT),
                             SecToStr((endT-startT)*(L/float(nn)-1)))
    sys.stdout.write('\r'+barStr+activity[nn%4]+timeStr); sys.stdout.flush()
    yield item
  barStr = u'%4d%% |%s|'%(100, u'\u2588'*25)
  timeStr = '   [%s, 0:00:00]\n'%(SecToStr(time.time()-startT))
  sys.stdout.write('\r'+barStr+timeStr); sys.stdout.flush()

# Example
s = ''
for c in ProgressBar(list('Disassemble and reassemble this string')):
  time.sleep(0.2)
  s += c
print(s)

Saran untuk perbaikan atau komentar lainnya dihargai. Bersulang!

Niko
sumber
3

Saya suka halaman ini .

Mulai dengan contoh sederhana dan beralih ke versi multi-utas. Bekerja di luar kotak. Tidak diperlukan paket pihak ketiga.

Kode akan terlihat seperti ini:

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)

Atau di sini adalah contoh untuk menggunakan utas untuk menjalankan bilah pemintalan saat program sedang berjalan:

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
pengguna1862895
sumber
3

Ini cukup mudah di Python3:

   import time
   import math

    def show_progress_bar(bar_length, completed, total):
        bar_length_unit_value = (total / bar_length)
        completed_bar_part = math.ceil(completed / bar_length_unit_value)
        progress = "*" * completed_bar_part
        remaining = " " * (bar_length - completed_bar_part)
        percent_done = "%.2f" % ((completed / total) * 100)
        print(f'[{progress}{remaining}] {percent_done}%', end='\r')

    bar_length = 30
    total = 100
    for i in range(0, total + 1):
        show_progress_bar(bar_length, i, total)
        time.sleep(0.1)

    print('\n')
Anton Ivanov
sumber
3

Saat berjalan di notebook jupyter penggunaan tqdm normal tidak berfungsi, karena ia menulis keluaran pada banyak baris. Gunakan ini sebagai gantinya:

import time
from tqdm import tqdm_notebook as tqdm

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

Jika pekerjaan Anda tidak dapat dipecah menjadi potongan yang terukur, Anda dapat memanggil fungsi Anda di utas baru dan berapa lama waktu yang dibutuhkan:

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"

Anda jelas dapat meningkatkan ketepatan waktu sesuai kebutuhan.

bvanvugt
sumber
Di mana orang akan melakukan pekerjaan yang diukur dalam kode sebagai jawaban?
unseen_rider
2

Saya suka jawaban Gabriel , tetapi saya mengubahnya agar fleksibel. Anda dapat mengirim panjang bar ke fungsi dan mendapatkan progress bar dengan panjang yang Anda inginkan. Dan Anda tidak dapat memiliki bilah progres dengan panjang nol atau negatif. Anda juga dapat menggunakan fungsi ini seperti jawaban Gabriel (Lihat Contoh # 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)

Hasil:

Ini adalah bilah kemajuan sederhana.

Contoh 1

Kemajuan: [### -------] 30%

Contoh # 2

Kemajuan: [||||||||||| ........] 60%

Selesai

Saeed Zahedian Abroodi
sumber
2

Saya menggunakan format()metode untuk membuat bar beban. Ini solusinya:

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

Keluaran:

[#######################] - 100.00%
Matheus Tavares
sumber
1

Berikut solusi singkat yang membuat bilah pemuatan secara terprogram (Anda harus memutuskan berapa lama Anda menginginkannya).

import time

n = 33  # or however many loading slots you want to have
load = 0.01  # artificial loading time!
loading = '.' * n  # for strings, * is the repeat operator

for i in range(n+1):
    # this loop replaces each dot with a hash!
    print('\r%s Loading at %3d percent!' % (loading, i*100/n), end='')
    loading = loading[:i] + '#' + loading[i+1:]
    time.sleep(load)
étale-cohomology
sumber
1

Coba PyProg. PyProg adalah pustaka sumber terbuka untuk Python untuk membuat indikator & bilah kemajuan yang dapat disesuaikan.

Saat ini di versi 1.0.2; di-host di Github dan tersedia di PyPI (Tautan di bawah). Ini kompatibel dengan Python 3 & 2 dan juga dapat digunakan dengan Qt Console.

Ini sangat mudah digunakan. Kode berikut:

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

akan menghasilkan:

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

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

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

Saya benar-benar membuat PyProg karena saya membutuhkan pustaka kemajuan sederhana namun super dapat dikustomisasi. Anda dapat dengan mudah menginstalnya dengan: pip install pyprog.

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

Bill Kudo
sumber
1

Anda juga dapat menggunakan mencerahkan . Keuntungan utama adalah Anda dapat login pada saat yang sama tanpa menimpa bilah kemajuan Anda.

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

Ini juga menangani beberapa progress bar.

import time
import enlighten

manager = enlighten.Manager()
odds = manager.counter(total=50)
evens = manager.counter(total=50)

for num in range(1, 101):
    time.sleep(0.05)
    if num % 2:
        odds.update()
    else:
        evens.update()
aviso
sumber
1

Gunakan perpustakaan kemajuan !

pip install progress

Berikut adalah subkelas khusus yang saya tulis untuk memformat ETA / Elapsed times menjadi format yang lebih baik dibaca:

import datetime
from progress.bar import IncrementalBar


class ProgressBar(IncrementalBar):
    '''
    My custom progress bar that:
       - Show %, count, elapsed, eta
       - Time is shown in H:M:S format
    '''

    message = 'Progress'
    suffix  = '%(percent).1f%% (%(index)d/%(max)d) -- %(elapsed_min)s (eta: %(eta_min)s)'

    def formatTime(self, seconds):
        return str(datetime.timedelta(seconds=seconds))

    @property
    def elapsed_min(self):
        return self.formatTime(self.elapsed)

    @property
    def eta_min(self):
        return self.formatTime(self.eta)

if __name__=='__main__':
    counter = 120
    bar     = ProgressBar('Processing', max=counter)

    for i in range(counter):
        bar.next()
        time.sleep(1)

    bar.finish()
kakhkAtion
sumber
1

Ini solusi sederhana saya:

import time

def progress(_cur, _max):
    p = round(100*_cur/_max)
    b = f"Progress: {p}% - ["+"."*int(p/5)+" "*(20-int(p/5))+"]"
    print(b, end="\r")

# USAGE:
for i in range(0,101):
    time.sleep(0.1) 
    progress(i,100)

print("..."*5, end="\r")
print("Done")
Dododo
sumber
0

Anda harus menautkan bilah progres ke tugas yang ada (sehingga mengukur progres: D). Sebagai contoh, jika Anda sedang FTP file, Anda dapat memberitahu ftplib untuk mengambil buffer ukuran tertentu, misalkan 128K, dan kemudian Anda menambahkan ke progress bar Anda berapa pun persentase dari filesize 128k mewakili. Jika Anda menggunakan CLI, dan meteran kemajuan Anda sepanjang 20 karakter, Anda akan menambahkan satu karakter ketika 1/20 file telah ditransfer.

johncip
sumber
Dalam kasus saya, saya menggunakan API dan tidak memberikan fasilitas untuk mendapatkan potongan tertentu. Terima kasih atas idenya, itu bagus.
user225312
0

@ Massagran: Ini berfungsi baik di program saya. Selanjutnya, kita perlu menambahkan penghitung untuk menunjukkan waktu loop. Penghitung ini berperan sebagai argumen metode update. Misalnya: baca semua baris file tes dan perlakukan mereka pada sesuatu. Misalkan fungsi dosth()tersebut tidak terkait dengan variabel 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()

Variabel imengontrol status pbarvia metodeupdate

Tung
sumber
0

jawaban yang sedikit lebih umum dari jelde015 (kredit kepadanya tentu saja)

untuk memperbarui bilah pemuatan secara manual adalah:

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

dan menyebutnya dengan:

loadingBar(7, 220, 40)

akan menghasilkan:

007/220 [=                                       ]  

panggil saja kapan saja Anda mau dengan nilai saat ini i.

atur sizejumlah chars yang seharusnya

Yarden Cohen
sumber
0

Kira saya sedikit terlambat tetapi ini harus bekerja untuk orang-orang yang bekerja dengan versi python 3 saat ini, karena ini menggunakan "f-string" , seperti yang diperkenalkan dalam Python 3.6 PEP 498 :

Kode

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

Contoh

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

Keluaran

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

Ini adalah cara sederhana untuk membuat progressbar

import time,sys
toolbar_width = 50
# setting up toolbar [-------------------------------------]
sys.stdout.write("[%s]"%(("-")*toolbar_width))
sys.stdout.flush()
# each hash represents 2 % of the progress
for i in range(toolbar_width):
    sys.stdout.write("\r") # return to start of line
    sys.stdout.flush()
    sys.stdout.write("[")#Overwrite over the existing text from the start 
    sys.stdout.write("#"*(i+1))# number of # denotes the progress completed 
    sys.stdout.flush()
    time.sleep(0.1)
Prasaanth Selvakumar
sumber