最終課題

ステップ0

以下のステップを実行する前に,概要課題のデータから必要なデータをダウンロードしておいてください.

ステップ1

1-A. 問題説明

プログラムの実行時に,引数に試験成績のcsvファイル(exam.csv)が渡されます. csvファイルは,IDと点数が記載されています. その点数を読み,秀,優,良,可,不可,K(未受験)のグレードを判定してください. IDは番号順に並んでいますが,番号が飛んでいる場合があります. その場合は,飛んだ番号は未受験であるため,0点,Kと出力してください. ただし,最後の行のIDが最後のIDであると信用しても構いません.

点数が60点未満が不可,60以上70点未満が可,70点以上80点未満が良,80点以上90点未満が優, 90点以上が秀です. K(未受験)はexam.csvに掲載されていません. IDが飛んだ時,その学生のグレードをKにしてください.

ファイル名は,GradeChecker1.javaとしてください. なお,入力ファイルの行数が増減した場合でも適切に処理が行えるようにしてください.

1-B. 実行例

$ cat exam.csv # ファイルの内容を確認する.
1,70.05347594
3,86.09625668
4,85.02673797
5,56.14973262
# ... 以下略
$ java GradeChecker1 exam.csv # 実行結果
1,70.053, 良
2,0.000, K
3,86.096, 優
4,85.027, 優
5,56.150, 不可
# ... 以下略
$ java GradeChecker1 exam2.csv # ファイルが exam.csv ではなくてもOK
1,78.053, 良
2,44.321, 不可
3,61.027, 可
4,17.150, 不可
5,82.096, 優
# ... 以下略
$ java GradeChecker1 # 何も指定しなかった場合は,エラーメッセージを表示する.
ERROR: 試験の成績ファイルが指定されていません.
java GradeChecker1 <EXAM.CSV>

IDが昇順になるように出力してください. 「ID, 最終成績,グレード」をコンマ区切りで出力してください.

なお,上の実行結果からもわかるように,exam.csvには,ID 2が抜けています. そのため,2番目の学生は未受験であるため,出力では,2番の学生は0点でグレードがKになっています. また,与えられるファイルの名前は exam.csvであるとは限りません.

1-C. ヒント

IDの抜けについて

IDが連続して抜けていた場合の処理も考えてみましょう。 次の2通りの考え方があります。

  • HashMapのキーにID,バリューに点数を入れることを考えます.
    • ファイルを全部読み,IDと点数をHashMapに格納します.
    • その際,最大値を覚えておきます.
    • そして,1から最大値まで順にHashMapから点数を取得してみましょう.
    • バリューが存在しない場合は,未受験であることがわかります.
  • 現在の行番号を数える変数を用意します.
    • ファイルを1行ずつ読み,行番号とIDを比較します.
    • 一致しなければ、行番号がIDになるまでKを出力します。

1-D. 評価項目

  • 概要に示した評価項目
  • データを変更しても,例外なく実行結果を出力できるか.
  • 引数が与えられなかった場合でも,適切な結果が出力できるか.

ステップ2

2-A. 問題説明

プログラムの実行時に,引数に試験成績(exam.csv), 課題(assignments.csv),小テスト(miniexam.csv)の3つのcsvファイルが渡されます.

それらの点数を読み,秀,優,良,可,不可,K(未受験)のグレードを判定してください. 最終成績の算出方法は,定期試験が70%,課題が25%,小テストの受験率が5%です.小数点以下は切り上げてください.

ファイル名は,GradeChecker2.javaとしてください. なお,入力ファイルの行数が増減した場合でも適切に処理が行えるようにしてください.

それぞれのcsvファイルの内容は次の通りです.

2-A-1. 試験成績

$ cat exam.csv
1,70.05347594
3,86.09625668
4,85.02673797
5,56.14973262
# ... 以下略

2-A-2. 課題

$ cat assignments.csv
1,10,8,8,10,8,10
2,,,,,,
3,8,9,8,,,10
4,8,10,10,8,10,10
5,10,10,,0,10,
# ... 以下略

上の各行は,「ID,課題1,課題2,課題3,課題4,課題5,課題6」の順に各課題の成績が記載されています. 点数が記載されていない部分は未提出です. 課題1〜6までの点数を合計した点数がその人の課題点であり,最高点は60点です. IDは昇順に並んでおり,途中に抜けている番号はありません.

