31番だけ色がない——Math.ceil の落とし穴とCSSクラス設計
番号ボールの色をMath.ceil(n/10)で出したら31番だけball-4になってCSSがなかった。たった1行の修正で解決した話
登場人物
- リナ社長 … 高校生なのに会社経営するやり手ギャル。テックにも強くてAI活用が得意。
- タクヤ … 入社3年目の男性社員。真面目で少しだけコードが書ける。
タクヤ「社長、一覧テーブルで31番だけ白く見えます。背景色がないみたいで……」
リナ社長「あ、まじじゃん。てかこれ完全に計算ミスだわ」
タクヤ「計算ミスって、数字の計算ですか?」
リナ社長「そー。Claudeが書いたコードに微妙なバグがあった。ちょっと一緒に見てみよ」
何が起きたのか
ミニロト解析ページでは番号ボールの色を数字の範囲で分けている。
| 範囲 | 色 | CSSクラス |
|---|---|---|
| 1〜10 | 青 | ball-1 |
| 11〜20 | 緑 | ball-2 |
| 21〜30 | オレンジ | ball-3 |
この色分けをAstroテンプレートでこう実装していた:
<span class={`ball ball-${Math.ceil(n / 10)}`}>
{String(n).padStart(2, '0')}
</span>
タクヤ「Math.ceil(n / 10) で1〜10は1、11〜20は2……ってなるわけですね」
リナ社長「そーそー。でも31は?」
タクヤ「31 ÷ 10 = 3.1、切り上げで……4!あ、ball-4 になる」
リナ社長「そういうこと。ball-4 なんてCSSに定義してないから色なしになってた」
なぜミニロトで問題が起きるのか
普通のロト6(1〜43)やロト7(1〜37)なら「10ごとに色を分ける」設計でも4グループや5グループのCSSを用意すれば問題ない。
でもミニロトの数字範囲は 1〜31 。
Math.ceil(31 / 10) = 4 になるのに、定義したCSSクラスは ball-1〜ball-3 の3つだけ。31だけが孤立する。
タクヤ「ミニロトって31までしかないから、31が1個だけ仲間外れになっちゃうんですね」
リナ社長「そーなの。“10で割って切り上げ”って式は1〜30なら完璧なんだけど、31があることを考慮してなかった」
解決策:Math.min で上限を3に固定する
直し方はシンプル。Math.ceil の結果が3を超えないように Math.min で上限を指定するだけ。
<!-- ❌ Before(31がball-4になってしまう) -->
<span class={`ball ball-${Math.ceil(n / 10)}`}>
<!-- ✅ After(上限を3に固定) -->
<span class={`ball ball-${Math.min(Math.ceil(n / 10), 3)}`}>
これで Math.ceil(31 / 10) = 4 になっても Math.min(4, 3) = 3 で ball-3(オレンジ)が適用される。
タクヤ「たった1箇所直すだけで解決するんですね」
リナ社長「ただ、同じ式を4箇所で使ってたから全部直さないといけなかった。ヒーローセクション・ホット数字・コールド数字・一覧テーブルの4箇所ね」
タクヤ「同じロジックが複数箇所にあるのか……」
リナ社長「理想はヘルパー関数にまとめることなんだけど、今回はサクッと直す優先で。ワンチャンリファクタは後でもいいしね」
こういうバグを防ぐには
タクヤ「最初からバグを防ぐ方法ってあるんですか?」
リナ社長「あるよ。今回の場合だと、最初にClaudeへの指示に数字範囲を明示することかな」
ミニロトは1〜31の番号を使う。
色分けは1〜10が青、11〜20が緑、21〜31がオレンジ。
31番も必ずオレンジになるようにすること。
タクヤ「仕様を具体的に書くだけで違うんですね」
リナ社長「そー!“10ごとに色分け”って言い方だとAIが素直に実装して31の端数を見落とす。“21〜31はオレンジ”って書けば31を考慮した実装が出てくる」
ポイントまとめ
リナ社長「まとめるとこれ」
- 数値でCSSクラスを生成するときは端数に注意 → 今回は31が範囲外のクラスを生成していた
Math.minで上限を固定するのが簡単な解決策 →Math.min(Math.ceil(n / 10), 3)- AIへの指示は”例外ケース”も明記する → “21〜31はオレンジ”のように境界を具体的に伝える
タクヤ「これ、AIが書いたコードでも自分で検証することが大事ってことですよね」
リナ社長「まじそれ!AIを信頼しすぎず、ちゃんと動くか見てあげることが大事。AIと人間のいいコンビネーションがえぐい成果を生む、っしょ」
コメント