ユーニックス総合研究所

  • home
  • archives
  • python-progress-bar

Pythonで自作プログレスバーを作る

  • 作成日: 2023-06-20
  • 更新日: 2023-12-24
  • カテゴリ: Python

Pythonで自作プログレスバー

プログレスバーというのは現在の進捗を視覚的に表示するバーのことです。
いま何パーセント終了しているの? というときに確認するのがプログレスバーです。

パッケージのダウンロードとかすると端末にプログレスバーが表示されて進捗が出ますよね。
あれなんですが今回は自作でプログレスバーを作ってみたいと思います。

関連記事
Djangoでオブジェクトを一括作成・更新【bulk_create, bulk_update】
DjangoのModel.objects.filter()の使い方【QuerySet】
Djangoのmodelのcreate()の使い方【Python】
Django入門: ルートの設定 ~ 簡単な一行掲示板アプリを作る その4【Windows10】
NumPyのappend()の使い方: 配列の末尾に要素を追加
Numpyのarangeの使い方: 指定範囲の数列を生成する
Python3でYoutube Data APIを使ってキーワード検索する
PythonからC言語(my.puts)を呼び出して実行する

ソースコード全文

ソースコードのライセンスはMITです。

import time  


class Progress:  
    def __init__(self, end=100, cur=0, width=50):  
        self.end = end  
        self.cur = cur  
        self.width = width  

    def print(self):  
        n = int(self.width * (self.cur / self.end))  
        nn = self.width - n  
        n100 = int(100 * (self.cur / self.end))  
        s = '[' + n * '#' + nn * ' ' + '] ' + str(n100) + '%'  
        print(f'\r{s}', end='')  

    def add(self, n):  
        self.cur += n  

    def is_end(self):  
        return self.cur >= self.end  



progress = Progress(200)  

while True:  
    progress.print()  
    if progress.is_end():  
        break  
    progress.add(1)  
    time.sleep(0.1)  

上記のコードを実行すると以下のように表示されます。

ソースコードの解説

先ほどのソースコードを解説します。
基本的な処理はProgressというクラスで行います。
やってることはけっこう単純なので順に解説していきます。

まずProgressを実際に使っているところのコードを見てみます。

Progressを実際に使っているところのコード

以下はProgressを使って端末に進捗を表示しているコードです。

progress = Progress(200)  

while True:  
    progress.print()  
    if progress.is_end():  
        break  
    progress.add(1)  
    time.sleep(0.1)  

まずProgressをオブジェクトにします。

progress = Progress(200)  

この時、イニシャライザの引数にはendの値を指定します。
200というのがendの値です。
この値は「全体の仕事総量」を指します。
たとえば100kbの画像のダウンロードであればこのendの値は100になります(最低1kbずつダウンロードする前提で)。

進捗というのは終わりが見えないと全体のパーセンテージを表示できません。
ですのでここで全体の仕事総量を指定しておく必要があります。

while True:  
    progress.print()  
    if progress.is_end():  
        break  
    progress.add(1)  
    time.sleep(0.1)  

上記は無限ループに入って進捗を表示しているところです。

    progress.print()  

上記は進捗バーを端末にprint()します。
これがバーを表示しているところです。

    if progress.is_end():  
        break  

progress.is_end()は進捗が完了したらTrueを返します。
進捗が完了している場合はループからbreakします。

    progress.add(1)  

progress.add(1)で進捗を進めます。
このadd(1)の値はProgresscur属性に加算されます。
Progressendcur属性から現在の進捗を計算します。
curの値が増えれば進捗がそれだけ進むということになります。

    time.sleep(0.1)  

上記はスレッドをスリープしています。
これはアニメーションを見せるための意味のないスリープです。
取っちゃってもかまいません。

Progressクラスの解説

ではProgressクラスの解説に入ります。

class Progress:  
    def __init__(self, end=100, cur=0, width=50):  
        self.end = end  
        self.cur = cur  
        self.width = width  

    def print(self):  
        n = int(self.width * (self.cur / self.end))  
        nn = self.width - n  
        n100 = int(100 * (self.cur / self.end))  
        s = '[' + n * '#' + nn * ' ' + '] ' + str(n100) + '%'  
        print(f'\r{s}', end='')  

    def add(self, n):  
        self.cur += n  

    def is_end(self):  
        return self.cur >= self.end  

まずイニシャライザです。

    def __init__(self, end=100, cur=0, width=50):  
        self.end = end  
        self.cur = cur  
        self.width = width  

上記のendは全体の仕事総量、curは現在の完了した仕事量、widthは表示を整えるための横幅です。
widthはデフォルトで50になっていますが、これを100にすると進捗バーの横幅が横に伸び、20にするとバーが短くなります。

    def print(self):  
        n = int(self.width * (self.cur / self.end))  
        nn = self.width - n  
        n100 = int(100 * (self.cur / self.end))  
        s = '[' + n * '#' + nn * ' ' + '] ' + str(n100) + '%'  
        print(f'\r{s}', end='')  

上記は進捗バーを表示しているメソッドです。
まずself.cur / self.endで現在の仕事量の全体の総量に対する割合を計算します。
これは0から1の値の範囲におさまります。
それにself.widthを掛けることでnとします。

nn = self.width - nwidthnの差分を取ります。これはバーの空白部分を埋めるための値です。
n * '#'とすることで進捗バーの進捗部分が埋まり、nn * ' 'とすることで空白が埋まります。

n100 = int(100 * (self.cur / self.end))はパーセンテージを計算しています。
割合に100を書けると0から100までのパーセンテージになります。

あとはs = '[' + n * '#' + nn * ' ' + '] ' + str(n100) + '%'で文字列を合成します。
これが進捗バーになります。

print(f'\r{s}', end='')とやって文字列をprint()します。
この時に\rで出力一を行頭に戻しています。かつそれに加えてend=''とやって改行を除いています。
こうするとアニメーションするような見た目になります。

    def add(self, n):  
        self.cur += n  

上記はself.curに進捗を加えるメソッドです。
加算してるだけです。

    def is_end(self):  
        return self.cur >= self.end  

上記は進捗が完了しているかどうかチェックするメソッドです。
self.curself.end以上であれば進捗完了と見なしTrueを返します。

おわりに

今回はPythonで自作プログレスバーを作ってみました。
なにか参考になれば幸いです。

🦝 < 進捗進捗ぅ!

🦝 < ひえ~