report-review

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | Submodules | README | LICENSE

integrate_data.py (5568B)


      1 import glob
      2 import json
      3 import os
      4 from typing import Any, Dict, List, Tuple
      5 
      6 
      7 def integrate_and_format_data(data_pairs: List[Dict[str, str]], output_file_path: str):
      8     """
      9     Typstファイルと構造化JSONファイルを統合し、学習用のJSON Lines形式に変換する。
     10 
     11     Args:
     12         data_pairs: TypstファイルパスとJSONファイルパスの辞書のリスト。
     13         output_file_path: 出力するJSON Linesファイルパス。
     14     """
     15 
     16     formatted_data = []
     17     processed_count = 0
     18 
     19     for pair in data_pairs:
     20         typst_path = pair["typst_file"]
     21         json_path = pair["json_file"]
     22 
     23         if not os.path.exists(typst_path) or not os.path.exists(json_path):
     24             print(
     25                 f"警告: ファイルペアが見つかりません - Typst: {typst_path}, JSON: {json_path}"
     26             )
     27             continue
     28 
     29         try:
     30             # 1. Typstファイルの内容を読み込む
     31             with open(typst_path, "r", encoding="utf-8") as f:
     32                 typst_content = f.read()
     33 
     34             # 2. 構造化されたJSONのフィードバックリストを読み込む
     35             with open(json_path, "r", encoding="utf-8") as f:
     36                 feedback_items = json.load(f)
     37 
     38             # 3. フィードバックリストをJSON文字列に変換
     39             #    改行やスペースを除去し、整形された単一のJSON文字列にする
     40             feedback_output = json.dumps(
     41                 feedback_items, ensure_ascii=False, separators=(",", ":")
     42             )
     43 
     44             # 4. LLM学習用のInstruction/Outputペアを作成
     45             learning_example = {"instruction": typst_content, "output": feedback_output}
     46 
     47             formatted_data.append(learning_example)
     48             processed_count += 1
     49             print(f"統合完了 ({processed_count}件目): {typst_path} と {json_path}")
     50 
     51         except Exception as e:
     52             print(f"エラー処理: {typst_path} / {json_path} - {e}")
     53 
     54     # 5. すべてのデータをJSON Lines形式でファイルに書き出す
     55     with open(output_file_path, "w", encoding="utf-8") as outfile:
     56         for entry in formatted_data:
     57             json.dump(entry, outfile, ensure_ascii=False)
     58             outfile.write("\n")
     59 
     60     print("\n--- 処理完了 ---")
     61     print(
     62         f"合計 {len(formatted_data)} 件の学習データが {output_file_path} に出力されました。"
     63     )
     64 
     65 
     66 def find_file_pairs(
     67     reports_dir: str, structured_dir: str, typst_base: str, json_base: str
     68 ) -> List[Dict[str, str]]:
     69     """
     70     構造化JSONファイルと連番に基づいて、対応するTypstファイルを検索し、ペアのリストを返す。
     71     """
     72     data_pairs = []
     73     # 例: structured-feedback/structured_data_*.json にマッチ
     74     search_pattern = os.path.join(structured_dir, f"{json_base}_*.json")
     75     json_files = glob.glob(search_pattern)
     76 
     77     for json_file_path in json_files:
     78         try:
     79             # structured_data_NNN.json から NNN を抽出
     80             base_filename = os.path.basename(json_file_path)
     81             parts = base_filename.replace(f"{json_base}_", "").split(".")
     82             if len(parts) < 2 or not parts[0].isdigit():
     83                 continue
     84 
     85             sequence_num_str = parts[0]
     86 
     87             # 対応するTypstファイル名を構築 (例: reports/report001.typ)
     88             typst_file_name = f"{typst_base}{sequence_num_str}.typ"
     89             typst_file_path = os.path.join(reports_dir, typst_file_name)
     90 
     91             if os.path.exists(typst_file_path):
     92                 data_pairs.append(
     93                     {
     94                         "typst_file": typst_file_path,
     95                         "json_file": json_file_path,
     96                     }
     97                 )
     98             else:
     99                 print(
    100                     f"警告: JSONファイル {base_filename} に対応するTypstファイル "
    101                     f"({typst_file_name}) が {reports_dir} に見つかりませんでした。スキップします。"
    102                 )
    103         except Exception as e:
    104             print(f"ファイルペアリング中にエラーが発生しました ({json_file_path}): {e}")
    105 
    106     return data_pairs
    107 
    108 
    109 if __name__ == "__main__":
    110     # === 設定箇所 (ディレクトリとファイル名のベース) ===
    111 
    112     # Typstファイルが格納されているディレクトリ
    113     REPORTS_DIR = "reports"
    114     # 構造化JSONファイルが格納されているディレクトリ
    115     STRUCTURED_DIR = "structured-feedback"
    116     # Typstファイルのベース名 (例: report001.typ の 'report')
    117     TYPST_BASE_NAME = "report"
    118     # 構造化JSONファイルのベース名 (例: structured_data_001.json の 'structured_data')
    119     JSON_BASE_NAME = "structured_data"
    120 
    121     OUTPUT_FILE_NAME = "typst_feedback_dataset.jsonl"
    122 
    123     # === スクリプト実行 ===
    124 
    125     # 構造化JSONファイルに基づいて、対応するTypstファイルを自動的に検索・ペアリング
    126     file_pairs = find_file_pairs(
    127         reports_dir=REPORTS_DIR,
    128         structured_dir=STRUCTURED_DIR,
    129         typst_base=TYPST_BASE_NAME,
    130         json_base=JSON_BASE_NAME,
    131     )
    132 
    133     if not file_pairs:
    134         print(
    135             "エラー: 処理対象のファイルペアが見つかりませんでした。ディレクトリとファイル名を確認してください。"
    136         )
    137     else:
    138         integrate_and_format_data(file_pairs, OUTPUT_FILE_NAME)