Bilah Kemajuan Teks di Konsol [ditutup]

435

Saya menulis aplikasi konsol sederhana untuk mengunggah dan mengunduh file dari server FTP menggunakan ftplib.

Saya ingin aplikasi menunjukkan visualisasi dari proses pengunduhan / pengunggahannya bagi pengguna; setiap kali sepotong data diunduh, saya ingin itu memberikan pembaruan kemajuan, bahkan jika itu hanya representasi numerik seperti persentase.

Yang penting, saya ingin menghindari menghapus semua teks yang telah dicetak ke konsol di baris sebelumnya (yaitu saya tidak ingin "menghapus" seluruh terminal saat mencetak kemajuan yang diperbarui).

Ini sepertinya tugas yang cukup umum - bagaimana saya bisa membuat progress bar atau visualisasi serupa yang menghasilkan ke konsol saya sambil menjaga keluaran program sebelumnya?

bobber205
sumber
Hmm, terlihat seperti duplikat dari pertanyaan ini yang diajukan kemarin: stackoverflow.com/questions/3160699/python-progress-bar/3162864 Jadi, Anda harus menggunakan fish pypi.python.org/pypi/fish
Etienne
29
"gunakan saja GUI" kesalahpahaman bahwa GUI hebat dalam beberapa situasi (kurva belajar cepat, eksplorasi ad-hoc atau kegiatan interaktif atau sekali saja) sementara alat baris perintah bagus untuk orang lain (pengguna ahli, membuat aplikasi ad-hoc di lalat untuk melakukan operasi yang didefinisikan dengan cermat berkali-kali.)
Jonathan Hartley
14
Saya memilih untuk membuka kembali. Pertanyaan itu tidak membuat saya terlalu luas.
Franck Dernoncourt
Saya pikir apa yang Anda cari adalah tqdm ... walaupun saya juga tidak tahu mengapa SO mendorong saya untuk meninjau kembali suara pada pertanyaan tahun lalu.
kungphu
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:

465

Bilah Kemajuan yang Sederhana dan Dapat Disesuaikan

Berikut adalah agregat dari banyak jawaban di bawah ini yang saya gunakan secara teratur (tidak perlu impor).

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

Catatan: Ini untuk Python 3; lihat komentar untuk detail tentang penggunaan ini di Python 2.

Contoh Penggunaan

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)

Output sampel:

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

Memperbarui

Ada diskusi dalam komentar mengenai opsi yang memungkinkan bilah kemajuan menyesuaikan secara dinamis dengan lebar jendela terminal. Meskipun saya tidak merekomendasikan ini, berikut adalah intinya yang mengimplementasikan fitur ini (dan mencatat peringatan).

Tongkat hijau
sumber
21
Cuplikan ini berfungsi dengan baik! Saya memang menemui beberapa masalah kecil sehingga saya melakukan beberapa pengeditan kecil (PEP-8, penyandian default untuk karakter non-ascii) dan melemparkannya ke intinya di sini: gist.github.com/aubricus/f91fb55dc6ba5557fbab06119420dd6a
Aubricus
3
Perlu dicatat bahwa deklarasi UTF-8 tidak diperlukan kecuali Anda menggunakan Python 2 @Aubricus
Greenstick
2
@MattClimbs Ini ditulis untuk Python 3 yang menggunakan pengkodean UTF-8 secara default. Anda dapat mengubah parameter pengisian default fungsi, yang merupakan karakter UTF-8, atau menggunakan deklarasi UTF-8. Lihat intisari dalam komentar di atas untuk contoh bagaimana deklarasi UTF-8 seharusnya terlihat.
Greenstick
1
Terima kasih, ringkasan yang bagus, juga deteksi ukuran terminal dapat berguna untuk fungsi ini # Size of terminal rows, columns = [int(x) for x in os.popen('stty size', 'r').read().split()] columnsharus diteruskan ke panjang untuk menyesuaikan ukuran bilah kemajuan ke jendela terminal. Meskipun panjang bagian progress bar harus dikurangi (dengan panjang awalan, akhiran, persen dan karakter tambahan dalam string ini'\r%s |%s| %s%% %s'
Arleg
3
Untuk mendapatkan ini untuk bekerja di beberapa IDE (misalnya PyCharm pada Windows) Anda mungkin perlu perubahan end = '\r'untuk end = ''.
thomas88wp
312

