Thanh tiến trình văn bản trong bảng điều khiển [đã đóng]


435

Tôi đã viết một ứng dụng bảng điều khiển đơn giản để tải lên và tải xuống các tệp từ máy chủ FTP bằng cách sử dụng ftplib.

Tôi muốn ứng dụng hiển thị một số hình ảnh về tiến trình tải xuống / tải lên của nó cho người dùng; mỗi khi một đoạn dữ liệu được tải xuống, tôi muốn nó cung cấp một bản cập nhật tiến độ, ngay cả khi đó chỉ là một biểu diễn số như tỷ lệ phần trăm.

Điều quan trọng, tôi muốn tránh xóa tất cả văn bản đã được in ra bàn điều khiển trong các dòng trước đó (nghĩa là tôi không muốn "xóa" toàn bộ thiết bị đầu cuối trong khi in tiến trình cập nhật).

Đây có vẻ là một nhiệm vụ khá phổ biến - làm cách nào tôi có thể tạo một thanh tiến trình hoặc trực quan hóa tương tự xuất ra bảng điều khiển của mình trong khi duy trì đầu ra chương trình trước đó?


Hmm, trông giống như một bản sao của câu hỏi này đã được hỏi ngày hôm qua: stackoverflow.com/questions/3160699/python-proTHER-bar/3162864 Vì vậy, bạn nên sử dụng cá pypi.python.org/pypi/fish
Etienne

29
"chỉ sử dụng GUI" hiểu nhầm rằng GUI rất tuyệt vời trong một số trường hợp (đường cong học nhanh, hoạt động khám phá hoặc hoạt động tương tác hoặc hoạt động một lần) trong khi các công cụ dòng lệnh rất tốt cho những người khác (người dùng chuyên gia, soạn ứng dụng ad-hoc con ruồi thực hiện một thao tác được xác định cẩn thận nhiều lần.)
Jonathan Hartley

14
Tôi đã bỏ phiếu để mở lại. Câu hỏi không đánh tôi là quá rộng.
Franck Dernoncourt

Tôi nghĩ những gì bạn đang tìm kiếm là tqdm ... mặc dù tôi cũng không biết tại sao SO lại khiến tôi phải xem lại việc mở lại phiếu bầu cho các câu hỏi cũ.
kungphu

Tôi đã xuất bản một loại thanh tiến trình mới, mà bạn có thể in, xem thông lượng và eta, thậm chí tạm dừng nó, bên cạnh các hình ảnh động rất tuyệt! Xin hãy xem: github.com/rsalmei/alive-proceed ! sống tiến bộ
rsalmei

Câu trả lời:


464

Một thanh tiến trình đơn giản, có thể tùy chỉnh

Đây là tổng hợp của nhiều câu trả lời dưới đây mà tôi sử dụng thường xuyên (không yêu cầu nhập khẩu).

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

Lưu ý: Đây là cho Python 3; xem các bình luận để biết chi tiết về cách sử dụng này trong Python 2.

Sử dụng mẫu

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)

Đầu ra mẫu:

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

Cập nhật

Đã có thảo luận trong các ý kiến ​​liên quan đến một tùy chọn cho phép thanh tiến trình điều chỉnh linh hoạt theo chiều rộng cửa sổ đầu cuối. Mặc dù tôi không khuyến nghị điều này, đây là một ý chính thực hiện tính năng này (và lưu ý các cảnh báo).


21
Đoạn trích này hoạt động rất tốt! Tôi đã gặp một vấn đề nhỏ vài vì vậy tôi thực hiện một số sửa đổi nhỏ (PEP-8, mã hóa mặc định cho nhân vật phi ascii) và ném chúng vào một ý chính ở đây: gist.github.com/aubricus/f91fb55dc6ba5557fbab06119420dd6a
Aubricus

3
Đáng lưu ý rằng khai báo UTF-8 là không cần thiết trừ khi bạn sử dụng Python 2 @Aubricus
Greenstick

2
@MattClimbs Điều này được viết cho Python 3 sử dụng mã hóa UTF-8 theo mặc định. Bạn có thể thay đổi tham số điền mặc định của hàm, đó là ký tự UTF-8 hoặc sử dụng khai báo UTF-8. Xem ý chính trong bình luận ở trên để biết ví dụ về cách khai báo UTF-8 sẽ như thế nào.
Greenstick

