本ページはプロモーションが含まれています

【Python】ループ処理の進行状況を視覚的に表示する方法(%表示、プログレスバー)

Python文字列

ループ処理の進捗を視覚的に数値(%表記など)やプログレスバー形式で表示させたい場合があります。
3rdParty製モジュールを使った本格的なプログレスバーもありますが、本記事では標準組込み関数を用いた方法についてまとめます。
ポイントは、「改行処理」、「キャリッジリターン」と「行クリア」です。

スポンサーリンク

改行とキャリッジリターン

出力結果を毎回同じ位置に出力するためのポイントは、以下3つです。

  1. 改行処理
    • print() で出力する場合は、例えばend引数=””を設定(下記具体例を参照)
    • sys.stdout.write() で出力する場合は改行の設定は不要
  2. キャリッジリターン(CR, 行頭復帰)
    • \rを出力文頭に記述し、カーソルを行の先頭に戻す
  3. 行クリア
    • 前のタイミングよりも短い文字列を出力する場合、そのまま表示するとはみ出た分の文字列が残ってしまいます。
    • その為、出力文字列の先頭に\033[KANSI escape code )を記述し、カーソルのある行を一旦クリアします。
      • ※ANSI escape code
        • \033: ESC(エスケープシーケンス)の8進数表記
        • [ :  CSI(Control Sequence Indicator)を表す。コマンド開始を示す
        • K :  EL (Erase in Line) を表す。カーソル位置から行の末尾まで削除

具体例

例1) 単純に同じ位置に出力する

# 0.5s毎に数値をカウントアップ
import time, sys

for i in range(10):
    print(f"\r\033[K{i}", end="")
    #sys.stdout.write(f"\r\033[K{i}")  #print()の代わりにsys.stdoutでもOK
    time.sleep(0.5)

出力イメージ(0から9までカウントアップされます)
※見やすくするためにelse節以下に改行処理を入れています

 

例2) かんたんプログレスバー

# 0.5s毎に"#" 表示を更新
import time

for i in range(1, 11):
    print(f"\r\033[K{'#' * i}", end="")
    time.sleep(0.5)

出力イメージ(”#”が伸びていきます)

 

例3) プログレスバー + 進捗(%表示など)

# 0.5s毎に"#"表示と数値を更新
import time

n = 20
for i in range(n+1):
    bar = '*' * i + " " * (n-i)
    print(f"\r\033[K[{bar}] {i/n*100:.02f}% ({i}/{n})", end="")
    time.sleep(0.5)

出力イメージ

 

例4) プログレスバーの先頭の形状を変えてみた

# 0.5s毎に"#"表示と数値を更新
import time

n = 20
for i in range(n+1):
    bar = '='*i + ("=" if i == n else ">")  + "."*(n-i)    # プログレスバーの先頭の表示を工夫
    print(f"\r\033[K[{bar}] {i/n*100:.02f}% ({i}/{n})", end="")
    time.sleep(0.5)

出力イメージ

 

例5) プログレスバーに色をつけてみた

ANSIエスケープコード\033[ n m(n:カラーを表す整数値、m: SGR (Select Graphic Rendition))で色を設定できます。
元の標準出力の色に戻すには\033[39mを設定します。

# 0.5s毎に黄色の"■"表示を更新
import time

n = 20
for i in range(n+1):
    bar = '■'*i + "."*(n-i)
    print(f"\r\033[K[\033[33m{bar}\033[39m] {i/n*100:.02f}% ({i}/{n})", end="")
    time.sleep(0.5)

出力イメージ

 

環境

  • OS: Ubuntu20.04LTS@WSL2
  • Python3.11.2

まとめ

標準出力へ同じ行に出力するポイントは以下3点です。

  • 出力後に改行コードを表示させない(print()の場合はend=””と設定)
  • キャリッジリターン(CR, 行頭復帰:”\r”)を出力文頭に記述する
  • カーソルのある行をクリア: ”\033[K”を記述(ANSI escape code)

参考書籍

書籍でもう少し詳しく学びたい場合はこちらもどうぞ。筆者もかなり参考にさせてもらっています!

シェアする
ひびきをフォローする