Menulis 'r' akan memindahkan kursor kembali ke awal baris.

Ini menampilkan penghitung persentase:

import time
import sys

for i in range(100):
    time.sleep(1)
    sys.stdout.write("\r%d%%" % i)
    sys.stdout.flush()
Stephen
sumber
3
Disisipkan itu dan lari. Ia mencetak ke baris baru setiap kali. Saya ingin nomor tersebut diperbarui pada baris yang sama. :)
bobber205
8
Contoh ini juga menghasilkan OBOB yang akhirnya dimuat di99%
Glenn Dayton
10
@moose Singkatan dari "Off by one bug"
Glenn Dayton
3
printmemiliki endargumen: stackoverflow.com/a/8436827/1959808
Ioannis Filippidis
3
Untuk menambah apa yang dikatakan @Ionisnisfilippidis, printjuga memiliki flushargumen: docs.python.org/3/library/functions.html#print
Wso
113

Tulis \rke konsol. Itu adalah "carriage return" yang menyebabkan semua teks setelahnya digaungkan di awal baris. Sesuatu seperti:

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

yang akan memberi Anda sesuatu seperti: [ ########## ] 100%

aviraldg
sumber
19
Lakukan \rdan kemudian tuliskan seluruh baris lagi. Pada dasarnya:, di print("\rProgress: [{0:50s}] {1:.1f}%".format('#' * int(amtDone * 50), amtDone * 100))mana amtDonefloat antara 0 dan 1.
Mike DeSimone
13
Lebih baik digunakan sys.stdout.writedaripada print. Dengan printsaya mendapat baris baru.
Gill Bates
14
tambahkan koma ,di akhir printkarya untuk saya.
Chunliang Lyu
10
di python3 gunakan print (...., end = '') dan Anda tidak akan memiliki baris baru
graywolf
7
Meringkas untuk mantan Python3 contribs:, di print("\rProgress: [{0:50s}] {1:.1f}%".format('#' * int(workdone * 50), workdone*100), end="", flush=True)mana workdoneadalah float antara 0 dan 1, misalnya,workdone = parsed_dirs/total_dirs
khyox
70

Itu kurang dari 10 baris kode.

Intinya di sini: 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

masukkan deskripsi gambar di sini

Vladimir Ignatyev
sumber
2
menambahkan "sys.stdout.flush ()" ke akhir fungsi.
romruben
bagi saya itu masuk dalam baris baru
GM
@ GM OS / platform apa yang Anda gunakan?
Vladimir Ignatyev
Saya tidak tahu mengapa jika saya menjalankannya dari spyder ide itu tidak berfungsi tetapi jika saya menjalankannya dari ipython console itu berfungsi!
GM
62

Coba klik perpustakaan yang ditulis oleh Mozart dari Python, Armin Ronacher.

$ pip install click # both 2 and 3 compatible

Untuk membuat bilah kemajuan sederhana:

import click

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

Seperti inilah tampilannya:

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

Sesuaikan dengan isi hati Anda:

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

Tampilan ubahsuaian:

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

Bahkan ada lebih banyak opsi, lihat dokumen 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)
Kucing Unfun
sumber
33

Saya menyadari bahwa saya terlambat ke permainan, tapi inilah gaya yang sedikit Yum (Red Hat) yang saya tulis (tidak mencapai akurasi 100% di sini, tetapi jika Anda menggunakan bilah kemajuan untuk tingkat akurasi itu, maka Anda Lagi pula SALAH):

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

Seharusnya menghasilkan sesuatu yang tampak seperti ini:

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

... di mana kurung tetap diam dan hanya hash yang meningkat.

Ini mungkin bekerja lebih baik sebagai dekorator. Untuk hari lain ...

