1. 目的と境界
Student 2 の複数参加者マッチングだけを、 標準ライブラリのみの単一 Python ファイルで動かし、 「ゲート → ペア採点 → 貪欲グループ」の構造を体感するためのデモです。 この HTML は想定構成の説明であり、デモ実行本体ではありません。
flowchart LR
subgraph Goal["デモのゴール"]
U["python matching_demo.py
--scenario A"] --> R["除外 / ペア点 / グループを
ターミナルに表示"]
end
subgraph Out["スコープ外"]
DB[(DB)]
API[HTTP API]
GEN[Event 生成]
LOG[AI ログ]
WEB[ブラウザ UI]
end
Goal -.->|接続しない| Out
図 1 — デモはマッチング理解専用。永続化・生成・ログ・Web UI は切る。
matching_demo.py。
依存は Python 標準ライブラリのみ(dataclasses / datetime / argparse など)。
FastAPI・pytest・プロジェクトの app.* は import しない。
2. 入れるもの/切るもの
flowchart TB
subgraph IN["matching_demo.py に入れる"]
C["設定定数"]
T["時刻ユーティリティ"]
D["候補・Beacon・プロフィール"]
G["除外ゲート"]
P["ペア採点 7要因"]
F["貪欲グループ形成"]
V["CLI 出力
print / 整形テーブル"]
end
subgraph OUT["入れない"]
S["status API / DB"]
M["micro_event_generator"]
A["ai_event_logs"]
O["オーケストレーション"]
Auth["認証"]
HTML["HTML / JS / CDN"]
PIP["サードパーティ pip"]
end
IN ~~~ OUT
図 2 — 含有範囲のブロック図。
| 区分 | 要素 | |
|---|---|---|
| 入れる | 重み・閾値・準備分・人数上下限 | 設定 |
| 入れる | 区間交差・クリップ・共通分数 | 時刻 |
| 入れる | 候補 / Beacon / プロフィールのインメモリ構造 | 入力 |
| 入れる | 除外 → ペア → グループ → score_detail | コア |
| 入れる | argparse でシナリオ選択・結果を stdout に整形出力 | CLI |
| 切る | PostgreSQL / Redis / FastAPI / Next | 基盤 |
| 切る | Event 作成・カテゴリ・manager・自動 Join | 生成 |
| 切る | 時限文字列の本番パーサ(デモは時刻直書き可) | 簡略化 |
| 切る | from app... や pip パッケージ | 依存 |
3. ファイル内の論理ブロック
形式は 1 つの Python ファイル。
マッチング本体は純関数/ローカル dataclass のみで完結させ、
末尾の main() がシナリオ読込 → 実行 → 印刷を行う。
flowchart TB FILE["matching_demo.py(単一ファイル)"] FILE --> B1["① CONFIG
重み・閾値・定数"] FILE --> B2["② TYPES / FIXTURES
dataclass + シナリオ辞書"] FILE --> B3["③ TIME UTILS
交差・結合・準備後クリップ"] FILE --> B4["④ SCORING
7要因 + 加重合計"] FILE --> B5["⑤ PIPELINE
filter → pairs → groups"] FILE --> B6["⑥ CLI
argparse / print_report"] B1 --> B5 B2 --> B5 B3 --> B4 B4 --> B5 B5 --> B6 B2 --> B6
図 3 — 単一ファイル内部のブロック構成と依存方向。
main から採点式を直書きせず、run_matching(...) 一本に集約すると、本番の
matching_service.run_matching と対応が取りやすい。
4. データモデル(デモ入力)
erDiagram
CANDIDATE ||--o{ INTERVAL : has
CANDIDATE }o--o| BEACON : current_location
PROFILE ||--|| CANDIDATE : same_student
PROFILE }o--o{ PROFILE : friends
RUN ||--|{ CANDIDATE : inputs
RUN ||--|{ BEACON : catalog
RUN ||--o{ DUPSET : duplicate_sets
CANDIDATE {
string student_id
string[] intents
datetime expires_at
string location_id
}
INTERVAL {
datetime start
datetime end
}
BEACON {
string id
int capacity
int max_parallel
string building_id
string campus_id
}
PROFILE {
string student_id
string department_id
string[] friend_ids
}
DUPSET {
string[] student_ids
}
図 4 — デモが扱う入力エンティティ(永続化なし)。Python では @dataclass(frozen=True) を推奨。
1 回の実行に渡す塊
now— 固定時刻(再現性のためシナリオに埋め込み)candidates: list[Candidate]— 参加者スナップショットbeacons: dict[str, Beacon]— 場所カタログprofiles: dict[str, Profile]— 学科・友人interests— 省略可(常にNone→ 0.50)duplicate_student_sets: frozenset[frozenset[str]]— 既 ACTIVE 相当(任意)
5. データフロー(実行時)
flowchart LR IN["Scenario
候補 N 人"] --> GATE["除外ゲート"] GATE --> ELIG["eligible"] GATE --> EX["exclusions"] ELIG --> PAIR["全ペア採点"] PAIR --> EDGES["edges ≥ 0.60"] PAIR --> ALLP["全 pair_scores"] EDGES --> FORM["貪欲グループ
2〜5人"] FORM --> GROUPS["groups
score ≥ 0.70"] FORM --> REJECT["閾値未満グループ"] ELIG --> PLACE["Beacon 選定"] PLACE --> FORM EX --> VIEW["print_report"] ALLP --> VIEW GROUPS --> VIEW REJECT --> VIEW
図 5 — 実行時データフロー。右端は stdout への観察ポイント。
sequenceDiagram
participant CLI as main / argparse
participant Run as run_matching
participant Gate as filter_eligible
participant Score as score_pair
participant Form as form_groups
participant Out as print_report
CLI->>Run: scenario (candidates, beacons, profiles, now)
Run->>Gate: candidates
Gate-->>Run: eligible + exclusions
loop 全ペア
Run->>Score: (a, b)
Score-->>Run: factors + total
end
Run->>Form: edges ≥ 0.60
Form-->>Run: groups + selection_score
Run-->>CLI: MatchingResult
CLI->>Out: result
Out-->>CLI: stdout(3セクション)
図 6 — CLI とコア関数のシーケンス。
ゲートで落ちる典型
flowchart TD
C["候補"] --> Q1{"expires_at > now
かつ空きあり?"}
Q1 -->|No| X1["inactive / NO_AVAILABILITY"]
Q1 -->|Yes| Q2{"準備15分後に
残り ≥ 30分?"}
Q2 -->|No| X2["insufficient_remaining_time"]
Q2 -->|Yes| Q3{"適合 Beacon あり?"}
Q3 -->|No| X3["no_suitable_beacon / parallel_full"]
Q3 -->|Yes| Q4{"duplicate set でない?"}
Q4 -->|No| X4["duplicate_candidate_event"]
Q4 -->|Yes| OK["eligible"]
図 7 — 除外ゲート詳細(スコア前)。
6. CLI / 出力の想定構成
flowchart TB
subgraph Entry["起動"]
CMD["python matching_demo.py
--scenario A|B|C|D|E
[--list]"]
end
subgraph Load["読込"]
SC["SCENARIOS[name]
now / candidates / beacons / ..."]
end
subgraph Core["コア"]
RUN["run_matching(...)"]
end
subgraph Out["stdout 3 セクション"]
R1["[1] Exclusions
student_id + reason_code"]
R2["[2] Pair scores
総合点 + 7要因"]
R3["[3] Groups
members / beacon / scores"]
end
CMD --> SC --> RUN --> Out
図 8 — CLI ブロック。結果は必ず 3 セクションを順に出すと構造が伝わる。
| セクション | 見せるもの | 理解ポイント |
|---|---|---|
| [1] Exclusions | student_id + reason_code | スコア以前に落ちる条件 |
| [2] Pair scores | 辺ごとの 7 要因と合計、閾値 0.60 | 説明可能性 |
| [3] Groups | メンバー、matching / selection、選定 Beacon | 貪欲・非再利用・0.70 |
起動例
python matching_demo.py --list— シナリオ一覧python matching_demo.py --scenario A— 成功パスpython matching_demo.py --scenario C— 複数グループ
対話編集 UI は必須ではない。シナリオはファイル内の辞書を書き換えて再実行する形で十分。
必要なら後から --scenario 以外のフラグを足す。
7. 埋め込みシナリオ(推奨セット)
flowchart LR S0["共通 now
Beacon 2〜3"] --> S1["Scenario A
3人: 揃う → 1グループ"] S0 --> S2["Scenario B
空き不足 → 除外"] S0 --> S3["Scenario C
6人: 2グループ + 余り"] S0 --> S4["Scenario D
duplicate set → 除外"] S0 --> S5["Scenario E
友人・同学科で加点差"]
図 9 — 学習用シナリオの分岐。A→C→D の順で見ると理解が進む。
- A: intent・時間・同一 Beacon が重なり、ペア・グループとも閾値超過
- B: 共通時間が準備後に 30 分未満 → ゲート落ち
- C: 人数が多く、貪欲の非再利用で第2グループ/余りが出る
- D: 同じ候補集合が
duplicate_student_setsにあり除外 - E: 低重み(友人 0.05 / 学科 0.05)の差が表で見える
8. 本番コードとの対応
flowchart LR
subgraph Demo["matching_demo.py"]
D1["CONFIG"]
D2["time utils"]
D3["score_pair / form_groups"]
D4["run_matching"]
D5["main / print_report"]
end
subgraph Prod["リポジトリ"]
P1["student2/config.py"]
P2["student2/availability.py"]
P3["matching_service.py"]
P4["run_matching"]
P5["orchestration / API"]
end
D1 -.対応.-> P1
D2 -.対応.-> P2
D3 -.対応.-> P3
D4 -.対応.-> P4
D5 -.デモ専用.-> P5
図 10 — デモブロックと本番モジュールの対応。CLI 以降は本番と切り離してよい。
| デモ | 本番 |
|---|---|
CONFIG 定数 | app/student2/config.py |
| 区間ユーティリティ | availability.py + matching 内の interval 関数 |
run_matching | matching_service.run_matching |
| fixture / SCENARIOS | StatusStore + Port(Beacon/Profile)の代わり |
main / print_report | デモ専用(API や画面には載せない) |
| (なし) | micro_event_generator / API / DB |
9. ソース配置スケッチ
1 ファイル内の定義順(上から下)の目安です。
docs/human/demos/matching_demo.py
(人間向けドキュメント配下)。本番の backend/app/ には混ぜず、
from app... も行わない。
実行例:
python docs/human/demos/matching_demo.py --scenario A
関連:
Student 2 完了実装ガイド
· 本番ロジック正本 backend/app/services/matching_service.py