【Python】作成したソースファイルについて、1行当たりの文字数が規約以内かチェックするツール

■ツール概要と目的

Pythonのソースコードを実装するにあたり、コーディングスタイルが重要となってくる。

今回は、Pythonチュートリアルの「4.9. 間奏曲: コーディングスタイル」に記載されている、1行当たりのソース幅に関して、作成した任意のPythonファイルが、79文字以下かどうか判定するツールを作成する。

ソースコードの幅が 79 文字を越えないように行を折り返すこと。

Pythonチュートリアル:「4.9. 間奏曲: コーディングスタイル」

以降、本ツールを「ソースファイル文字数チェックツール」と呼ぶ。

■機能設計

本項では、「ソースファイル文字数チェックツール」を使用するユーザ観点での機能設計を示す。

▼機能フロー図

「ソースファイル文字数チェックツール」の機能フロー図を以下に示す。

▼機能概要

「ソースファイル文字数チェックツール」の機能概要を以下に示す。

入力処理内容出力
ユーザは作成したPythonのソースファイルを
「./INPUT」フォルダに格納する。
【ファイル】
ソース
「ソースファイル文字数チェックツール」を実行する。【ファイル】
チェック結果
ユーザはチェック結果を確認する。
▼条件分岐:チェック結果
<NGの場合>
該当部分を修正する。
→「処理内容」の先頭に戻る。
<OKの場合>
終了
▲条件分岐:チェック結果

▼入出力一覧

「ソースファイル文字数チェックツール」にて使用する、入出力を以下に示す。

項目名区分内容
ソースファイル入力ユーザが作成した任意のソースファイル。
格納先:「./INPUT」
チェック結果出力1行あたりの文字数が、
上限以上のファイル名および行数を出力する。
出力先:「./RESULT」

・入力:ソースファイル

入力項目について、ここでは、検証も兼ねて以下のソースファイルを使用する。

・sampleA.py

ひたすら「A」を出力する処理


・sampleB_1.py

ひたすら「B」を出力する処理(その1)
※ところどころに空の改行あり


・sampleB_2.py

ひたすら「B」を出力する処理(その2)
※「sampleB_1.py」と同じ内容
※ところどころに空の改行あり


なお、上記3ファイルについては、以下のディレクトリ階層に配置する。

./INPUT/sampleA.py
./INPUT/BBB/sampleB_1.py
./INPUT/BBB/sampleB_2.py

・出力:チェック結果

出力項目について、「チェック結果」ファイルのレイアウトを示す。

・check_result.txt

ソースファイル名
n行目:○○文字
n行目:○○文字
n行目:○○文字

ソースファイル名
n行目:○○文字
n行目:○○文字

ソースファイル名
n行目:○○文字
n行目:○○文字
n行目:○○文字
n行目:○○文字

「n」は、上限より多い行。
「〇〇」は、対象行の文字数。

▼制約事項・前提条件

「ソースファイル文字数チェックツール」を実装するにあたり、制約事項・前提条件を以下に示す。

  • 「./INPUT」ディレクトリ配下は、サブディレクトリ配下も含めてソースファイルを判定する。
  • 実行環境はMacであるため、改行コードは「\n」とする。
    ※windowsの場合、改行コードは「\r\n」。
  • 出力ファイル「チェック結果」については、上書きモードで作成する。
    ※処理の度に内容を洗い替えする。

■プログラム設計

「ソースファイル文字数チェックツール」にて使用する処理は、「文字数チェック処理」のみである。

以降、「定数」および「文字数チェック処理」のプログラム仕様を示す。

▼定数

本処理で使用する定数を以下の表に示す。

定数名内容
CHECK_FILE_PATH./INPUTチェック対象のソースファイルを
格納するディレクトリ名
RESULT_FILE_NAME./RESULT/check_result.txtチェック後の対象を
出力するファイル名
CHEK_CHAR_LENGTH80上限の文字数

▼文字数チェック処理

INPUTディレクトリ配下のファイルについて、1行あたりの文字数が規定数以内かチェックし、規定数以上であれば、該当のモジュール名、行数と文字数をRESULTファイルに出力する。

