成績判定プログラム
成績判定プログラム とは
if文を使って、入力された点数に応じて成績を判定するプログラムを実装します。本レッスンでは、成績判定プログラム の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。
5 段階で成績を判定する
これまでに if と else を使って「真ん中で 2 つに分ける」条件分岐を書いてきました。今回はそこから一歩進んで、A B C D F の 5 段階に枝分かれする判定ロジックを書いていきます。学校の成績表のように、点数を「90 点以上は A」「80 点以上は B」と段階的に振り分けていく、現実によく出てくるパターンです。
多段階の条件分岐は、業務でも本当に頻繁に登場します。会員ランクの判定、料金プランの選択、配送区分の決定、ゲームのレベル判定など、「数値の範囲ごとにラベルを返す」処理はあらゆるシステムの中核にあります。ここで
else ifの書き方をしっかり身につけておくと、後がぐっと楽になります。
コードに入る前に、まず「成績判定とは何をしている処理か」を整理しておきましょう。やりたいのは、int score という整数を受け取って、その大きさによって String を返すことです。Java ではこれを if else if else の組み合わせで自然に書けます。
仕様のおさらい
今回のメソッドは Solution.getGrade(int score) です。0 から 100 までの点数を受け取り、次の対応で String を返します。
90以上 →"A"80以上 →"B"70以上 →"C"60以上 →"D"- それ未満 →
"F"
境界に注目してください。「90 以上」と書いてあるので、ちょうど 90 点は "A" です。89 点は "B" です。境界値をどちらに含めるかは仕様で必ず決まっているので、勝手に解釈を変えないようにしましょう。
仕様書に「以上 (
>=)」と書いてあるか「より大きい (>)」と書いてあるかは、プログラミングの世界では決定的に重要な違いです。ユーザーから見れば 1 点の差ですが、テストはピンポイントで境界を狙ってきます。>=と>の区別はこれから何度も登場するので、いま完全に理解しておきましょう。
else if で多段階に分ける
まずシンプルに書いてみます。if の後ろに else if を並べて、最後に else で受けるのが基本形です。
Java
public class Solution {
public static String getGrade(int score) {
if (score >= 90) {
return "A";
} else if (score >= 80) {
return "B";
} else if (score >= 70) {
return "C";
} else if (score >= 60) {
return "D";
} else {
return "F";
}
}
}この書き方では、上から順番に条件をチェックしていきます。score = 85 が来た場合の動きを追ってみましょう。最初の score >= 90 は false、次の score >= 80 で true になるので "B" が返って、メソッドはそこで終了します。下の score >= 70 以降は 評価すらされない のがポイントです。
図を見ると、上から順番に条件を絞り込んでいる様子がよくわかります。if else if の連鎖は「大きい順 (または小さい順) に並べて、最初にヒットしたものを返す」という流れで読むと一気に理解しやすくなります。
順序が決定的に重要
ここがこのレッスンの最大の落とし穴です。if else if を どの順番で並べるか によって、結果が変わってしまいます。たとえば次のように、下から並べたらどうなるでしょうか。
Java
public class Solution {
public static String getGrade(int score) {
if (score >= 60) {
return "D";
} else if (score >= 70) {
return "C";
} else if (score >= 80) {
return "B";
} else if (score >= 90) {
return "A";
} else {
return "F";
}
}
}一見もっともらしく見えますが、これは 完全に壊れています。score = 95 を入れたとしましょう。最初の score >= 60 がいきなり true になるので、"D" が返ってしまいます。90 以上を判定する else if には永遠にたどり着きません。
else ifのチェーンは、上から並んだ条件を順番にしか見ません。重なり合う範囲がある場合は、狭い (厳しい) 条件から先に書く のが鉄則です。>=で書く場合は「大きい順」、<=で書く場合は「小さい順」と覚えておきましょう。
もうひとつの解決策は、else if を使わずに各条件を独立した範囲として書くことです。たとえば次のような書き方もできます。
Java
public class Solution {
public static String getGrade(int score) {
if (score >= 90 && score <= 100) {
return "A";
}
if (score >= 80 && score < 90) {
return "B";
}
if (score >= 70 && score < 80) {
return "C";
}
if (score >= 60 && score < 70) {
return "D";
}
return "F";
}
}動きはしますが、条件が長くなって読みづらく、80 90 のような境界値がコードに何度も出てきます。最初の else if チェーン版のほうが圧倒的に簡潔で、ミスも起こりにくいです。慣れたうえで使い分けてください。
境界値の挙動を確かめる
仕様で 90 以上が "A" と決まっているので、score = 90 はちょうど "A" になります。score = 89 は "B" です。同じように score = 60 は "D" で、score = 59 は "F" です。境界値はバグが集中しやすい場所なので、必ず自分で値を入れて確認する習慣をつけましょう。
境界の挙動を if 文の言葉で書き直すと、それぞれの段階が受け持つ範囲は次のとおりです。
"A"の範囲 —90 <= score <= 100"B"の範囲 —80 <= score < 90"C"の範囲 —70 <= score < 80"D"の範囲 —60 <= score < 70"F"の範囲 —score < 60
隣り合う範囲が 重ならず、隙間も空かない ように作るのがコツです。else if のチェーン版なら、上の条件で弾かれた時点で「それ未満」が自動的に保証されるので、score < 90 のような上限の条件を明示する必要がありません。これが else if の便利なところです。
業務でよく見るバグに「
60点が"D"ではなく"F"になる」「90点が"A"ではなく"B"になる」というものがあります。原因はだいたい>=を>と書いてしまった1文字のミスです。境界値テストはこの種のバグを必ず捕まえてくれるので、テストケースに必ず混ぜましょう。
よくある間違い
成績判定を書くとき、初学者がよくハマるポイントを 4 つ紹介します。
>=を>と書いてしまう — 「90以上」のつもりでif (score > 90)と書くと、ちょうど90点が"A"ではなく"B"に落ちてしまいます。「以上」は>=、「より大きい」は>、と日本語と記号を必ずペアで覚えてください- 条件の順序を逆にしてしまう —
if (score >= 60) ... else if (score >= 70) ...のように下から並べると、70点以上の人もみんな最初のscore >= 60でヒットしてしまい、"D"のままになります。else ifチェーンは必ず狭い (厳しい) 条件から書く - 範囲を重複させる —
if (score >= 90)とelse if (score >= 80 && score < 95)のように、範囲が重なる書き方をすると、どちらにヒットするかが順番に依存してしまい、読む人を混乱させます。境界はきっちり閉じる elseを忘れて漏れを作る —else if (score >= 60)で止めてelseを書かないと、50点のときに"F"を返す経路がなくなり、コンパイラに「missing return statement」と怒られます。多段階のifの最後は必ずelseで受ける
これらは Java に限らず、他のあらゆる言語の条件分岐で起こる典型的なミスです。一度しっかりパターンを覚えてしまえば、ほぼ無意識に避けられるようになります。
やってみよう
右側のエディタを開いて、Solution.getGrade(int score) を完成させましょう。手順は次のとおりです。
if (score >= 90)から始めるelse if (score >= 80)else if (score >= 70)else if (score >= 60)と続ける- 最後の
elseで"F"を返す - 「実行」ボタンを押して、すべてのテストが緑になることを確認する
テストが通ったら、自分でいくつか境界値を試してみてください。getGrade(90) getGrade(89) getGrade(60) getGrade(59) getGrade(100) getGrade(0) あたりが面白いはずです。値を変えながら出力を眺めると、>= のふるまいが感覚として身につきます。
さらに余裕があれば、次のような拡張も考えてみましょう。score がマイナスや 101 以上のときに「不正な点数」というメッセージを返すように先頭に if を 1 つ足す。あるいは、A+ A A- のようなプラスマイナスつきの細かい判定にしてみる。実務で出てくる条件分岐は、たいていこうした「特殊ケースの先回り」と「細分化」の積み重ねでできています。
条件分岐は単純に見えて、組み合わせるとアプリの動きそのものを決める力を持ちます。if else if else のリズムを体に染み込ませて、次のレッスンへ進みましょう。
次のレッスン
次は うるう年を判定する で、if文を使って、入力された点数に応じて成績を判定するプログラムを実装します を学びます。
事前確認 — 進む前に次の 3 つができることを確認しましょう。
- 成績判定 の要点を自分の言葉で説明できる
- このレッスンの最小コード (または操作手順) を見ずに書ける
- 練習問題やクイズで間違えた箇所を読み直して理解した
理解度チェック (30 秒)
Q. 成績判定 とは何か、1 文で説明してください。
A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。
関連レッスン
要件
- 90点以上: A
- 80点以上: B
- 70点以上: C
- 60点以上: D
- 60点未満: F
入出力例
test-cases.txt
getGrade(95) → "A"
getGrade(85) → "B"
getGrade(75) → "C"
getGrade(65) → "D"
getGrade(45) → "F"