【Python】固定長ファイル:字幕時間ファイルを所定のフォーマットに変換する

■実装するプログラムの概要

固定長の時間を記載しているテキストファイルをインプットとして、所定の字幕時間フォーマットに変換する。

【条件】

「8桁数字+半角スペース+8桁数字」のファイルについて・・・

8桁の数字(例:00000112)の場合は、
①左6桁(000001)は「00:00:01」形式にする。
②右2桁の数字(12)は60で割り(12÷60=0.2000)、少数第4位(赤字部分)を四捨五入する。
③四捨五入した値について、少数第1位から第3位までの値(200)を取得する。
④上記結果の①と③の間にカンマ「 , 」を付与する。(00:00:01,200)

半角スペースの場合は、「 -> 」に変換する。

インプットファイルの1行を1件として、アウトプットファイルに1から順番にNo.を付与する。

▼完成イメージ

・インプット

00000112 00000115
00000130 00000145
12345610 11121314

・アウトプット

1
00:00:01,200->00:00:01,250
2
00:00:01,500->00:00:01,750
3
12:34:56,167->11:12:13,233

■フローチャート

▼メイン処理

▼ファイルのフォーマット変換

▼小数点算出処理

■プログラム仕様

▼ファイルのフォーマット変換

引数:なし
戻り値:なし

処理概要:ファイルを読み込み、所定の書式に変換する処理
インプット処理内容アウトプット
【ファイル】
input_file.txt
読み取りでインプットファイルを開く。
書き込みモードでアウトプットファイルを作成する。【ファイル】
out_file.txt
カウンタの初期値をセットする(初期値:1)。
【ループ処理:開始】Trueの間
インプットファイルを1行ずつ取得する。
【条件分岐】1行ずつ取得した値がない場合
ループ処理終了
アウトプットファイル出力用の文字列を初期化する。
カウンタと改行を挿入する。
「00:00:00,」形式に変換する。
【小数点算出】関数呼び出し
半角スペースを「->」に変換する。
「00:00:00,」形式に変換する。
【小数点算出】関数呼び出し
アウトプットファイルに出力【ファイル】
out_file.txt
【ループ処理:ここまで】Trueの間

▼小数点算出処理

引数:計算対象(文字列)
戻り値:小数点第1位から第3位の値(文字列)

処理概要:計算対象を60で割る。
        少数点第4位を四捨五入する。
        小数点第1位から第3位の値のみを出力する。
インプット処理内容アウトプット
引数の文字列をfloat型に変換する。
引数を60で割る。
小数点第4位を四捨五入する。
小数点第1位から3位を取得する。
戻り値(小数点第1位から3位)を返す。

■インプットファイルレイアウト

・input_file.txt

00000112 00000115
00000130 00000145
12345610 11121314
01020340 01020355
00200120 00200130
00300130 00300142
00400131 00400143
00500133 00500144
02000134 02000146

■サンプルコード

from decimal import Decimal
from decimal import ROUND_HALF_UP


# ----------- 定数 -----------
INPUT_FILE_NAME = './input_file.txt'
OUTPUT_FILE_NAME = './out_file.txt'
NUM_60 = 60
SEPARATE_TARGET = '.'


def CalDecimalPoint(str_read_line):
    """
    小数点算出関数

    引数:計算対象(文字列)
    戻り値:小数点第1位から第3位の値(文字列)

    処理概要:計算対象を60で割る。
            少数点第4位を四捨五入する。
            小数点第1位から第3位の値のみを出力する。
    """

    # 引数の文字列をfloat型に変換
    float_read_line = float(str_read_line)

    # 指定の値で割る
    float_cal_data = float_read_line / NUM_60

    # 小数点第4位を四捨五入し、文字列にする
    str_result_cal = str(Decimal(str(float_cal_data)).quantize(
        Decimal('0.001'), rounding=ROUND_HALF_UP))

    # 少数点[.]が出力される文字数を取得する。
    int_sep_num = str_result_cal.find(SEPARATE_TARGET)

    # 小数点[.]以下の文字(小数点第1位から3位)のみを取得
    result_data = str_result_cal[int_sep_num+1:]

    # 戻り値を返す。
    return result_data


def ChangeFileFormat():
    """
    ファイルのフォーマット変換関数

    引数:なし
    戻り値:なし

    処理概要:ファイルを読み込み、所定の書式に変換する処理
    """

    # 読み取りでインプットファイルを開く
    input_file = open(INPUT_FILE_NAME, 'r')
    # 書き込みモードでアウトプットファイルを作成
    output_file = open(OUTPUT_FILE_NAME, 'w')

    # カウンタの初期値をセット
    count = 1

    # ループ処理
    while True:

        # 1行ずつ取得
        read_line = input_file.readline()

        # 1行ずつ取得した値がなくなれば、ループ処理終了
        if not read_line:
            break

        # アウトプットファイル出力用の文字列を初期化
        result = ''

        # カウンタと改行を挿入
        result = str(count) + '\n'

        # 2文字ずつ間に「:」、「:」、「,」を挿入する
        result = result + read_line[0:2] + ':'
        result = result + read_line[2:4] + ':'
        result = result + read_line[4:6] + ','

        # 小数点以下第1位から3位までの値を取得
        point_1_3_first = CalDecimalPoint(read_line[6:8])

        # 計算結果を出力対象へ追記
        result = result + point_1_3_first

        # 半角スペースを「->」に変更
        result = result + '->'

        # 2文字ずつ間に「:」、「:」、「,」を挿入する
        result = result + read_line[9:11] + ':'
        result = result + read_line[11:13] + ':'
        result = result + read_line[13:15] + ','

        # 小数点以下第1位から3位までの値を取得
        point_1_3_second = CalDecimalPoint(read_line[15:17])

        # 計算結果を出力対象へ追記
        result = result + point_1_3_second

        # 改行を入れる
        result = result + '\n'

        # アウトプットファイルに出力
        output_file.write(result)

        # カウンタのインクリメント
        count = count + 1

    # ファイルをクローズ
    input_file.close()
    output_file.close()


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

■実行結果

・out_file.txt

1
00:00:01,200->00:00:01,250
2
00:00:01,500->00:00:01,750
3
12:34:56,167->11:12:13,233
4
01:02:03,667->01:02:03,917
5
00:20:01,333->00:20:01,500
6
00:30:01,500->00:30:01,700
7
00:40:01,517->00:40:01,717
8
00:50:01,550->00:50:01,733
9
02:00:01,567->02:00:01,767
タイトルとURLをコピーしました