その初陣が、網を張った翌々日に来ました。しかも稼働1日目にして、いきなり複数の乱れが同時に。今回はその初陣が暴いた、「同じ出来事を、どう”1つ”と数えるか」という、地味だけど奥の深い問題の話です。
Contents
まず結論
1つの乱れを記録しようとしただけで、記録の仕組みに4つの欠陥が連鎖的に見つかりました。そして最後は、たった1つの原則に収束しました。
同じ出来事かどうかは、「名前」ではなく「実体」で判定する。
この原則にたどり着くまでの道のりが、今週いちばんの学びでした。
観測網の初陣:稼働1日目に、乱れが来た
JRの観測を始めて早々、屋外の路線がいくつか乱れました。前回書いたとおり、私はまだ「アプリ」を作っていません。あるのは、乱れを見つけたらその断面を自動で保存する「記録機構」だけ。この初陣は、その記録機構にとっての初めての実戦でした。
そして実戦は、机上では見えなかった穴を、次々にあぶり出しました。
1つの乱れが、4つの欠陥を連鎖的に暴いた
記録機構のバグは、1つ直すと次が顔を出す、という連鎖で現れました。初学者向けに、性質だけ並べます(どれも「同じ乱れを正しく1件として保存する」ための問題です)。
- 早すぎる確定:まだ進行中の乱れを「もう終わった」と勘違いして、途中で記録を締めてしまう
- 初動の取りこぼし:公式の発表が実際の発生より遅れるため、発表を待って記録すると、乱れ始めの一番大事な数分が抜ける
- 終わりが伸びると、二度と更新できない:一度記録した乱れが実はまだ続いていても、「もう保存済み」と判断してその後を無視してしまう
- 始まりが動くと、”双子”が生まれる:同じ乱れなのに、開始時刻の見え方が変わった拍子に、別物として2件登録されてしまう
この4つ目——「双子」が、今回の核心でした。
なぜ「双子」が生まれたのか
私は最初、「同じ出来事かどうか」を名前(ラベル)で見分けていました。ざっくり言うと「○時○分に始まった、△△という原因の乱れ」というような名札で管理していたのです。
ところが乱れというのは生き物で、観測が進むと”始まり”の見え方が変わります。あとから「実はもっと早く始まっていた」と分かることがある。すると名札の時刻部分が変わり、システムは「別の出来事だ」と勘違いして、同じ乱れをもう1件、二重に保存してしまった。これが双子の正体でした。
解決:同一性を「名前」ではなく「実体」で判定する
ここで効いたのが、前作からの積み重ねでした。答えは、見分け方そのものを変えることだったのです。
名前で比べるのをやめて、「時間帯が重なっているかどうか」で判定するようにしました。名札が違っても、同じ時間帯を占めている乱れなら、それは同じ乱れとみなす。人間なら当たり前にやっている判断——「呼び方は違うけど、あれとこれ、同じ事件だよね」——を、そのまま仕組みにしたわけです。
初学者向けに、今日の一番の学びを言葉にすると、こうです。
ものの”同じ・違う”を、貼ったラベルで判断すると、ラベルが変わった瞬間に破綻する。
中身(実体)そのもので判断すれば、ラベルが揺れても揺るがない。
そして、このブログで何度も出てきた原則——「真実は1箇所に」——が、ここでも顔を出しました。以前つけた応急処置と、今回の新しい判定が二重に残ると、また混乱の種になる。だから判定するコードは1箇所に統合し、古い見分け方は消しました。
修正の確認は「正しく動く」だけでなく「余計に動かない」まで
もう一つ、確認のやり方で大事なことを学びました。双子を統合する仕組みは強力です。でも強すぎると、今度は「本当は別々の、2つの乱れまで1つにまとめてしまう」危険が出てきます。
だから確認では、逆側も必ず試しました。「時間帯が重なっていない2つの乱れは、ちゃんと別々の2件として残るか」。修正のたびに、その逆の壊れ方を1つ試す——これは前作からずっと続けている型です。
極めつきは、最後の確認でした。掃除を終えたあと、記録機構を実際に走らせて「何も起きないこと」=「アーカイブ対象はありませんでした」と正しく沈黙することを確かめたのです。直したあとに見るべきは「ちゃんと動くこと」だけでなく、「余計に動かないこと」でもある。一見地味な「何もしませんでした」というログが、今回は合格の証明でした。
おまけの発見:2つの目は、補い合う
初陣では、うれしい発見もありました。私はJRを2種類のデータ源で観ています。ひとつは電車の位置そのもの、もうひとつは公式の運行情報のテキストです。
この初陣で、両者の関係がはっきりしました。ある乱れは位置データのほうが公式発表より早く捉えました。ところが別の乱れは、逆に公式テキストには出たのに、位置データはほとんど動かなかった。本線に影響しない、特定の系統だけの出来事だったからです。
つまり、どちらか一方だけでは、乱れの全体像が必ず欠ける。最初から2つの目を並走させておいた判断が、初陣で早くも報われた形でした。「片方が沈黙しても、もう片方が拾う」——これも、前作で学んだ「見ていない場所のことは画面に出ない」への、私なりの答えです。
おわりに ── まだ「アプリ」は1行も書いていない
ここまでやって、面白いのは——私はまだ、JR版の「アプリ」を1行も書いていないということです。今週やったのは全部、「乱れを正しく記録する」ための土台固めでした。
でも、これでいいと思っています。前回書いたとおり、順番は「まず正確な観測、予報はそのあと」。記録が信用できないうちに予報を作っても、砂の上の城です。今週、初陣が暴いた4つの穴をふさいだことで、記録機構は「早すぎる確定」「初動の欠落」「終わりの伸び」「始まりのブレ」すべてに耐える形になりました。ようやく、信用できる観測台が組み上がったところです。
浅草線の「到着35分?」から、12日。次にこの観測台が、JRの本格的な乱れの日に何を写すのか。網は、いよいよ本物になってきました。
個人開発 / 観測フェーズ / データ設計 / JR
このブログでは、ローカルLLM・Aider・個人開発の試行錯誤をそのまま記録しています。
