ファイルのダウンロードをする時にダウンロード時間残り5分と書かれているのに1分後には残り10分に増えることがあるので、
プログレスバーってPythonでどういう風に実装できるのかと気になりだしたため記事を書きます。
tqdmライブラリ
ライブラリとして存在しているみたいですね。
自分、python初心者なので知らなかったです。
tqdm(スペイン語で「te quiero demasiado」の略)は処理の進捗状況を表してくれるプログレスバーを提供してくれる。
進捗バーの状態(カウンタ、時間、メッセージ)を保持するだけなので基本メモリ消費は激しくないようです。
準備
tqdmをインストール
pip install tqdm
さっそくやってみよう
#使うライブラリ
from concurrent.futures import ThreadPoolExecutor, as_completed
from tqdm import tqdm
import time
#usersとintervalsのリストを作る(別に辞書でもいい)
users = ["Andy", "Bob", "Cameron", "David"]
intervals = [1, 2, 3, 4]
#処理内容
def count_interval(user, interval):
time.sleep(interval)
return f"{user}:done"
# 進捗バーを表示しながら並列処理
with ThreadPoolExecutor(max_workers=4) as executor: #max_workersは同時に処理するスレッド数を決める
futures = {executor.submit(count_interval, user, interval) for user,interval in zip(users,intervals)} #ユーザの人数分スレッドを立てて処理を実行する
with tqdm(total=len(users)) as pbar: total引数でバーの数を決める
for future in as_completed(futures):
result = future.result()# 計算結果を受け取る
pbar.update(1) # 処理が終わるごとに進捗バーを1つ進める
結果
20%|██ | 1/5 [00:02<00:11, 2.97s/it]
↓
100%|██████████| 5/5 [00:09<00:00, 1.99s/it]
しっかりと5ユーザ分の進捗表示がされました!
しかし...
プログレスバーの内容が理解し難いので自分流にカスタマイズする
bar_formatを使って自分の好きなように表示を変えることができます。
ついでにバーの長さも変えちゃいます。
詳しくは、tqdmのサイトを参照してください。
with ThreadPoolExecutor(max_workers=4) as executor:
futures = {executor.submit(count_interval, user, interval) for user,interval in zip(users,intervals)}
with tqdm(total=len(futures), bar_format="{l_bar}{bar} [{n_fmt}/{total_fmt}|経過時間: {elapsed}]",ncols=100) as pbar:
completed = 0
for future in as_completed(futures):
result = future.result()
pbar.update(1)
結果
20%|██████████████▌ [1/5|経過時間: 00:00]
↓
100%|█████████████████████████████████████████████████████████████████████████ [5/5|経過時間: 00:09]
という感じでカスタマイズ性も兼ね備えてますね!(バーが長すぎた...)
プレースホルダー紹介
プレースホルダー | 説明 |
---|---|
{l_bar} |
左側の情報 (例: 50%) |
{bar} |
プログレスバー本体 |
{n} |
現在の進捗数 |
{total} |
合計数 |
{n_fmt} |
現在の進捗数(フォーマット済み) |
{total_fmt} |
合計数(フォーマット済み) |
{percentage} |
進捗率(例: 50.0) |
{elapsed} |
経過時間(例: 00:10) |
{remaining} |
残り時間 |
{rate_fmt} |
処理速度(例: 10it/s) |
まとめ
・時間計測する場合は精度が高いわけではないので厳密にテストする時に使うには力不足
・大雑把な進捗+時間を把握するのに丁度よさそう