Python3 進捗をコンソール出力する

こんにちは、kisseです。

今日は、Pythonを触ってて気になった点について書いていきます。

やりたいこと

ループ回数が何千回っていう処理の進捗を画面に表示したいです。
しかもループさせる処理が重たかったりするので、何も出力されないまま待っているのは何かエラーが発生しているのではないかと不安になるので精神衛生上悪いです。笑笑
あとは、処理の終了時間に目処がつくのもいいですね。コンビニ行けるかもしれません。笑笑
パッと思いついて書けるのは

length = 100
for i in range(length):
    print(i)
    #重たい処理

っていうコードでしょうか。
でもこれだと、ループ処理が100回なので、1000行出力されますよね。
あんまり見た目がよろしくありません。笑

ところで、コンソールで何かダウンロードする際に進捗バーみたいなのが表示されるのを見たことありませんか?
あれを実現することができるのであれば、1行に進捗を表示させ続けることもできるはずです。

書いたコードと解説

進捗バーを表示させるライブラリはPython2にあるそうなんですが、Python3用ではないそうです。(動きはするらしい?)
なので、自分でパッと書いてしまいます。
ループの中に2行ほど処理を足すだけで実現できました。

まずは私が書いたコードを見てみてください。

import sys
import time

length = 100

for i in range(length):
    
    #進捗表示
    sys.stdout.write("\r%d / 100" %(int(i * 100 / (length-1))))
    sys.stdout.flush()
    #進捗表示おわり
    
    #重い処理のはじまり
    time.sleep(0.1)
    #重い処理の終わり

このように記述することで、1行に進捗を数字ベースで出力することができます。
sys.stdout.write()は改行が自動的に入らない出力方法です。
“\r”は文字の出力位置を行の最初に移動させるためのエスケープ文字です。
ダブルクォーテーション内の%dはそのあと渡される変数の値を表示させるもので、変数の型がintの時にのみ使えます。int型じゃない変数を渡してもエラーは発生しませんが、意味わかんない値が出力されます。C言語触ったことがある人にはすんなりわかると思います。
ダブルクォーテーションの外の%に続く値は進捗状況を百分率で表した数字となります。

sys.stdout.flush()は現時点で出力するべき文字列を全て出力させる命令を行います。

このように記述することで、重たい処理の進捗を示すことができるようになります。
これ、割と使えるので私は多用しています。
暇な時間別の作業するか、コンビニいけますもん。笑笑
関数化しちゃったほうがいいかもしれませんね。

import sys
import time

def progress(p, l):
    sys.stdout.write("\r%d / 100" %(int(p * 100 / (l - 1))))
    sys.stdout.flush()
    
length = 100

for i in range(length):
    progress(i, length)
    
    #重い処理のはじまり
    time.sleep(0.1)
    #重い処理の終わり

まとめ

重たい処理をループ処理で繰り返す場合は、以上の処理で画面表示させると便利です。
ぜひ活用してください。
「python progressbar」で検索してもらえれば、Python2用ですがライブラリもあります。
パソコンに頑張らせてる間、コンビニ行きましょう。笑笑

最後まで読んでいただきありがとうございました!
Pythonに関する記事を量産していく計画なので、ぜひ他の記事も読んでいってください!

あわせて読みたい