Szarny.io

There should be one-- and preferably only one --obvious way to do it.

pythonのtqdmモジュールで進捗状況を表示する

はじめに

tqdmモジュールを使うことで,プログラムの進捗状況を可視化することができるようです.
実際に使いながら見ていきます.

モジュールのインストール

# pip install tqdm

Anaconda環境の方はこちら

# conda install tqdm

使用例

簡単な例

関数do_somethingでは,time.sleep関数を用いて時間のかかる処理を模倣しています.

import tqdm
import time

def do_something():
    time.sleep(0.1)
    print("done.")
    
for i in tqdm.tqdm(range(10)):
    do_something()
  0%|                                | 0/10 [00:00<?, ?it/s]done.
 10%|██▍                     | 1/10 [00:00<00:00,  9.91it/s]done.
 20%|████▊                   | 2/10 [00:00<00:00,  9.90it/s]done.
 30%|███████▏                | 3/10 [00:00<00:00,  9.89it/s]done.
 40%|█████████▌              | 4/10 [00:00<00:00,  9.90it/s]done.
 50%|████████████            | 5/10 [00:00<00:00,  9.91it/s]done.
 60%|██████████████▍         | 6/10 [00:00<00:00,  9.90it/s]done.
 70%|████████████████▊       | 7/10 [00:00<00:00,  9.91it/s]done.
 80%|███████████████████▏    | 8/10 [00:00<00:00,  9.92it/s]done.
 90%|█████████████████████▌  | 9/10 [00:00<00:00,  9.92it/s]done.
100%|███████████████████████| 10/10 [00:01<00:00,  9.93it/s]

関数と組み合わせる

import time
import tqdm

def add(a, b):
    time.sleep(0.1)
    return "{} + {} = {}".format(a, b, a+b)

def sub(a, b):
    time.sleep(0.1)
    return "{} - {} = {}".format(a, b, a-b)

def mul(a, b):
    time.sleep(0.1)
    return "{} * {} = {}".format(a, b, a*b)

def div(a, b):
    time.sleep(0.1)
    return "{} / {} = {}".format(a, b, a/b)

# 進捗状況付きの関数リスト
func_with_progress = tqdm.tqdm([add, sub, mul, div])

for func in func_with_progress:
    print(func(6,2))

print("program done.")
  0%|                                 | 0/4 [00:00<?, ?it/s]6 + 2 = 8
 25%|██████▎                  | 1/4 [00:00<00:00,  9.92it/s]6 - 2 = 4
 50%|████████████▌            | 2/4 [00:00<00:00,  9.90it/s]6 * 2 = 12
 75%|██████████████████▊      | 3/4 [00:00<00:00,  9.91it/s]6 / 2 = 3.0
100%|█████████████████████████| 4/4 [00:00<00:00,  9.92it/s]
program done.

通信処理と出力のカスタマイズ

処理に時間がかかりがちで,実際に実行が続いているか不安になることが多い通信処理を含むプログラムと組み合わせるとよさそうですね.

本ブログの最新記事のタイトルを取得し,表示するプログラムです.
各チェックポイント毎に,進捗状況をカスタマイズして表示させています.

import tqdm
import requests
from bs4 import BeautifulSoup as bs

progress = tqdm.tqdm(total=3)

page = requests.get("http://szarny.hatenablog.com/")
progress.set_description("[HTTP GET Request]")
progress.update(1)

soup = bs(page.text, "lxml")
progress.set_description("[HTML Parse]")
progress.update(1)

title_list = soup.find_all("a", class_="entry-title-link")
progress.set_description("[Finding title]")
progress.update(1)
progress.close()

for i, title in enumerate(title_list, start=1):
    print("[{}] {}".format(i, title.text))
※実際には以下のプログレスバーがシームレスに表示されます
                      0%|          | 0/3 [00:00<?, ?it/s]
[HTTP GET Request]:  33%|███▎      | 1/3 [00:00<00:00,  4.61it/s]
[HTML Parse]:        67%|██████▋   | 2/3 [00:00<00:00,  3.88it/s]      
[Finding title]:    100%|██████████| 3/3 [00:00<00:00,  4.60it/s]

[1] Metasploitのsmb_versionモジュールを使ってWindowsマシンを特定する
[2] 高性能ポートスキャナ「Nmap」を使ってポートスキャン - 通信方式・オプション・実行例ほか
[3] Base64 Encoder + Decoder をPythonで実装する
[4] SANS NETWARSトーナメント2017 に参加しました
[5] バッファオーバーフローを実験する(deadbeefとeip奪取)
[6] VMware Playerでインターネット接続が突然切れた
[7] 簡単なプログラムをgdb-pedaで解析する