・プログラム処理フロー図

「文字数チェック処理」のプログラム処理フロー図を以下に示す。


・プログラム仕様

「文字数チェック処理」のプログラム仕様を以下に示す。

区分概要
引数引数なし
戻り値戻り値なし
入力処理内容出力
●出力ファイルを上書きモード「w」で開く
【ディレクトリ】
./INPUT
■ループ処理:ディレクトリ分繰り返し
【ディレクトリ配下の
ファイル群】
ソース
■ループ処理:ファイル数分繰り返し
ソースファイルパスをセット
ソースファイル名を出力【txtファイル】
チェック結果
改行(\n)を出力【txtファイル】
チェック結果
【ファイル】
ソース
●読み込みソースファイルを開く
■ループ処理:ファイルの行数分繰り返し
▼条件分岐:1行の文字数
<80文字以上の場合>
行数+文字数+改行(\n)を出力【txtファイル】
チェック結果
▲条件分岐:1行の文字数
■ループ処理:ファイルの行数分繰り返し
改行(\n)を出力
■ループ処理:ファイル数分繰り返し
■ループ処理:ディレクトリ分繰り返し

■サンプルコード

「ソースファイル文字数チェックツール」のソースを以下に示す。

import os

# 定数関連
CHECK_FILE_PATH = './INPUT'
RESULT_FILE_NAME = './RESULT/check_result.txt'
CHEK_CHAR_LENGTH = 80

def check_chars_length():
    '''
    文字数チェック処理
    概要:
        INPUTディレクトリ配下のファイルについて、
        1行あたりの文字数が規定数以内かチェックし、
        規定数以上であれば、該当のモジュール名、
        行数と文字数をRESULTファイルに出力する。
    引数:
        なし
    戻り値:
        なし
    INPUT:
        「./INPUT」ディレクトリ配下(サブディレクトリも含む)のファイル
    OUTPUT
        判定NGリストファイル(./RESULT/check_result.txt)
    '''
    
    # 出力用ファイルを上書きモードで開く
    with open(RESULT_FILE_NAME, 'w') as out:
        
        # インプットディレクトリ(サブディレクトリ含む)分繰り返し
        for current_dir, sub_dir, file_list in os.walk(CHECK_FILE_PATH):
            
            # ファイルの数だけ繰り返し
            for file_name in file_list:
                
                # ファイルのパスをセット
                tmp_file_path = current_dir + '/' + file_name
                
                # ファイル名を出力
                out.write(tmp_file_path)
                # 改行
                out.write('\n')
                
                # 読み込みファイルを開く
                with open(tmp_file_path, 'r') as f:
                
                    # ファイルの行数分繰り返し
                    for i, line_str in enumerate(f):
                
                        # 1行当たりの文字数が規定より大きい場合
                        if len(line_str) >= CHEK_CHAR_LENGTH:
                
                            # 出力用の行数と文字数をセット
                            # *「i」は0始まりなのでインクリメント
                            chk_value = str(i+1) \
                                + '行目:' \
                                + str(len(line_str)) \
                                + '文字'
                            
                            # 判定NGを出力
                            out.write(chk_value)
                            # 改行
                            out.write('\n')
                
                # 改行
                out.write('\n')


# メイン処理
if __name__ == '__main__':
    check_chars_length()

■実行結果

「ソースファイル文字数チェックツール」の実行結果(チェック結果ファイルの内容)を以下に示す。

./INPUT/sampleA.py
8行目:138文字
9行目:266文字

./INPUT/BBB/sampleB_2.py
1行目:266文字
3行目:138文字
12行目:138文字
15行目:265文字

./INPUT/BBB/sampleB_1.py
1行目:266文字
3行目:138文字
12行目:138文字
15行目:265文字

■参考

「ソースファイル文字数チェックツール」を作成するにあたり、参考とさせていただいた外部リンクおよび内部リンクを示す。

▼外部参考リンク

・任意のディレクトリのファイル名を取得


・ファイルを1行ずつ読み込み

▼内部参考リンク

・GitHub

コメント