2-A-3. 小テスト

$ cat miniexam.csv
1,5,2,,1,2,2,,1,5,0,0,5,0,2
2,5,3,1,,1,0,,0,3,,,,0,1
4,7,2,8,6,9,4,,4,,2,6,6,0,
5,3,5,7,,3,5,,1,3,,2,4,0,0
6,6,8,10,8,,,7,10,9,8,5,7,0,
# ... 以下略

各行は,IDから始まり,14回分の小テストの点数が記載されています. 点数の記載がない部分は小テストを未受験であり,0は受験したものの点数が取れなかったことを表しています. また,IDは昇順に並んでいますが,途中飛んでいる場合もあります.

この小テストでは,受験率を算出してください. すなわち,書かれている点数は重要ではなく,点数が書かれているか否かが重要です. 受験回数を14で割り,受験率を算出してください. その受験率を小テストの点数とします.

2-A-4. 成績の算出

プログラムには,コマンドライン引数で exam.csvassignments.csvminiexam.csvの順にファイルが指定されます. IDが$n$の学生の最終成績$s$を次の式で算出してください. $e$が定期試験の点数,$a$が課題の合計点,$t$が小テストの受験率(0.0〜1.0)とします.

\[ s=\frac{70}{100}e + \frac{25}{60}a + 5t \]

Double givenValue = 17.01;
Double ceiledValue = Math.ceil(givenValue);
// ceiledValueには 18.0 が代入される.

最終成績$s$は小数点以下を切り上げてください. 切り上げは,上記のように,Math.ceilを利用してください.

また,グレード算出の時にKか不可かを判定するため,定期試験を受験したか否かのフラグを保持しておくと良いでしょう.

2-A-5. 満たすべき要件

ただし,以下の2つの要件を満たすようにプログラムを作成してください.

  • GradeChecker2.java のフィールドが5つ以下になるようにしてください.
  • GradeChecker2.java のそれぞれのメソッドにおいても,宣言する変数が5つ以下になるようにしてください.

2-B. 実行例

)$ java GradeChecker2 exam.csv assignments.csv miniexam.csv 
1,76.0,70.05347594,54.0000,0.857143,良
2,4.0,,0.00000,0.642857,K
3,75.0,86.09625668,35.0000,0.00000,良
4,87.0,85.02673797,56.0000,0.785714,優
5,56.0,56.14973262,30.0000,0.785714,不可
6,71.0,68.98395722,45.0000,0.785714,良
7,76.0,75.93582888,48.0000,0.428571,良
8,79.0,83.95721925,38.0000,0.785714,良
9,36.0,32.0855615,26.0000,0.357143,不可
10,58.0,50.80213904,51.0000,0.0714286,不可
11,71.0,68.98395722,43.0000,0.928571,良
# ... 以下略
$ java GradeChecker2 # ファイルが3つ指定されなかった場合は,エラーメッセージを表示する.
ERROR: 必要なファイルが指定されていません.
java GradeChecker2 <EXAM.CSV> <ASSIGNMENTS.CSV> <MINIEXAM.CSV>

出力例を上に示します. IDの昇順になるように出力してください. 各行は,ID,最終成績,試験の点数,課題の合計点,小テストの受験回数,グレードをコンマ区切りで出力してください.

実行例にあるID 2の学生のように,試験を受けていない場合は K として扱ってください. なお,試験を受験したが,0点である場合もあることに注意してください.

2-C. ヒント

2-C-a. 満たすべき要件のために

  • 満たすべき要件を果たすため,各学生の試験成績,課題の点数,小テストをまとめる型を導入すると良いでしょう.
    • Student.javaを定義し,フィールドに examScore, assignments, miniexamsid を宣言します.
      • Double finalScore() メソッドは,examScore, assignments, miniexamsを元に最終成績の点数を算出しましょう.
      • String grade() メソッドは,finalScoreメソッドの結果を元に秀優良可不可を算出しましょう. examScorenullであればKと判断しましょう.

2-D. 評価項目

  • 概要に示した評価項目
  • データを変更しても,例外なく実行結果を出力できるか.
  • 独自の型を作成できているか.
  • 引数が与えられなかった場合でも,適切な結果が出力できるか.

ステップ3

3-A. 問題説明

