---
paths: ["src/**", "scripts/**"]
---

# コーディング規約 (Coding Standards)

Python コード（`src/**`・`scripts/**`）を編集するときは本ルールに従うこと．

## 基本方針 (Basic Policy)

- ruff を唯一の lint / format ツールとして使用する．設定は `pyproject.toml` の `[tool.ruff]` に集約する．
- 標準（PEP 8）から逸脱しない範囲で ruff の自動修正に従う．
- プロジェクト固有のルールは本ファイルに最小限で書く．
- 別ツール（black・isort・mypy 等）は導入しない（ruff で完結させる）．

## 適用 ruff ルール (Ruff Rules)

`pyproject.toml` の `[tool.ruff.lint]` で `select = ["E", "F", "W", "I", "B", "UP", "N"]` を選択する．

| ルール | 内容 |
| --- | --- |
| E (pycodestyle) | PEP 8 形式エラー |
| F (pyflakes) | 未使用変数・未定義シンボル等 |
| W (pycodestyle) | 形式警告 |
| I (isort) | import 文の並び順 |
| B (flake8-bugbear) | バグになりやすいパターン検出 |
| UP (pyupgrade) | Python 3.12 の機能で書き換え可能なコードの提案 |
| N (pep8-naming) | クラス・関数・変数の命名 |

行長は 100 文字とする．実行コマンドは [ENV_04 開発コマンド](../../docs/02_ENV/ENV_04_開発コマンド.md)を参照する．

## 臨床データを扱うコードの規則 (Clinical Data Rules)

本プロジェクトの最重要規則．[PLAN_01 要件定義書](../../docs/03_PLAN/PLAN_01_要件定義書.md)の制約に対応する．

- **データのパスをコードに書かない**．データの場所は設定 YAML と環境変数から受け取る
- **ログ・例外メッセージに患者 ID・画像ファイル名を出さない**．個票が手元のログに流れるのを防ぐため，件数・行番号・クラス名で示す（例外処理の詳細は `.claude/rules/error-handling.md`）
- `print` ではなく `logging` を使う（サーバ実行のログが `runs/<実験ID>/log.txt` に残るため）

## 機械学習コードの規則 (ML Code Rules)

- **乱数はグローバル状態に依存しない**．seed を引数・設定から受け取り，実際に使った値を `config.yaml` に記録する
- **デバイスをハードコードしない**．`cuda:0` を直書きせず設定から受け取る（共用サーバのため GPU 指定が必要）
- **テンソルの形状を docstring に書く**（例: `(B, C, H, W)`）．形状の取り違えは ML コードの主要なバグ源である
- 学習のハイパーパラメータは設定 YAML に置き，コードに既定値を散らさない

## 型ヒント (Type Hints)

- **公開関数（モジュールから export される関数・クラス）**: 引数と戻り値に型ヒント必須
- **内部ヘルパ・テストコード**: 任意．書ける所は書く
- `torch.Tensor`・`np.ndarray` は型だけでは情報が足りないため，要素型と形状を docstring で補う

静的型チェック（mypy / pyright）は当面導入しない．必要が出てから追加する．

## docstring

- **公開関数・クラス**: docstring 必須
- **書式**: Google スタイル（`Args:` / `Returns:` / `Raises:`）に統一
- **言語**: 日本語可

例:

```python
import torch


def normalize_batch(images: torch.Tensor, mean: torch.Tensor, std: torch.Tensor) -> torch.Tensor:
    """バッチ画像を ImageNet の統計で正規化する．

    Args:
        images: 入力画像（`(B, 3, H, W)`, float32, 値域 0.0〜1.0）．
        mean: チャンネルごとの平均（`(3,)`）．
        std: チャンネルごとの標準偏差（`(3,)`）．

    Returns:
        正規化後の画像（`(B, 3, H, W)`, float32）．
    """
```

## 命名規則 (Naming)

ruff `N` ルールでチェックする．

| 対象 | スタイル | 例 |
| --- | --- | --- |
| モジュール | snake_case | `manifest.py`・`patient_split.py` |
| パッケージ | snake_case | `tias_judge_model` |
| 関数・変数 | snake_case | `load_manifest`・`macro_f1` |
| クラス | PascalCase | `TongueColorDataset`・`TrainConfig` |
| 定数 | UPPER_SNAKE_CASE | `CLASS_SLUGS` |
| プライベート | 接頭辞 `_` | `_validate_manifest` |

## コメント (Comments)

- **WHY を書く**: 何をしているかは識別子で表現し，コメントは「なぜこの実装か」「制約」「出典」に限定する
- **TODO** は `# TODO(rintoHasegawa): 内容` 形式で記述する

## import 順序 (Import Order)

ruff `I` で自動整列する．手動整列は不要．

1. 標準ライブラリ
2. サードパーティ（`torch`・`timm`・`numpy` 等）
3. プロジェクト内（`from tias_judge_model import ...`）

## CLI 引数 (CLI Arguments)

- 短縮形より長い形を優先する（`--config` を主とする）
- `argparse` 標準を使用する
- ヘルプ文は日本語可

## 参考 (References)

- [PEP 8 — Style Guide for Python Code](https://peps.python.org/pep-0008/)
- [Google Python Style Guide — Docstrings](https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings)
- [ruff documentation](https://docs.astral.sh/ruff/)
