pythonで小さなコマンドラインゲームに取り組んでいます。tqdmモジュールを使用してプログレスバーを表示しています。msvcrtモジュールを使用してユーザー入力をリッスンし、進行を中断します。中断したら、ユーザーはコマンドラインプロンプトに「restart」と入力して再起動できます。進行状況バーが2回表示されると、進行状況で同じ行を更新する代わりに、毎回新しい行を作成します。
同じように進行状況を表示するにはどうすればよいですか?
このコードスニペットは、進行状況バーの使用方法を示しています。
def transfer():
for i in tqdm.tqdm(range(1000), desc="Transfer progress", ncols=100, bar_format='{l_bar}{bar}|'):
sleep(.1)
if msvcrt.kbhit():
if msvcrt.getwche() == ' ':
interrupt()
break
def interrupt():
type("File transfer interrupted, to restart the transfer, type 'restart'")
position=0
とleave=True
でお試しください
(ソリューションはGoogle Colabで動作し、改行を出力しないようにします)
from tqdm import tqdm
import time
def foo_():
time.sleep(0.3)
range_ = range(0, 10)
total = len(range_)
with tqdm(total=total, position=0, leave=True) as pbar:
for i in tqdm((foo_, range_ ), position=0, leave=True):
pbar.update()
標準のprint()
の代わりに_tqdm.tqdm.write
_を使用してみてください
これにより、進行状況バーの上に印刷され、進行状況バーが1行下に移動します。
以下のコードを使用してこれをテストしました。space
を押すとstdoutに出力されますが、ループは中断しません。あなたのinterrupt()
関数は提供された文字列の型をチェックするだけなので、何を達成しようとしているのかは100%明確ではありませんでした。 type()組み込み関数
_import tqdm
import msvcrt
from time import sleep
def transfer():
for i in tqdm.tqdm(range(1000), desc="Transfer progress", ncols=100, bar_format='{l_bar}{bar}|'):
sleep(.1)
if msvcrt.kbhit():
if msvcrt.getwche() == ' ':
interrupt()
# break
def interrupt():
tqdm.tqdm.write("File transfer interrupted, to restart the transfer, type 'restart'", end="")
transfer()
_
編集:Paul Netherwoodが指摘したtqdm.write()
のend
パラメータを含める tqdm.tqdm.write()
from tqdm import tqdm_notebook
このコマンドはgoogle colabで機能します。
以下はハックですが、tqdmをリセットするのに適度に機能しているようです:
from tqdm import tqdm as tqdm_base
def tqdm(*args, **kwargs):
if hasattr(tqdm_base, '_instances'):
for instance in list(tqdm_base._instances):
tqdm_base._decr_instances(instance)
return tqdm_base(*args, **kwargs)
以前の出力が最初に出力される場合があります(削除する方法がわかりません)が、改行(特に長いループの場合)よりもずっと面倒ではありません。
私はtqdmソリューションを試しましたが、Spyder(Anaconda)を使用しているため、他の回答で述べられているように、書き込みコマンドと印刷コマンドの競合により、私の場合は機能しません。シンプルで効果的な解決策を思いつきました。
def ybar(progr, total, step=50):
#starts with 1
l2=(progr/total)//(1/step)
if progr==1: print(f'[{total}]: '+'|'*int(l2), end = '')
else:
l1=((progr-1)/total)//(1/step)
ll=int(l2-l1)
if l1 < l2:
for j in range(1,ll+1):
if (int(l1)+j)%5==0:
print('*', end = '')
else:
print('|', end = '')
if progr==total: print(" DONE")
その結果、シンプルになります:[100]:||||||
for i in range(1,101):
ybar(i,len(range(1,101)),50)
#something
ここにはたくさんの解決策があります: Python Progress Bar
tqdm_notebookは非推奨です。代わりにtq.notebook.tqdmを使用する必要があります。
import tqdm.notebook as tq
for i in tq.tqdm(...):
さらに、tqdm_notebookはパフォーマンスの面で本当に悲惨でした。新しいライブラリで完全に修正されています。
Tqdmを使用する前にtqdmインスタンスを閉じると、Jupyter Labの新しい行にステータスバーを印刷する問題が再び解決されることに気付きました。
while len(tqdm._instances) > 0:
tqdm._instances.pop().close()
tqdm
をインポートします。
from tqdm import tqdm
最初に、tqdm
を使用するコードを開始します。複数行が出力されるため、コードを停止します。
次に行います:
list(getattr(tqdm, '_instances'))
for instance in list(tqdm._instances):
tqdm._decr_instances(instance)
エラーが発生した場合:
AttributeError:タイプオブジェクト 'tqdm'に属性 '_instances'がありません
最初にコードを開始し、tqdm
を使用し、その開始コードの後にのみ言及します。
そして、このすべての操作の後、あなたのtqdm
は正常に動作します。