ステップ2までに出力した内容の統計情報を出力しましょう. 統計情報とは,全学生の最終成績の平均,最高,最低点を算出してください. ただし,K,不可の学生を含めた場合と含めない場合での点数の両方を算出しましょう.

次に,各グレードに何人が属しているかを数えて出力してください.

ファイル名は,GradeChecker3.javaとしてください. なお,入力ファイルの行数が増減した場合でも適切に処理が行えるようにしてください.

3-B. 実行例

$ java GradeChecker3 exam.csv assignments.csv miniexam.csv
1,76.0,70.05347594,54.0000,0.857143,良
2,4.0,,0.00000,0.642857,K
3,75.0,86.09625668,35.0000,0.00000,良
4,87.0,85.02673797,56.0000,0.785714,優
5,56.0,56.14973262,30.0000,0.785714,不可
6,71.0,68.98395722,45.0000,0.785714,良
# ... 途中省略
149,92.0,93.5828877,54.0000,0.642857,秀
150,80.0,76.47058824,58.0000,0.428571,優
151,1.0,,0.00000,0.0714286,K
152,64.0,60.96256684,38.0000,1.00000,可
Avg: 63.2303 (78.2264)
Max: 96.0000 (96.0000)
Min: 0.00000 (60.0000)
  秀:  11
  優:  37
  良:  41
  可:  17
不可:  26
  K:  20

出力例を上に示します. IDの昇順になるように出力してください. 各行は,ID,最終成績,試験の点数,課題の合計点,小テストの受験回数,グレードをコンマ区切りで出力してください.

すべての学生の成績を出力し終えたら,統計情報を出力してください. 統計情報は,最終成績の平均,最大,最小です. カッコ内の情報は,単位取得者(最終成績が60点以上)のみを対象に求めた平均,最大,最小です.

それらを出力し終えたら,今度は,各グレードに属する人数を出力してください.

3-C. ヒント

  • 統計情報を計算するStatsを作成しましょう.
    • 最大値を表すmax,最小値を表すmin,追加された値の合計値を表すsum,追加された数を表すcountの4つのフィールドを定義しましょう.
    • 4つのメソッドを定義します.
      • 平均を返すaverageメソッド,
      • 最大値を返すmaxメソッド,
      • 最小値を返すminメソッド,
      • 値を受け取るputメソッド.
    • putメソッドで点数をうけとりましょう.
      • 受け取れば,その値が最大値であるか,最小値であるかをそれぞれ判定しましょう.
      • また,sumに追加された値を加算しましょう.
      • 最後に count1を加算しましょう.
    • 統計情報を計算するメソッドでは,2つのStatsの実体を作成しましょう.
      • 一方のStatsの実体のputメソッドに全てのStudentfinalScoreの値を渡しましょう.
      • gradeメソッドが"K"ではない場合に,もう一方のStatsの実体のputメソッドに最終成績を渡しましょう.

3-D. 評価項目

  • 概要に示した評価項目
  • データを変更しても,例外なく実行結果を出力できるか.
  • 与えられた引数が不正だった場合に,エラーを出力できるか.

ステップ4

4-A. 問題説明

この講義の成績算出には,特別ルールが適用されます. それは,定期試験の素点が80点以上であれば,最終成績をその点数とする,というものです. なお,定期試験の点数も切り上げて判定してください. すなわち,定期試験の点数が 79を超えていれば,切り上げにより80点隣,上記の定期試験の素点が80点を超える,というルールに該当するようになります. ただし,ステップ2 で算出した成績の方が上であれば,その成績を最終成績とします.

また,グレードにを追加してください. は出席日数不足を表しています. 条件は,定期試験を受験し,最終成績が60点未満かつ,小テストの受験回数が7回以下の場合に,グレードをとします. 定期試験を受験していない学生のグレードはKとしてください.

この特別ルールを適用したプログラムを作成してください. ファイル名は,GradeChecker4.javaとします. なお,入力ファイルの行数が増減した場合でも適切に処理が行えるようにしてください.

4-B. 実行例

