はじめに
長時間かかる処理を実行するとき、「あとどのくらいで終わるの?」という不安を感じたことはありませんか?プログレスバーがあれば、進捗が一目でわかり、ユーザー体験が格段に向上します。
この記事では、プログレスバーを3つのレベルで実装し、それぞれの使い分けを備忘録します。
1. 10行で作るシンプルなプログレスバー
まずは仕組みを理解するため、最小限のコードでプログレスバーを作ってみましょう。
import time, sys
def progress_bar(total, current):
progress = current / total
filled = int(50 * progress)
bar = '█' * filled + '-' * (50 - filled)
sys.stdout.write(f'\r[{bar}] {progress*100:.1f}%')
sys.stdout.flush()
# デモ実行
print("シンプルなプログレスバー:")
for i in range(101):
progress_bar(100, i)
time.sleep(0.02)
print("\n✅ 完了!")
このコードは進捗率を視覚的に表示する基本的な仕組みを示しています。\r
で行の先頭に戻り、sys.stdout.flush()
で即座に表示を更新することで、動的な表示を実現しています。
2. 実用的なProgressBarクラス
次に、残り時間の予測機能を追加したクラスベースの実装を見てみましょう。
import time, sys
from datetime import timedelta
class ProgressBar:
def __init__(self, total, desc="進捗"):
self.total = total
self.desc = desc
self.current = 0
self.start_time = time.time()
def update(self, current):
self.current = current
progress = current / self.total
filled = int(40 * progress)
bar = '█' * filled + '░' * (40 - filled)
elapsed = time.time() - self.start_time
if current > 0:
eta = int((elapsed / progress) - elapsed)
eta_str = str(timedelta(seconds=eta))
else:
eta_str = "計算中"
sys.stdout.write(f'\r{self.desc}: [{bar}] {progress*100:5.1f}% | '
f'残り: {eta_str}')
sys.stdout.flush()
def finish(self):
self.update(self.total)
print()
# デモ実行
print("時間予測付きプログレスバー:")
pbar = ProgressBar(80, "データ処理")
for i in range(81):
pbar.update(i)
time.sleep(0.05)
pbar.finish()
このクラスでは、経過時間と現在の進捗率から残り時間を計算し、ユーザーにより詳しい情報を提供します。中規模な処理で威力を発揮します。
3. tqdmでプロフェッショナルなプログレスバー
本格的な開発では、豊富な機能を持つtqdm
ライブラリを使用しましょう。
try:
from tqdm import tqdm, trange
except ImportError:
import subprocess, sys
subprocess.check_call([sys.executable, "-m", "pip", "install", "tqdm"])
from tqdm import tqdm, trange
import time
# 基本的な使い方
print("tqdm基本:")
for i in tqdm(range(60), desc="処理中"):
time.sleep(0.03)
# ネストしたプログレスバー(機械学習風)
print("\n機械学習風ネストバー:")
for epoch in trange(3, desc="エポック"):
for batch in trange(20, desc=f"エポック{epoch+1}", leave=False):
time.sleep(0.03)
# リアルタイム情報表示
print("\nリアルタイム情報:")
with tqdm(range(50), desc="処理", unit="item") as pbar:
for item in pbar:
time.sleep(0.04)
rate = pbar.format_dict.get('rate') or 0
pbar.set_postfix({"値": item, "速度": f"{rate:.1f}it/s"})
tqdm
は機械学習のトレーニングループやデータ処理パイプラインなど、複雑な処理に最適です。ネストしたプログレスバーやリアルタイム情報表示など、高度な機能が簡単に利用できます。
まとめ
使い分け指針
用途 | 手法 | 特徴 |
---|---|---|
学習用 | 自作関数 | 仕組み理解に最適 |
中規模処理 | ProgressBarクラス | 時間予測機能付き |
本格開発 | tqdm | 高機能で安定した動作 |
実装のポイント
プログレスバーを効果的に活用するには、いくつかの重要なポイントがあります。まず更新頻度に注意が必要で、あまり頻繁に更新するとパフォーマンスが低下するため、適切な間隔での更新を心がけましょう。また、単純な進捗率だけでなく、残り時間や処理速度といった有用な情報も併せて表示することで、ユーザーの体験が大幅に向上します。さらに、例外が発生した場合でもプログレスバーを適切に終了させるエラー対応も忘れずに実装しておくことが大切です。
これらのポイントを押さえてプログレスバーを活用すれば、ユーザーにとって親しみやすく、使いやすいPythonアプリケーションを作ることができます!