JoeLinux
sumber
2
Solusi hebat! Bekerja dengan sempurna! Terima kasih banyak!
Vasilije Bursac
18

Periksa perpustakaan ini: clint

ia memiliki banyak fitur termasuk bilah kemajuan:

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)

tautan ini menyediakan gambaran umum singkat fitur-fiturnya

skrip
sumber
12

Berikut adalah contoh bagus dari progressbar yang ditulis dengan Python: http://nadiana.com/animated-terminal-progress-bar-in-python

Tetapi jika Anda ingin menulisnya sendiri. Anda dapat menggunakan cursesmodul ini untuk mempermudah :)

[sunting] Mungkin lebih mudah bukan kata kutukan. Tetapi jika Anda ingin membuat cui yang lengkap, kutukan akan mengurus banyak hal untuk Anda.

[Sunting] Karena tautan lama sudah mati saya telah memasang versi saya sendiri dari Python Progressbar, dapatkan di sini: https://github.com/WoLpH/python-progressbar

Wolph
sumber
14
curses? Lebih mudah? Hmmm ....
aviraldg
Artikel yang sangat bagus, saya akan memberikan tautannya tetapi tidak dapat menemukannya di bookmark saya :)
Andy Mikhaylenko
@ Aviral Dasgupta: cukup adil, lebih mudah mungkin bukan kata yang tepat di sini. Ini bisa menghemat banyak pekerjaan, tetapi itu benar-benar tergantung pada apa yang Anda cari.
Wolph
Tidak mencari apa pun di dekat ini terlibat, tetapi terima kasih pula. :)
bobber205
2
Tautan mati, itulah harga untuk tidak memposting konten tautan dalam jawaban Anda -__-
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()

keluaran

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

ashish2py
sumber
7

dan, hanya untuk menambah tumpukan, inilah objek yang bisa Anda gunakan

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"

menghasilkan:

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

Ini paling sering dianggap "di atas", tetapi sangat berguna ketika Anda sering menggunakannya

FraggaMuffin
sumber
Terima kasih untuk ini. Perbaikan kecil, metode plotProgress harus menggunakan baris sys.stdout.flush () kalau tidak progress bar tidak dapat ditarik sampai tugas telah selesai (seperti yang terjadi di terminal mac).
osnoz
Aku suka ini!!! Cukup mudah digunakan !!! Terima kasih
Mikro
7

Instal tqdm. ( pip install tqdm) Dan gunakan sebagai berikut:

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

Itu bilah kemajuan 10 detik yang akan menampilkan sesuatu seperti ini:

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

Jalankan ini di baris perintah Python ( bukan di lingkungan IDE atau pengembangan apa pun):

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

Bekerja dengan baik pada sistem Windows saya.

PaulMcG
sumber
4

Saya menggunakan progres dari reddit . Saya suka karena dapat mencetak kemajuan untuk setiap item dalam satu baris, dan itu tidak harus menghapus cetakan dari program.

Edit: tautan tetap

Ib33X
sumber
1
Tautan Anda rusak - baris sebenarnya dalam kode sumber adalah 1274, bukan 1124! Jadi, tautan yang benar adalah ini: github.com/reddit/reddit/blob/master/r2/r2/lib/utils/…
Vladimir Ignatyev
Varian ini memiliki desain terbaik sesuai selera saya: ia menggunakan iterator dan bekerja mungkin dengan segala jenis pekerjaan yang terukur, ini menunjukkan waktu yang telah berlalu.
Vladimir Ignatyev
4

Coba instal paket ini 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
sumber
3

berdasarkan jawaban di atas dan pertanyaan serupa lainnya tentang progress bar CLI, saya pikir saya mendapat jawaban umum yang umum untuk semuanya. Periksa di https://stackoverflow.com/a/15860757/2254146

Singkatnya, kodenya adalah ini:

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

Seperti