$ java GradeChecker4 exam.csv assignments.csv miniexam.csv
1,76.0,70.05347594,54.0000,0.857143,良
2,4.0,,0.00000,0.642857,K
3,87.0,86.09625668,35.0000,0.00000,優 # ステップ3までは,この学生の最終成績は75だが,特別ルールで87になった.
4,87.0,85.02673797,56.0000,0.785714,優 # テストの点数が80点を超えているが,計算した点数の方が高いため,87が最終成績となっている.
5,56.0,56.14973262,30.0000,0.785714,不可
6,71.0,68.98395722,45.0000,0.785714,良
7,76.0,75.93582888,48.0000,0.428571,良
8,84.0,83.95721925,38.0000,0.785714,優
9,36.0,32.0855615,26.0000,0.357143,※ # 受験回数が少ないため,最終成績が※となっている.
# ... 途中省略
18,80.0,79.67914439,43.0000,0.0714286,優 # 試験が79.679... で ceil すると 80点になる.計算した点数が75点であるため,特別ルールで80点となる.
# ... 途中省略
149,94.0,93.5828877,54.0000,0.642857,秀
150,80.0,76.47058824,58.0000,0.428571,優
151,1.0,,0.00000,0.0714286,K
152,64.0,60.96256684,38.0000,1.00000,可
Avg: 64.3026 (79.7642)
Max: 96.0000 (96.0000)
Min: 0.00000 (60.0000)
  秀:  14
  優:  49
  良:  27
  可:  16
不可:   9
  K:  20
  ※:  17

4-C. ヒント

  • 基本的には,Student型のfinalScoreメソッド,gradeメソッドを変更すると良いでしょう.
    • ただし,この変更を行うと,ステップ3以前の結果が変更されてしまうため,Student4とクラス名を変更しておきましょう.
  • そのほかは,頻度を計算するところで,の頻度を追加することで完成です.

4-D. 評価項目

ステップ5

5-A. 問題説明

今までは,コマンドライン引数でexam.csvassignments.csvminiexam.csvの順でファイルが渡されていました. これを自由な順序で指定するできるようにプログラムを変更します. しかし,本当に自由な順序で渡されるとどのファイルに何が書かれているのかがわかりませんので,コマンドライン引数でファイルを指定しましょう.

成績のファイルを -examオプションで受け取ってください. 課題のファイルを -assignmentsオプションで受け取ってください. 小テストのファイルを -miniexamオプションで受け取ってください. 出力先を-outputオプションで受け取ってください. ファイルが指定されない場合は,その成績は0点として最終成績を算出してください. 最終成績の計算式は変更する必要はありません. また,-outputオプションが指定された場合は,そのファイルに結果を出力してください. 指定されなかった場合は,標準出力に出力してください.

ファイル名は,GradeChecker5.javaとしてください. なお,入力ファイルの行数が増減した場合でも適切に処理が行えるようにしてください. ファイル名がexam.csvminiexam.csvassignments.csvであるとは限りません.

なお,一つもファイルが指定されなかった場合は,エラーメッセージを表示して終了してください.

5-B. 実行例

$ java GradeChecker5 -exam exam.csv -assignments assignments.csv -output result.csv
$ cat result.csv
1,72.0,70.05347594,54.0000,0.00000,良
2,0.0,,0.00000,0.00000,K
3,87.0,86.09625668,35.0000,0.00000,優
4,86.0,85.02673797,56.0000,0.00000,優
5,52.0,56.14973262,30.0000,0.00000,※
6,68.0,68.98395722,45.0000,0.00000,可
# ... 途中省略
149,94.0,93.5828877,54.0000,0.00000,秀
150,78.0,76.47058824,58.0000,0.00000,良
151,0.0,,0.00000,0.00000,K
152,59.0,60.96256684,38.0000,0.00000,※
Avg: 62.2829 (78.5098)
Max: 96.0000 (96.0000)
Min: 0.00000 (60.0000)
  秀:  11
  優:  43
  良:  27
  可:  21
不可:   0
  K:  20
  ※:  30
$ java GradeChecker5
ERROR: 何もファイルが指定されていません.
java GradeChecker5 [OPTIONS]
OPTIONS
    -exam        <EXAM.CSV>
    -assignments <ASSIGNMENTS.CSV>
    -miniexam    <MINIEXAM.CSV>
    -output      <RESULT_FILE>

左の実行例では,小テストのファイルを指定せずに成績を算出し,結果を result.csv に出力するよう指定しています. もちろん,-outputオプションが指定されなければ,今まで通り標準出力に出力されます.

