成績判定プログラム

生田 陸人
LuaGate エンジニア / 現役エンジニア
編集 LuaGate編集部

成績判定プログラム とは

if文を使って、入力された点数に応じて成績を判定するプログラムを実装します。本レッスンでは、成績判定プログラム の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。

5 段階で成績を判定する

これまでに ifelse を使って「真ん中で 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 >= 90false、次の score >= 80true になるので "B" が返って、メソッドはそこで終了します。下の score >= 70 以降は 評価すらされない のがポイントです。

diagram (will load when visible)

図を見ると、上から順番に条件を絞り込んでいる様子がよくわかります。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) を完成させましょう。手順は次のとおりです。

  1. if (score >= 90) から始める
  2. else if (score >= 80) else if (score >= 70) else if (score >= 60) と続ける
  3. 最後の else"F" を返す
  4. 「実行」ボタンを押して、すべてのテストが緑になることを確認する

テストが通ったら、自分でいくつか境界値を試してみてください。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 つができることを確認しましょう。

  1. 成績判定 の要点を自分の言葉で説明できる
  2. このレッスンの最小コード (または操作手順) を見ずに書ける
  3. 練習問題やクイズで間違えた箇所を読み直して理解した

理解度チェック (30 秒)

Q. 成績判定 とは何か、1 文で説明してください。

この章のポイント

A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。

関連レッスン

要件

  1. 90点以上: A
  2. 80点以上: B
  3. 70点以上: C
  4. 60点以上: D
  5. 60点未満: F

入出力例

test-cases.txt

getGrade(95)"A" getGrade(85)"B" getGrade(75)"C" getGrade(65)"D" getGrade(45)"F"

ヒント

main.java
main.java
学習モード

メモ

成績判定プログラム

⌘S で保存