development

상태 표시 줄 및 백분율을 인쇄하는 Python

big-blog 2020. 6. 24. 07:07
반응형

상태 표시 줄 및 백분율을 인쇄하는 Python


아래와 같이 상태 표시 줄을 구현하려면

[==========                ]  45%
[================          ]  60%
[==========================] 100%

이것을 stdout으로 인쇄하고 다른 줄로 인쇄하지 않고 새로 고치기를 원합니다. 이것을하는 방법?


당신이에서 얻을 수있는 파이썬 모듈있다 PyPI 라는 progressbar구현 이러한 기능 그게. 의존성을 추가하는 것이 마음에 들지 않으면 좋은 해결책입니다. 그렇지 않으면 다른 답변 중 하나와 함께 가십시오.

사용 방법에 대한 간단한 예 :

import progressbar
from time import sleep
bar = progressbar.ProgressBar(maxval=20, \
    widgets=[progressbar.Bar('=', '[', ']'), ' ', progressbar.Percentage()])
bar.start()
for i in xrange(20):
    bar.update(i+1)
    sleep(0.1)
bar.finish()

설치하려면을 사용 easy_install progressbar하거나 pip install progressbarpip를 선호하는 경우 사용할 수 있습니다 .


'\r'문자 (캐리지 리턴) 라인의 시작 부분으로 커서를 재설정하고 줄에 이전에 무슨 이상 작성할 수 있습니다.

from time import sleep
import sys

for i in range(21):
    sys.stdout.write('\r')
    # the exact output you're looking for:
    sys.stdout.write("[%-20s] %d%%" % ('='*i, 5*i))
    sys.stdout.flush()
    sleep(0.25)

이것이 모든 시스템에서 완전히 이식 가능한지 100 % 확신하지는 못하지만 적어도 Linux 및 OSX에서 작동합니다.