小テストが指定されていないため,出力の小テストの列はすべて0になっています. また,最終成績が60点以下であれば,小テストの受験回数が0回ですので,グレードがになっています. それに伴い,不可の人数が0人となっています(不可に割り当てられる学生は,小テストの回数が0点であるため,となる.).

また,定期試験のファイルが指定されなかった場合,全員が未受験扱いとなるため,全員がKと判定されます.

5-C. ヒント

5-C-a. Arguments型

  • 指定されたオプションを格納するArguments型を作成しましょう.
    • 次のフィールドを宣言しましょう.
      • String型の exam
      • String型の miniexam
      • String型の assignments
      • String型の output
      • PrintWriter型の out
    • void parse(String[] args) メソッドを用意しましょう.
      • このメソッド内でフィールドに値を代入しましょう.
      • -exam-assignments-miniexam-outputが指定された場合は,インデックスを1つ進めて,変数に代入しましょう.
    • 出力先を表す PrintWriterを作成して返す createPrintWriterメソッドを用意しましょう.
      • 処理内容は,オプションでoutputが指定されているか否かで分岐させましょう.
        • オプションでoutputが指定されていれば,指定されたファイルをFileWriterで開き,PrintWriterでラップして返しましょう.
        • オプションでoutputが指定されていなければ,System.outPrintWriterでラップして返しましょう.
    • 出力先となる PrintWriterを返す outメソッドを用意しましょう.
      • outnullであれば,createPrintWriterを呼び出して,outに代入しましょう.
      • outを返しましょう.

5-C-b. parseメソッド内の処理の例

void parse(String[] args){
    for(Integer i = 0; i < args.length; i++){
        // 途中省略
        else if(/* -exam が指定された場合の条件式 */){
            i++;
            this.exam = args[i];
        }
        // 途中省略
    }
}

5-D. 評価項目

ステップ6

6-A. 問題説明

次の統計情報と, 最終成績の順位を算出してください. ファイル名は,GradeChecker6.javaとしてください. なお,入力ファイルの行数が増減した場合でも適切に処理が行えるようにしてください.

  • 単位取得率
    • 単位取得者の人数を数え,全体の学生数で割ってください.これで単位取得率が算出できます.統計情報として百分率(パーセンテージ)で出力してください.
  • 各グレードの人数の全体に占める割合
    • 秀,優,良,可,不可,K,※の6種類のグレードが算出されています. 各グレードに属する人数が,全体のうちどれくらいの割合であるのかを算出してください. グレードの人数と同じ行に百分率(パーセンテージ)で出力してください.
  • 秀,優,良,可の人数の単位取得者に占める割合
    • 秀,優,良,可の4種類のグレードについては,各グレードに属する人数が,単位取得者のうちどれくらいの割合を占めているのかを算出してください. グレードの人数と同じ行に百分率(パーセンテージ)で出力してください.

6-A-1. 最終成績の順位

最終成績でソートし,学生に順位をつけてください. 各学生の成績を出力するときに,順位を行の最後につけて出力してください. 同じ点数であったとしても,同じ順位である必要はありません. 学生の情報を表す型が用意されている時,次のプログラムでソートが行えます.

学生の情報を表す型がStudent4,最終成績が Student4型のfinalScoreメソッドで算出できるとします.

import java.util.Comparator;

public class StudentComparator implements Comparator<Student4>{
    public int compare(Student4 student1, Student4 student2){
        Double score1 = student1.finalScore();
        Double score2 = student2.finalScore();
        if(score1 < score2)      return 1;
        else if(score1 > score2) return -1;
        return 0;
    }
}

このプログラムをStudentComparator.javaとして保存し,GradeChecker6.java と同じ場所に保存してください. このプログラムが2つの成績を比べる比較器であり,compareメソッドが実際に比較するメソッドです. score1 > score2であれば負の値,score1 < score2であれば正の値,score1 == score2であれば0を返すと,適切に降順にソートしてくれます. 返り値の符号がが逆転すると,逆順ソート(昇順)のソートになります.

// listに学生の情報がすべて格納されている.
ArrayList<Student4> list = // ...
// 先に作成した比較器.
Comparator<Student4> comp = new StudentComparator();
// 比較器を元にソートを行う.
Collections.sort(list, comp);

