以下のようなステータスバーを実装するには:
[========== ] 45%
[================ ] 60%
[==========================] 100%
これをstdoutに出力し、別の行に出力するのではなく、更新し続けたいです。これを行う方法?
以下のようなステータスバーを実装するには:
[========== ] 45%
[================ ] 60%
[==========================] 100%
これをstdoutに出力し、別の行に出力するのではなく、更新し続けたいです。これを行う方法?
回答:
Pythonモジュールは、あなたから得ることができることがありますは、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 progressbar、pipを使用します。
bar.start()ですか?
bar.start()
sudo -H pip install progressbar2。
'\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で動作します。
n=21、交換するrange(21)とrange(n)、その後、追加j = (i + 1) / nループ内、および交換するwriteこのわずかな変更で声明を:sys.stdout.write("[%-20s] %d%%" % ('='*int(20*j), 100*j))。ここで行う必要がある唯一の変更はn=21、ループの前に(より可能性が高いn=len(iterable))、次に反復可能オブジェクトを列挙することです。この編集を推奨しましたが、拒否されました。明らかに機能性は「投稿の本来の意図から逸脱している」。
sys.stdout.write("[{:{}}] {:.1f}%".format("="*i, n-1, (100/(n-1)*i)))
私は有用なライブラリ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 イテラブルをラップできます。
\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()
totalとして試してみると10、エラーメッセージが表示されますZeroDivisionError: long division or modulo by zero
ここでは、次のコードを関数として使用できます。
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()
] percent * 100 %
上記の回答と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%
コマンドラインインターフェイスを開発している場合は、clickどれが非常に優れているかを確認することをお勧めします。
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)
ここであなたが得る出力:
$ python test.py
[====================================] 100%
[====================================] 100%
[========= ] 27%
関数を次のように使用してさらに改善します:
import sys
def printProgressBar(i,max,postText):
n_bar =10 #size of progress bar
j= i/max
sys.stdout.write('\r')
sys.stdout.write(f"[{'=' * int(n_bar * j):{n_bar}s}] {int(100 * j)}% {postText}")
sys.stdout.flush()
呼び出し例:
total=33
for i in range(total):
printProgressBar(i,total,"blah")
sleep(0.05)
出力:
[================================================ ] 96% blah
私は今日このスレッドに出くわし、マーク・ルシャコフからこの解決策を試した後
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)
これは、Python 3.4.3 64ビットのW7-64で正常に機能すると言えますが、ネイティブコンソールでのみ機能します。ただし、spyder 3.0.0devの組み込みコンソールを使用する場合、改行がまだ存在します。これには少し時間がかかったので、ここでこの観察を報告したいと思います。
ここや他の場所でいくつかの答えに基づいて、進行状況バーと経過時間/推定残り時間を表示するこの簡単な関数を作成しました。ほとんどのUNIXベースのマシンで動作するはずです。
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
これは非常にシンプルなアプローチで、どのループでも使用できます。
#!/usr/bin/python
for i in range(100001):
s = ((i/5000)*'#')+str(i)+(' %')
print ('\r'+s),
Mark Rushakoffのソリューションで説明されているように、キャリッジリターン文字を出力してsys.stdout.write('\r')、カーソルを行の先頭にリセットできます。そのソリューションを一般化するには、Python 3のf-Stringsも実装しながら、次を使用できます。
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
PyProgを試してください。PyProgは、Pythonのオープンソースライブラリで、超カスタマイズ可能な進行状況インジケーターとバーを作成します。
現在バージョン1.0.2です。Githubでホストされ、PyPIで利用できます(下のリンク)。Python 3および2と互換性があり、Qt Consoleでも使用できます。
とても使いやすいです。次のコード:
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()
あなたが望むものを正確に生成します(バーの長さも!):
[=========== ] 45%
[=============== ] 60%
[==========================] 100%
進行状況バーをカスタマイズするその他のオプションについては、このWebサイトのGithubページにアクセスしてください。
シンプルだが非常にカスタマイズ可能なプログレスバーライブラリが必要だったので、実際にPyProgを作成しました。簡単にインストールできますpip install pyprog。
PyProg Github:https : //github.com/Bill13579/pyprog
PyPI:https ://pypi.python.org/pypi/pyprog/
@ Mark-Rushakoffの回答を使用して、sysライブラリを呼び出す必要がない、より簡単な方法を考え出しました。Python 3で動作します。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)
@ Mark-Rushakoffのソリューションを使用して作成したものを以下に示します。端子幅に適応的に調整します。
from time import sleep
import os
import sys
from math import ceil
l = list(map(int,os.popen('stty size','r').read().split()))
col = l[1]
col = col - 6
for i in range(col):
sys.stdout.write('\r')
getStr = "[%s " % ('='*i)
sys.stdout.write(getStr.ljust(col)+"]"+"%d%%" % (ceil((100/col)*i)))
sys.stdout.flush()
sleep(0.25)
print("")