1
Cảm ơn, tóm tắt hay, cũng phát hiện kích thước thiết bị đầu cuối có thể hữu ích cho chức năng này # Size of terminal rows, columns = [int(x) for x in os.popen('stty size', 'r').read().split()] columnsnên được chuyển theo chiều dài để điều chỉnh kích thước thanh tiến trình cho cửa sổ đầu cuối. Mặc dù độ dài của phần tiến trình của thanh nên được giảm (theo độ dài của tiền tố, hậu tố, phần trăm và các ký tự bổ sung trong chuỗi này'\r%s |%s| %s%% %s'
Arleg 11/11/19

3
Để làm việc này trong một số IDE (ví dụ PyCharm trên Windows), bạn có thể cần phải thay đổi end = '\r'thành end = ''.
thomas88wp

312

Viết '\ r' sẽ di chuyển con trỏ trở lại đầu dòng.

Điều này sẽ hiển thị một bộ đếm phần trăm:

import time
import sys

for i in range(100):
    time.sleep(1)
    sys.stdout.write("\r%d%%" % i)
    sys.stdout.flush()

3
Dán nó và chạy. Nó in ra một dòng mới mỗi lần. Tôi muốn số được cập nhật trên cùng một dòng. :)
bobber205

8
Ví dụ này cũng tạo ra một OBOB mà nó kết thúc tải tại99%
Glenn Dayton

10
@moose Nó là viết tắt của "Tắt bởi một lỗi"
Glenn Dayton

3
printcó một endđối số: stackoverflow.com/a/8436827/1959808
Ioannis Filippidis

3
Để thêm vào những gì @IoannisFilippidis nói, printcũng có một flushlập luận: docs.python.org/3/library/functions.html#print
WSO


113

Viết một cái \rcho bàn điều khiển. Đó là một "trở về vận chuyển" làm cho tất cả các văn bản sau nó được lặp lại ở đầu dòng. Cái gì đó như:

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

sẽ cung cấp cho bạn một cái gì đó như: [ ########## ] 100%


19
Làm \rvà sau đó viết toàn bộ dòng ra một lần nữa. Về cơ bản : print("\rProgress: [{0:50s}] {1:.1f}%".format('#' * int(amtDone * 50), amtDone * 100)), đâu amtDonelà số float giữa 0 và 1.
Mike DeSimone

13
Sử dụng sys.stdout.writetốt hơn print. Với printtôi có tin mới.
Gill Bates

14
viết thêm dấu phẩy ,vào cuối printtác phẩm cho tôi.
Chunliang Lyu

10
trong python3 sử dụng in (...., end = '') và bạn sẽ không có bất kỳ dòng mới nào
Graywolf

7
Tóm tắt cho các đóng góp cũ của Python3 : print("\rProgress: [{0:50s}] {1:.1f}%".format('#' * int(workdone * 50), workdone*100), end="", flush=True), trong đó workdonenổi giữa 0 và 1, ví dụ:workdone = parsed_dirs/total_dirs
khyox

70

Nó là ít hơn 10 dòng mã.

Ý chính ở đây: 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

nhập mô tả hình ảnh ở đây


2
thêm "sys.stdout.flush ()" vào cuối hàm.
romruben 7/07/2015

đối với tôi nó đi theo một dòng mới
GM

@GM bạn sử dụng hệ điều hành / nền tảng nào?
Vladimir Ignatyev

Tôi không biết tại sao nếu tôi chạy nó từ ide spyder thì nó không hoạt động nhưng nếu tôi chạy nó từ bảng điều khiển ipython thì nó hoạt động!
GM

62

Hãy thử thư viện nhấp chuột được viết bởi Mozart of Python, Armin Ronacher.

$ pip install click # both 2 and 3 compatible

Để tạo một thanh tiến trình đơn giản:

import click

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

Đây là những gì nó trông giống như:

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

Tùy chỉnh nội dung trái tim của bạn:

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

Giao diện tùy chỉnh:

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

Thậm chí còn có nhiều tùy chọn hơn, xem tài liệu 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)

33

Tôi nhận ra rằng tôi đã trễ trò chơi, nhưng đây là một kiểu hơi Yum (Mũ đỏ) mà tôi đã viết (sẽ không chính xác 100% ở đây, nhưng nếu bạn đang sử dụng thanh tiến trình cho mức độ chính xác đó, thì bạn dù sao cũng SAU):

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

