おさかなさんの覚え書き

Python3でプロセスバーを作ったり、ターミナル上の文字色や文字の装飾を変える

POST: 2020-02-11 / UPDATED: 2020-02-20

はじめに

この記事では一行のみのプロセスバー(進捗バー)を作成するやり方や、ターミナル上の文字色や文字装飾の変更の仕方を記述しています。

プロセスバー(進捗バー)を作る

for i in range(11):
    print(f"\r[{'#'*i}{(10-i)*' '}] {i*10}%",end="")
print()

ここで重要なのは\rと末尾のend=""。 前者は先頭、後者はカンマ区切りで末尾につける必要があります。

\rは復帰を示し、現在カーソルが合っている列の行頭まで復帰させる効果を持ちます。結果、既に出力されている文字の上に次の出力が来ると上書きされ、一行のみでプロセスバーの実現を可能とします。

end=""\rの効果を発揮するためのもの。本来print()単体では行末に改行がつけられているので、それを空の文字列に置き換えてカーソルを同じ行に存在させています。

三行目の空のprint()は改行させることでプロセスバー以降のCUIが崩れないようにしているもの。

エモいプロセスバー(進捗バー)を作る

for i in range(0,101):
    progress = "\033[07m \033[0m"*(i//2)+" "*(50-i//2)
    p = (3-len(str(i)))*" "+str(i)
    print(f"\r{p}% |{progress}| ", end="")

"\033[07m \033[0m"*i" "*100だと無駄に長い進捗バーになってしまうので、ゲージを50として"\033[07m \033[0m"*(i/2)" "*(50-i//2)としています。

これを実行すると、半角スペースの背景色を反転させた、パーセンテージも表示されるプロセスバーになります。

また、(3-len(str(i)))*" "+str(i)としたことでパーセンテージが上がるにつれてカクカクと動いてしまうことを防ぎます。

ターミナル上で文字色や文字装飾を変える

文字色を変える方法にはライブラリを使うものがありますが、今回の解説では使用しません。素のままのPython3で実行できます。

print("\033[31m"+RED+"\033[0m")

前述のコードではREDという文字列を赤色でターミナルに出力します。\033[31mが赤色の開始コードで、\033[0mは終了コードです。終了コードは文字色設定の終了にも使えます。

print(開始コード+変えたい文字列+終了コード)

以上の構造が基本で、終了コードをつけなくても動作しますが、それ以降のターミナルを全てその開始コードで色付けしたり装飾してしまうため、つけておくことを推奨します。

また、開始コードがprint("\033[31m"+"\033[1m"+"RED"+"\033[0m")のように複数あっても、一番近い終了コード一つで止まるので文字色や文字装飾を重ね付けする際には楽にやれそうですね。

# 重ね付け※下のコードのクラスを流用しています
print(Decorate.BOLD+Color.RED+BgColor.BLACK+"BoldRed+BgBlack"+Decorate.END)

以下に文字色や文字装飾の指定に使えるコードを書いておきます。お好きに利用してください。

class Color:
    BLACK = "\033[30m"
    RED = "\033[31m"
    GREEN = "\033[32m"
    YELLOW = "\033[33m"
    BLUE = "\033[34m"
    WHITE = "\033[37m"
    END = "\033[39m" # 文字色のみの終了コード
class Decorate:
    BOLD = "\033[1m"
    UNDERLINE = "\033[4m"
    INVISIBLE = "\033[08m"
    REVERSE = "\033[07m"
    END = "\033[0m" # 全ての色指定や装飾の終了コード
class BgColor:
    BLACK = "\033[40m"
    RED = "\033[41m"
    GREEN = "\033[42m"
    YELLOW = "\033[43m"
    BLUE = "\033[44m"
    WHITE = "\033[47m"
    END = "\033[49m" # 背景色のみの終了コード
# 太字+文字色赤+"BoldRed"+文字色終了+"BOLD"+全て終了
print(Decorate.BOLD+Color.RED+"BoldRed"+Color.END+"BOLD"+Decorate.END) # テスト用

以下のプログラムを利用することでrgb値での詳細な色指定コード(開始コードのみ)が容易に算出できます。
こちらもご自由にどうぞ。

# 文字色指定
rgb = input("rgb値: ")
print(r"\033[38;2;{};{};{}m".format(rgb[0],rgb[1],rgb[2]))
# 背景色指定
rgb = input("rgb値: ")
print(r"\033[48;2;{};{};{}m".format(rgb[0],rgb[1],rgb[2]))

Pythonで、進捗バーを自作する - Narito Blog

Pythonでエスケープシーケンスを無視(無効化)するraw文字列 | note.nkmk.me

[python]print文で色をつけてみよう - 野村数学研究所

まだ問題が解決していない場合、上記のサイト群が参考になる可能性があります。

閲覧いただきありがとうございました。質問あるいは指摘などございましたらコメントをお願いします。

TWEET