Persen: [##########] 99.0%

Brian Khuu
sumber
3

Saya sarankan menggunakan tqdm - https://pypi.python.org/pypi/tqdm - yang membuatnya mudah untuk mengubah setiap iterable atau proses menjadi bilah kemajuan, dan menangani semua masalah dengan terminal yang dibutuhkan.

Dari dokumentasi: "tqdm dapat dengan mudah mendukung panggilan balik / pengait dan pembaruan manual. Inilah contoh dengan 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)
Kotak Malcolm
sumber
3

Solusi yang sangat sederhana adalah dengan memasukkan kode ini ke loop Anda:

Letakkan ini di badan (yaitu bagian atas) dari file Anda:

import sys

Letakkan ini di badan loop Anda:

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

progressbar()

CATATAN: jika Anda menjalankan ini dalam interepter interaktif Anda mendapatkan nomor tambahan yang dicetak

Ramchandra Apte
sumber
2

lol saya hanya menulis semuanya untuk ini, ini kode yang perlu diingat Anda tidak dapat menggunakan unicode ketika melakukan blok ascii saya menggunakan 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()

dan Anda menyebutnya seperti itu

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

jadi terlihat seperti ini

loading something awesome
|█████     |
ryan
sumber
2

Dengan saran hebat di atas, saya mengerjakan bilah kemajuan.

Namun saya ingin menunjukkan beberapa kekurangan

  1. Setiap kali progress bar memerah, itu akan mulai pada baris baru

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

    seperti ini:
    [] 0%
    [#] 10%
    [##] 20%
    [###] 30%

2. kurung siku ']' dan angka persen di sisi kanan bergeser ke kanan saat '###' bertambah panjang.
3. Kesalahan akan terjadi jika ekspresi 'progress / 10' tidak dapat mengembalikan integer.

Dan kode berikut akan memperbaiki masalah di atas.

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

Kode untuk bilah progres terminal python

import sys
import time

max_length = 5
at_length = max_length
empty = "-"
used = "%"

bar = empty * max_length

for i in range(0, max_length):
    at_length -= 1

    #setting empty and full spots
    bar = used * i
    bar = bar+empty * at_length

    #\r is carriage return(sets cursor position in terminal to start of line)
    #\0 character escape

    sys.stdout.write("[{}]\0\r".format(bar))
    sys.stdout.flush()

    #do your stuff here instead of time.sleep
    time.sleep(1)

sys.stdout.write("\n")
sys.stdout.flush()
emd_22
sumber
1

saya menulis progressbar sederhana:

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)

seperti yang Anda lihat, ada: panjang bilah, awalan dan akhiran, pengisi, spasi, teks dalam bilah pada 100% (oncomp) dan batas

berikut sebuah contoh:

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)

sedang dalam proses:

30% [######              ]

keluar lengkap:

100% [   done in 9 sec   ] 
Jenkins
sumber
1

Menyusun beberapa ide yang saya temukan di sini, dan menambahkan perkiraan waktu yang tersisa:

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
sumber
1

Untuk 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
sumber
0

Nah berikut ini adalah kode yang berfungsi dan saya mengujinya sebelum memposting:

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

Pro:

  • 20 bar karakter (1 karakter untuk setiap 5 (angka bijaksana))
  • Karakter isian khusus
  • Karakter kosong khusus
  • Berhenti (angka berapa pun di bawah 0)
  • Selesai (100 dan angka berapa pun di atas 100)
  • Hitungan kemajuan (0-100 (di bawah dan di atas digunakan untuk fungsi khusus))
  • Persentase angka di sebelah bilah, dan itu adalah satu baris

Cons:

  • Hanya mendukung bilangan bulat (Itu dapat dimodifikasi untuk mendukungnya, dengan membuat divisi menjadi bilangan bulat, jadi ubah saja prog2 = prog/5menjadi prog2 = int(prog/5))
Cold Diamondz
sumber
0

Inilah solusi Python 3 saya:

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

'\ b' adalah garis miring terbalik, untuk setiap karakter dalam string Anda. Ini tidak berfungsi di dalam jendela cmd Windows.

Matt-the-Bat
sumber
0

fungsi dari Greenstick untuk 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
sumber
0

Modul python progressbar adalah pilihan yang bagus. Ini kode khas saya:

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
sumber