Nên tạo ra một cái gì đó trông như thế này:

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

... Trong đó dấu ngoặc đứng yên và chỉ có giá trị băm tăng.

Điều này có thể làm việc tốt hơn như là một trang trí. Vào một ngày khác...


2
Giải pháp tuyệt vời! Hoạt động hoàn hảo! Cảm ơn rât nhiều!
Vasilije Bursac

18

Kiểm tra thư viện này: clint

nó có rất nhiều tính năng bao gồm một thanh tiến trình:

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)

liên kết này cung cấp một cái nhìn tổng quan nhanh về các tính năng của nó


12

Đây là một ví dụ hay về thanh tiến trình được viết bằng Python: http://nadiana.com/animated-terminal-proTHER-bar-in-python

Nhưng nếu bạn muốn tự viết nó. Bạn có thể sử dụng cursesmô-đun để làm cho mọi thứ dễ dàng hơn :)

[sửa] Có lẽ dễ dàng hơn không phải là từ để nguyền rủa. Nhưng nếu bạn muốn tạo ra một cui đầy đủ hơn những lời nguyền thì sẽ chăm sóc rất nhiều thứ cho bạn.

[sửa] Vì liên kết cũ đã chết, tôi đã đưa ra phiên bản Python Progressbar của riêng mình, hãy truy cập vào đây: https://github.com/WoLpH/python-proTHERbar


14
curses? Dễ dàng hơn? Hmmm ....
aviraldg

Một bài viết tuyệt vời, tôi sẽ cung cấp một liên kết đến nó nhưng không thể tìm thấy trong dấu trang của tôi :)
Andy Mikhaylenko

@Avirus Dasgupta: đủ công bằng, dễ dàng hơn có thể không phải là từ đúng ở đây. Nó có thể giúp bạn tiết kiệm rất nhiều công việc, nhưng nó thực sự phụ thuộc vào những gì bạn đang tìm kiếm.
Wolph

Không tìm kiếm bất cứ điều gì gần này liên quan, nhưng dù sao cũng cảm ơn. :)
bobber205

2
Liên kết chết, đó là giá của việc không đăng nội dung liên kết trong câu trả lời của bạn -__-
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()

đầu ra

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


7

và, chỉ để thêm vào đống, đây là một đối tượng bạn có thể sử dụng

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"

kết quả trong:

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

Điều này thường được coi là "trên hết", nhưng nó rất tiện lợi khi bạn sử dụng nó nhiều


Cám ơn vì cái này. Khắc phục nhỏ, phương thức cốt truyện nên sử dụng dòng sys.stdout.flush () nếu không thanh rút tiến trình có thể không được vẽ cho đến khi tác vụ được hoàn thành (như xảy ra trong thiết bị đầu cuối mac).
osnoz

Tôi thích điều này !!! Khá dễ sử dụng !!! Thankyou
Microos

7

Cài đặt tqdm. ( pip install tqdm) Và sử dụng nó như sau:

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

Đó là thanh tiến trình 10 giây sẽ tạo ra thứ gì đó như thế này:

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

6

Chạy lệnh này tại dòng lệnh Python ( không phải trong bất kỳ môi trường IDE hoặc môi trường phát triển nào):

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

Hoạt động tốt trên hệ thống Windows của tôi.



4

Tôi đang sử dụng tiến trình từ reddit . Tôi thích nó bởi vì nó có thể in tiến trình cho mọi mục trong một dòng và nó không nên xóa các bản in ra khỏi chương trình.

Chỉnh sửa: liên kết cố định


1
Liên kết của bạn bị hỏng - dòng thực tế trong mã nguồn là 1274, không phải là 1124! Vì vậy, liên kết bên phải là liên kết này: github.com/reddit/reddit/blob/master/r2/r2/lib/utils/ trộm
Vladimir Ignatyev

Biến thể này có thiết kế tốt nhất theo sở thích của tôi: nó sử dụng các trình vòng lặp và hoạt động có thể với bất kỳ loại công việc có thể đo lường nào, nó cho thấy thời gian trôi qua.
Vladimir Ignatyev

3

dựa trên các câu trả lời ở trên và các câu hỏi tương tự khác về thanh tiến trình CLI, tôi nghĩ rằng tôi đã có một câu trả lời chung cho tất cả chúng. Kiểm tra nó tại https://stackoverflow.com/a/15860757/2254146

