自動化について考えるブログ

自動化に関する話が好きで、ロボットやライフロギングについて書いていきます。たまに趣味の地理・旅行に関する話もします。

Pythonによるファイル数カウンタ

概要

デスクトップのファイル数がその時のテンパり具合と相関がありそうだったので、
テンパり度合いを自動抽出できないかと思いファイル数のカウンタを実装しました。

コード

言語: Python3
実行環境: Windows 10
コードは以下から。

import os
import datetime
 
#ディレクトリ内の全てのファイルをカウントする再帰関数
def countFiles(target_dir_name):
    #カウンタの初期化
    cnt = 0
    # 指定したパス内の全てのファイルとディレクトリを要素とするリストを返す
    target_dir_files = os.listdir(target_dir_name)
    for file in target_dir_files:
        new_target_dir_name = target_dir_name + "\\" +file
        #ディレクトリか非ディレクトリで条件分岐
        if os.path.isdir(new_target_dir_name):
            #ディレクトリの場合、中に入って探索する
            cnt += countFiles(new_target_dir_name)
        else:
            #非ディレクトリの場合、数え上げを行う
            cnt += 1
    return cnt

#ファイル数を数えて.csvファイルに書き込む
def writeFilenum(target_dir_name, count_mode):
    #ファイル数ログファイルの名前の設定
    dir_name = target_dir_name.split("\\")[-1]
    logfile_name = "file_n_log_" + dir_name + ".csv"
    #現在時刻の取得
    now_dt = datetime.datetime.now()
    now_dt_str = now_dt.strftime("%Y/%m/%d %H:%M:%S")
    # "all_files"の指定の場合、ディレクトリ内の全てのファイルをカウント
    if count_mode == "all files":
        #書き込み用データの作成
        new_row = [now_dt_str, countFiles(target_dir_name)]
    else: # "all_files"以外の指定の場合、ターゲットディレクトリ直下のファイル数をカウント
        # 指定したパス内の全てのファイルとディレクトリを要素とするリストを返す
        target_dir_files = os.listdir(target_dir_name)
        """
        #debug: ファイル一覧の表示
        for ind, file in enumerate(target_dir_files):
            print(ind, end="")
            print(file)
        """
        #書き込み用データの作成 中身はタイムスタンプとファイル数
        new_row = [now_dt_str, len(target_dir_files)]
    #プログラムがあるディレクトリの取得
    current_dir = os.getcwd()
    current_dir_files = os.listdir(current_dir)
    if current_dir_files.count(logfile_name) >= 1: # print("書き込み用ファイルあるよ")
        with open(logfile_name, 'a') as f:
            f.write(new_row[0])
            f.write(",")
            f.write(str(new_row[1]))
            f.write(",")
            f.write("\n")
    else: # print("書き込み用ファイルないよ")
        with open(logfile_name, 'wt') as f:
            f.write(new_row[0])
            f.write(",")
            f.write(str(new_row[1]))
            f.write(",")
            f.write("\n")

#ファイル数の時系列プロット
def visualizeFilenumLog(target_dir_name):
    #ファイル数ログファイルの名前の設定
    dir_name = target_dir_name.split("\\")[-1]
    logfile_name = "file_n_log_" + dir_name + ".csv"
    #csvファイルからの読み込み
    with open(logfile_name, 'r') as f:
        data = f.readlines()
    dt_ls = []
    file_n_ls = []
    for row in data:
        ele = row.split(",")
        dt_ls.append(datetime.datetime.strptime(ele[0], "%Y/%m/%d %H:%M:%S"))
        file_n_ls.append(ele[1])
    #描画部
    import matplotlib.pyplot as plt
    import matplotlib.dates as mdates
    fig = plt.figure()
    ax = fig.add_subplot(1,1,1)
    #目盛り間隔の定義
    days = mdates.AutoDateLocator()
    #日付表現の定義
    daysFmt = mdates.DateFormatter("%b/%d")
    ax.plot(dt_ls,file_n_ls)
    ax.set_title("Directory name: %s"%dir_name)
    ax.xaxis.set_major_locator(days)
    ax.xaxis.set_major_formatter(daysFmt)
    plt.show()

if __name__ == '__main__':
    #計測したい対象のディレクトリと、深くまで探索を行うかのモードを指定
    target_dir_ls = [
        ["C:\\Users\\[ユーザ名]\\Desktop","root only"],
        ["C:\\Users\\[ユーザ名]\\[任意のディレクトリ名]", "all files"],
        ]
    for target_dir in target_dir_ls:
        writeFilenum(target_dir[0], target_dir[1])
        visualizeFilenumLog(target_dir[0])

使い方

writeFilenum関数は対象ディレクトリのファイル数を数え、タイムスタンプとともにcsvファイルに追記していきます。
writeFilenum関数には対象ディレクトリのパスとカウントモードの情報を渡します。
カウントモードは2つあり、ディレクトリ直下のファイル数を数えるモード、深い階層まで数えるモードがあります。

実施例

実行はWindowsのタスクスケジューラに.batファイルを登録し、1時間毎に行いました。
そして、半月ほど計測してみた結果が以下のグラフ。
f:id:ky61:20180218130428p:plain

とくに意識はしなかったのですが、実績をみると
・自分は1週間に1度くらい掃除を行っている
・自分は掃除の時には20~30個一気に掃除する
という傾向があることが見て取れます。

まとめ

今回は単純なファイル数のみをカウントしましたが、
将来的には、以下の情報をとってみるのも面白そうです。
・ファイルの種類 (pdfやlnk)
・あるファイル時系列でのディレクトリの推移

情報の整理のうまさや同時進行タスク数を可視化出来るような気がします。