유용한 라이브러리 tqdm ( https://github.com/tqdm/tqdm/ , 이전에는 https://github.com/noamraph/tqdm )을 찾았습니다 . 완료 시간을 자동으로 추정하여 반복자로 사용할 수 있습니다.

용법:

import tqdm
import time

for i in tqdm.tqdm(range(1000)):
    time.sleep(0.01)
    # or other long operations

결과 :

|####------| 450/1000  45% [elapsed: 00:04 left: 00:05, 99.15 iters/sec]

tqdm iterable을 감쌀 수 있습니다.


\r( 캐리지 리턴 )을 사용할 수 있습니다 . 데모:

import sys
total = 10000000
point = total / 100
increment = total / 20
for i in xrange(total):
    if(i % (5 * point) == 0):
        sys.stdout.write("\r[" + "=" * (i / increment) +  " " * ((total - i)/ increment) + "]" +  str(i / point) + "%")
        sys.stdout.flush()

다음 코드를 함수로 사용할 수 있습니다.

def drawProgressBar(percent, barLen = 20):
    sys.stdout.write("\r")
    progress = ""
    for i in range(barLen):
        if i < int(barLen * percent):
            progress += "="
        else:
            progress += " "
    sys.stdout.write("[ %s ] %.2f%%" % (progress, percent * 100))
    sys.stdout.flush()

.format을 사용하는 경우 :

def drawProgressBar(percent, barLen = 20):
    # percent float from 0 to 1. 
    sys.stdout.write("\r")
    sys.stdout.write("[{:<{}}] {:.0f}%".format("=" * int(barLen * percent), barLen, percent * 100))
    sys.stdout.flush()

위의 답변과 CLI 진행률 표시 줄에 대한 다른 유사한 질문을 바탕으로, 나는 그들 모두에게 일반적인 공통 답변을 얻었습니다. https://stackoverflow.com/a/15860757/2254146 에서 확인 하십시오.

다음은 함수의 복사본이지만 스타일에 맞게 수정되었습니다.

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

처럼 보인다

퍼센트 : [====================] 99.0 %


오늘이 스레드에 왔으며 Mark Rushakoff 에서이 솔루션을 시도한 후

from time import sleep
import sys

for i in range(21):
sys.stdout.write('\r')
# the exact output you're looking for:
sys.stdout.write("[%-20s] %d%%" % ('='*i, 5*i))
sys.stdout.flush()
sleep(0.25)

I can say that this works fine on W7-64 with python 3.4.3 64-bit but only in the native console. However when using the built-in console of spyder 3.0.0dev, the line breaks are still/again present. As this took me some time to figure out, I'd like to report this observation here.


If you are developing a command line interface, I suggest you to take a look at click which is very nice:

import click
import time

for filename in range(3):
    with click.progressbar(range(100), fill_char='=', empty_char=' ') as bar:
        for user in bar:
            time.sleep(0.01)

Here the output you get:

$ python test.py
  [====================================]  100%
  [====================================]  100%
  [=========                           ]   27%

Building on some of the answers here and elsewhere, I've written this simple function which displays a progress bar and elapsed/estimated remaining time. Should work on most unix-based machines.

import time
import sys

percent = 50.0
start = time.time()
draw_progress_bar(percent, start)


def draw_progress_bar(percent, start, barLen=20):
sys.stdout.write("\r")
progress = ""
for i in range(barLen):
    if i < int(barLen * percent):
        progress += "="
    else:
        progress += " "

elapsedTime = time.time() - start;
estimatedRemaining = int(elapsedTime * (1.0/percent) - elapsedTime)

if (percent == 1.0):
    sys.stdout.write("[ %s ] %.1f%% Elapsed: %im %02is ETA: Done!\n" % 
        (progress, percent * 100, int(elapsedTime)/60, int(elapsedTime)%60))
    sys.stdout.flush()
    return
else:
    sys.stdout.write("[ %s ] %.1f%% Elapsed: %im %02is ETA: %im%02is " % 
        (progress, percent * 100, int(elapsedTime)/60, int(elapsedTime)%60,
         estimatedRemaining/60, estimatedRemaining%60))
    sys.stdout.flush()
    return

This is quite a simple approach can be used with any loop.

#!/usr/bin/python
for i in range(100001):
    s =  ((i/5000)*'#')+str(i)+(' %')
    print ('\r'+s),

Easiest is still

import sys
total_records = 1000
for i in range (total_records):
    sys.stdout.write('\rUpdated record: ' + str(i) + ' of ' + str(total_records))
    sys.stdout.flush()

Key is to convert the integer type to string.


Try PyProg. PyProg is an open-source library for Python to create super customizable progress indicators & bars.

It is currently at version 1.0.2; it is hosted on Github and available on PyPI (Links down below). It is compatible with Python 3 & 2 and it can also be used with Qt Console.

It is really easy to use. The following code:

import pyprog
from time import sleep

# Create Object
prog = pyprog.ProgressBar(" ", " ", total=34, bar_length=26, complete_symbol="=", not_complete_symbol=" ", wrap_bar_prefix=" [", wrap_bar_suffix="] ", progress_explain="", progress_loc=pyprog.ProgressBar.PROGRESS_LOC_END)
# 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()

will produce exactly what you want (even the bar length!):

[===========               ] 45%
[===============           ] 60%
[==========================] 100%

For more options to customize the progress bar, go to the Github page of this website.

I actually made PyProg because I needed a simple but super customizable progress bar library. You can easily install it with: pip install pyprog.

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


Using @Mark-Rushakoff answer, I worked out a simpler approach, no need to call the sys library. It works with Python 3. Tested in Windows:

from time import sleep
for i in range(21):
    # the exact output you're looking for:
    print ("\r[%-20s] %d%%" % ('='*i, 5*i), end='')
    sleep(0.25)

As described in Mark Rushakoff's solution, you can output the carriage return character, sys.stdout.write('\r'), to reset the cursor to the beginning of the line. To generalize that solution, while also implementing Python 3's f-Strings, you could use

from time import sleep
import sys

n_bar = 50
iterable = range(33)  # for demo purposes
n_iter = len(iterable)
for i, item in enumerate(iterable):
    j = (i + 1) / n_iter

    sys.stdout.write('\r')
    sys.stdout.write(f"[{'=' * int(n_bar * j):{n_bar}s}] {int(100 * j)}%")
    sys.stdout.flush()

    sleep(0.05)  
    # do something with <item> here

참고URL : https://stackoverflow.com/questions/3002085/python-to-print-out-status-bar-and-percentage

반응형