Tóm lại, mã này là:

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

Giống như

Phần trăm: [##########] 99,0%


3

Tôi khuyên bạn nên sử dụng tqdm - https://pypi.python.org/pypi/tqdm - điều này giúp đơn giản để biến bất kỳ lần lặp hoặc xử lý nào thành một thanh tiến trình và xử lý tất cả các lỗi lộn xộn với các thiết bị đầu cuối cần thiết.

Từ tài liệu: "tqdm có thể dễ dàng hỗ trợ các cuộc gọi lại / hook và cập nhật thủ công. Đây là một ví dụ với 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)


3

Một giải pháp rất đơn giản là đặt mã này vào vòng lặp của bạn:

Đặt phần này vào phần thân (tức là trên cùng) của tệp của bạn:

import sys

Đặt cái này trong phần thân của vòng lặp của bạn:

sys.stdout.write("-") # prints a dash for each iteration of loop
sys.stdout.flush() # ensures bar is displayed incrementally

2
import sys
def progresssbar():
         for i in range(100):
            time.sleep(1)
            sys.stdout.write("%i\r" % i)

progressbar()

LƯU Ý: nếu bạn chạy cái này trong bộ tương tác, bạn sẽ nhận được thêm số


2

lol tôi chỉ viết toàn bộ điều này cho mã này, hãy nhớ rằng bạn không thể sử dụng unicode khi thực hiện chặn ascii tôi sử dụng 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()

và bạn gọi nó như vậy

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

nó trông như thế này

loading something awesome
|█████     |

2

Với những lời khuyên tuyệt vời ở trên, tôi tìm ra thanh tiến trình.

Tuy nhiên tôi muốn chỉ ra một số thiếu sót

  1. Mỗi khi thanh tiến trình được tuôn ra, nó sẽ bắt đầu trên một dòng mới

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

    như thế này:
    [] 0%
    [#] 10%
    [##] 20%
    [###] 30%

2. Dấu ngoặc vuông ']' và số phần trăm ở bên phải dịch chuyển sang phải khi '###' dài hơn.
3. Một lỗi sẽ xảy ra nếu biểu thức 'tiến trình / 10' không thể trả về một số nguyên.

Và đoạn mã sau sẽ khắc phục vấn đề trên.

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

1

Mã cho thanh tiến trình thiết bị đầu cuối 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()

1

tôi đã viết một thanh tiến trình đơn giản:

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)

như bạn có thể thấy, nó có: chiều dài của thanh, tiền tố và hậu tố, phụ, khoảng trắng, văn bản trong thanh trên 100% (oncomp) và viền

đây là một ví dụ:

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)

trong tiến trình:

30% [######              ]

hoàn thành

100% [   done in 9 sec   ] 

1

Tổng hợp một số ý tưởng tôi tìm thấy ở đây và thêm thời gian ước tính còn lại:

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)

1

Đối với trăn 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 "")

0

Đây là mã hoạt động và tôi đã kiểm tra nó trước khi đăng:

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

Ưu điểm:

  • Thanh 20 ký tự (1 ký tự cho mỗi 5 (số khôn ngoan))
  • Nhân vật điền tùy chỉnh
  • Ký tự trống tùy chỉnh
  • Dừng lại (bất kỳ số nào dưới 0)
  • Xong (100 và bất kỳ số nào trên 100)
  • đếm Progress (0-100 (sau đây trở lên sử dụng cho các chức năng đặc biệt))
  • Số phần trăm bên cạnh thanh và đó là một dòng duy nhất

Nhược điểm:

  • Chỉ hỗ trợ số nguyên (Nó có thể được sửa đổi để hỗ trợ chúng, bằng cách làm cho phép chia thành một số nguyên, vì vậy chỉ cần thay đổi prog2 = prog/5thành prog2 = int(prog/5))

0

Đây là giải pháp Python 3 của tôi:

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

'\ b' là dấu gạch chéo ngược, cho mỗi ký tự trong chuỗi của bạn. Điều này không hoạt động trong cửa sổ cmd Windows.


0

chức năng từ Greenstick cho 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()

0

Thanh tiến trình mô-đun python là một lựa chọn tốt. Đây là mã tiêu biểu của tôi:

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()
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.