このプログラムが,StudentComparatorを利用する側のプログラムの断片です. すべての学生情報が入ったArrayList<Student4>Collections型のsortメソッドにStudentComparatorの実体と共に渡してください. そうすると,listの順序が最終成績の昇順に並び替えられています.

ただし,学生の情報を保存する独自の型は適宜読み替えてください. また,最終成績が得られるメソッドもここではfinalScoreメソッドですが,自分自身で定義したものに置き換えてください.

なお,この場合,総合点のみでソートするため,Kと不可,※は順不同で出力されます. グレードが秀,優,良,可,不可,K,※の順で並ぶようなプログラムにするにはどのようにすれば良いかを考えてみましょう. StudentComparecompareメソッドをどのように変更すれば良いかを考えてみてください.

6-B. 実行例

$ java GradeChecker6 -miniexam miniexam.csv -exam exam.csv -assignments assignments.csv 
1,76.0,70.05347594,54.0000,0.857143,良,71
2,4.0,,0.00000,0.642857,K,141
3,87.0,86.09625668,35.0000,0.00000,優,24
4,87.0,85.02673797,56.0000,0.785714,優,25
5,56.0,56.14973262,30.0000,0.785714,不可,110
6,71.0,68.98395722,45.0000,0.785714,良,85
7,76.0,75.93582888,48.0000,0.428571,良,72
8,84.0,83.95721925,38.0000,0.785714,優,36
9,36.0,32.0855615,26.0000,0.357143,※,129
# ... 途中省略
149,94.0,93.5828877,54.0000,0.642857,秀,5
150,80.0,76.47058824,58.0000,0.428571,優,63
151,1.0,,0.00000,0.0714286,K,145
152,64.0,60.96256684,38.0000,1.00000,可,101
Average:   64.3026 (79.7642)
Max:       96.0000 (96.0000)
Min:       0.00000 (60.0000)
単位取得率: 69.7% (106/152)
   秀:   14 (9.2105% (14/152), 13.208% (14/106))
   優:   49 (32.237% (49/152), 46.226% (49/106))
   良:   27 (17.763% (27/152), 25.472% (27/106))
   可:   16 (10.526% (16/152), 15.094% (16/106))
  不可:    9 (5.9211% ( 9/152))
   K:   20 (13.158% (20/152))
   ※:   17 (11.184% (17/152))

各行に学生の成績が出力されます. 行のフォーマットは,「ID,最終成績,試験の点数,課題の点数,小テストの受験回数,グレード,順位」です.

すべての学生の成績の出力後に,統計情報が出力されています. 最終成績の平均,最大値,最小値です. カッコ内の値は,単位取得者に限った時の最終成績の平均,最大値,最小値です.

次に単位取得率が出力されています.

最後に各グレードに属する人数とその割合が出力されています. 秀,優,良,可のカッコ内にある2つの数値は,全体におけるその人数の割合と単位取得者におけるその人数の割合です. 不可,K,※は,全体におけるその人数の割合が出力されています.

例えば,例の場合,全体の人数は152名で,単位取得者の人数は106名,秀の人数は12名です. 単位取得率は73.026%($=\frac{111}{152}$)です. また,全体に占める秀の人数の割合は7.8947%($=\frac{12}{152}$), 単位取得者に占める秀の人数の割合は11.321%($=\frac{12}{106}$)です.

6-C. ヒント

各学生の順位

順位を求めるには,学生を点数で降順にソートし,順位を保存しておく必要があります.

  • Student4型にInteger型のrankという変数を追加しましょう.順位を保存しておく変数です.
  • 学生のデータを読み終えて,出力する前に各学生の順位を調べましょう.
    • 6-A-1にあるように,StudentComparatorの実体を作成しましょう.
    • 学生の一覧のArrayList<Student4>型の変数listを用意しましょう.
      • 学生のデータをHashMap<Integer, Student4>型のmapに入れているのであれば,list.addAll(map.values())で用意できます.
      • 学生のデータをArrayList<Student4>型のstudentsに入れているのであれば,list.addAll(students)で用意できます.
        • 最終的にID順で出力するため,元のリストの順序は変更しないようにしています.
        • もちろん,順位を調べた後,IDでソートし直しても問題ありません.
    • Collections.sortメソッドを用いて,listStudentComparatorを用いてソートしましょう.
    • listの各要素のStudent4型のrankに順位をつけていきましょう.

6-D. 評価項目