最終課題
ステップ0
以下のステップを実行する前に,概要の
課題のデータからexam.csv
,miniexam.csv
, assignments.csv
の3つのデータをダウンロードしておいてください.
- 小テストが行われた日付
- reading/writingの区別
- 課題番号
- 学生ID
- 点数
- 開始時刻
- 提出時刻
ステップ1
1-A. 問題説明
プログラムの実行時に,引数に試験成績のcsvファイル(exam.csv
)が渡されます.
csvファイルは,IDと点数が記載されています.
その点数を読み,秀,優,良,可,不可,K(未受験)のグレードを判定してください.
IDは番号順に並んでいますが,番号が飛んでいる場合があります.
その場合は,飛んだ番号は未受験であるため,0点,Kと出力してください.
点数が60点未満が不可,60以上70点未満が可,70点以上80点未満が良,80点以上90点未満が優, 90点以上が秀です.
K(未受験)はexam.csv
に掲載されていません.つまり,IDが飛んだ時,その学生のグレードをKにしてください.
ファイル名は,GradeChecker1.java
としてください.
なお,入力ファイルの行数が増減した場合でも適切に処理が行えるようにしてください.
1-B. 実行例
$ cat exam.csv
1,70.05347594 # <- ID 2が飛んでいる.
3,86.09625668
4,85.02673797
5,56.14973262
... 以下略
$ java GradeChecker1 exam.csv
1,70.053,良
2,0.000,K # <- IDがexam.csvに存在しないのは,未受験であり,Kとする.
3,86.096,優
4,85.027,優
5,56.150,不可
... 以下略
- ファイルが何も指定されなかった場合は考える必要はありません.
- 違うフォーマットのファイルが指定されることは考慮する必要はありません.
exam.csv
に書かれているIDの最大値は3つのファイル全ての最大値と捉えてもらって構いません. すなわち,最後のIDを持つ学生は受験した,つまり,exam.csv
に記載されていると扱ってください.
1-C. ヒント
1-C-1. リンク集
- クラス定義の基本形
- コマンドライン引数
- 文字列から
Integer
型への変換 - String型からDouble型への変換
- 例外機構
- 典型的なファイルからのデータの読み込み方法
- Map(連想配列)
- 文字列を特定の文字で区切る(
split
)
1-C-2. Integer
型同士の比較
実はInteger
型もString
型と同じく,参照型であり,==
での比較(参照先の一致性検査)性では,内容の一致性は判定できません.
内容の一致性判定には、Objects.equals
を利用します.
Integer num1 = 1;
Integer num2 = new Integer("1");
System.out.println(num1 == num2);
// 「false」が出力される。
System.out.println(Objects.equals(num1, num2));
// 「true」が出力される。
1-C-3. IDの抜けについて
IDが連続して抜けていた場合の処理も考えてみましょう.次の2通りの考え方があります.
Map
のキーにID,バリューに点数を入れることを考えます. ファイルを全部読み,IDと点数をMap
に格納します. その際、最大値を覚えておきます. その後、1から最大値まで順にMap
から点数を取得すると良いでしょう.- 現在の行番号を数える変数を用意します.
ファイルを1行ずつ読み、行番号と
ID
を比較します(1-C-2参照). 一致しなければ、行番号が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
... 以下略
試験成績のcsvファイルでは,IDは番号順に並んでいますが,番号が飛んでいる場合があります. その場合は,飛んだ番号は未受験であるため,0点,Kと出力してください.
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.csv
,assignments.csv
,miniexam.csv
の順にファイルが指定されます.
IDがnの学生の最終成績sを次の式で算出してください.
eが定期試験の点数,aが課題の合計点,tが小テストの受験率(0.0〜1.0)とします.
s=70100e+2560a+5t
2-B. 実行例
$ java GradeChecker2 exam.csv assignments.csv miniexam.csv
1,76,70.053,54,12,良
2, 4,,0,9,K
3,75,86.096,35,0,良
4,87,85.027,56,11,優
5,56,56.150,30,11,不可
6,71,68.984,45,11,良
... 以下略
IDの昇順になるように出力してください. 各行は,ID,最終成績,試験の点数,課題の合計点,小テストの受験回数, グレードをコンマ区切りで出力してください.
2-C. ヒント
2-C-1. 値の切り上げ
最終成績sは小数点以下を切り上げてください. 切り上げは下のように Math.ceil
を利用してください.
また,グレード算出の時にKか不可かを判定するため, 定期試験を受験したか否かのフラグを保持しておくと良いでしょう.
Double givenValue = 17.01;
Double ceiledValue = Math.ceil(givenValue);
// ceiledValueには 18.0 が代入される.
2-D. 評価項目
- 概要に示した評価項目
- データファイルを変更しても,例外なく実行結果を出力できるか
- 成績のデータの管理に配列を用いていないこと.
ステップ3
3-A. 問題説明
ステップ2で出力した内容の統計情報を出力しましょう. 統計情報とは,各学生の最終成績の平均,最高,最低点を算出してください. ただし,K,不可の学生を含めた場合と含めない場合での点数の両方を算出しましょう.
次に,各グレードに何人が属しているかを数えて出力してください.
ファイル名は,GradeChecker3.java
としてください.
なお,入力ファイルを変更して,行数が増減した場合でも適切に処理が行えるようにしてください.
3-B. 実行例
$ java GradeChecker3 exam.csv assignments.csv miniexam.csv
1,76,70.053,54,12,良
2, 4,,0,9,K
3,75,86.096,35,0,良
4,87,85.027,56,11,優
5,56,56.150,30,11,不可
6,71,68.984,45,11,良
... 途中省略
149,92,93.583,54,9,秀
150,80,76.471,58,6,優
151, 0,,0,0,K
152,64,60.963,38,14,可
Avg: 63.224 (78.226)
Max: 96.000 (96.000)
Min: 0.000 (60.000)
秀: 11
優: 37
良: 41
可: 17
不可: 26
K: 20
出力例は上記の通りです. IDの昇順になるように出力してください. 各行は,ID,最終成績,試験の点数,課題の合計点,小テストの受験回数, グレードをコンマ区切りで出力してください.
すべての学生の成績を出力し終えたら,統計情報を出力してください. 統計情報は,最終成績の平均,最大,最小です. カッコ内の情報は,単位取得者(最終成績が60点以上)のみを対象に求めた平均,最大,最小です.
それらを出力し終えたら,今度は,各グレードに属する人数を出力してください.
3-D. 評価項目
- 概要に示した評価項目
- データファイルを変更しても,例外なく実行結果を出力できるか.
ステップ4
4-A. 問題説明
この講義の成績算出には,特別ルールが適用されます. それは,定期試験の素点が80点以上であれば,最終成績をその点数とする,というものです. ただし,ステップ2で算出した成績の方が上であれば,その成績を最終成績とします.
また,グレードに※を追加してください. ※は出席日数不足を表しています. 条件は,定期試験を受験し,最終成績が60点未満かつ,小テストの受験回数が7回以下の場合に,グレードを※とします. 定期試験を受験していない学生のグレードはKとしてください.
この特別ルールを適用したプログラムを作成してください.
ファイル名は,GradeChecker4.java
とします.
なお,入力ファイルを変更して行数が増減した場合でも適切に処理が行えるようにしてください.
4-B. 実行例
$ java GradeChecker4 exam.csv assignments.csv miniexam.csv
1,76,70.053,54,12,良
2, 4,,0,9,K
3,87,86.096,35,0,優
4,87,85.027,56,11,優
5,57,56.150,30,11,不可
6,71,68.984,45,11,良
7,76,75.936,48,6,良
8,84,83.957,38,11,優
9,36,32.086,26,5,※
... 途中省略
149,94,93.583,54,9,秀
150,80,76.471,58,6,優
151, 0,,0,0,K
152,64,60.963,38,15,可
Avg: 65.868 (80.027)
Max: 96.000 (96.000)
Min: 0.000 (60.000)
秀: 14
優: 49
良: 35
可: 13
不可: 8
K: 20
※: 13
ステップ3までは, IDが3の学生の最終成績は75でした. ここで特別ルールを適用すると,テストの点数が 86.096 ですので,この点数を切り上げ,87点が最終成績となっています.
一方,IDが4の学生を見てみると,テストの点数が 85.027 と 80 点を超えています. しかし,ステップ2 で計算した点数の方が高いため,最終成績が87になっています.
また,IDが5の学生と9の学生では,最後の小テストの受験回数の違いが,グレードの違いになっています. さらに,グレードが一つ追加されたため,統計情報にも変更が加わっています.
4-C. ヒント
4-D. 評価項目
- 概要に示した評価項目
- データを変更しても,例外なく実行結果を出力できるか
- 人数やスコアの有効値が変更されても例外なく出力されるか.
ステップ5
5-A. 問題説明
今までは,コマンドライン引数でexam.csv
,assignments.csv
,miniexam.csv
の順でファイルが渡されていました.
これを自由な順序で指定するようにプログラムを変更します.
しかし,本当に自由な順序で渡されるとどのファイルに何が書かれているのかがわかりませんので,オプションでファイルを指定しましょう.
- 成績のファイルを
-record
オプションで受け取ってください. - 課題のファイルを
-assignments
オプションで受け取ってください. - 小テストのファイルを
-miniexam
オプションで受け取ってください. - 出力先を
-output
オプションで受け取ってください.
ファイルが指定されない場合は,その成績は0点として最終成績を算出してください.
最終成績の計算式は変更する必要はありません.
また,-output
オプションが指定された場合は,そのファイルに結果を出力してください.
指定されなかった場合は,標準出力に出力してください.
ファイル名は,GradeChecker5.java
としてください.
なお,入力ファイルが変更され,行数が増減した場合でも適切に処理が行えるようにしてください.
5-B. 実行例
$ java GradeChecker5 -record exam.csv -assignments assignments.csv -output result.csv
$ cat result.csv
1,72,70.053,54,0,良
2, 0,,0,0,K
3,87,86.096,35,0,優
4,86,85.027,56,0,優
5,57,56.150,30,0,※
6,69,68.984,45,0,可
... 途中省略
149,94,93.583,54,0,秀
150,78,76.471,58,0,良
151, 0,,0,0,K
152,61,60.963,38,0,可
Avg: 64.539 (78.800)
Max: 96.000 (96.000)
Min: 0.000 (61.000)
秀: 11
優: 43
良: 38
可: 18
不可: 0
K: 20
※: 22
この実行例では,小テストのファイルを指定せずに成績を算出し,結果をresult.csv に出力するよう指定しています.
もちろん,-output
オプションが指定されなければ, これまで通り標準出力に出力されます.
小テストが指定されていないため,出力の小テストの列はすべて0になっています. また,最終成績が60点以下であれば,グレードが※になっています.
5-C. ヒント
オプションの解析
オプションの解析では,オプションの指定方法が間違っているケースは考える必要はありません.
オプションの内容を記録するためにArguments
型を用意しましょう.
Arguments
型にはフィールドとして,オプションの内容を保持する変数を宣言してください.
そして,Arguments
型に次のようなparse
を用意してください.
void parse(String[] args){
for(Integer i = 0; i < args.length; i++){
if(!args[i].startsWith("--")){
arguments.add(args[i]);
}
else {
i = parseOption(args, i);
}
}
}
Integer parseOption(String[] args, Integer i) {
if(Objects.equals(args[i], "--dest")){
i++;
this.dest = args[i];
}
...
return i;
}
5-D. 評価項目
- 概要に示した評価項目
- オプションの解析を適切に行えているか.
- オプションが指定された場合,指定されなかった場合の両方で,適切に処理できているか.
- データを変更しても,例外なく実行結果を出力できるか
- 人数やスコアの有効値が変更されても例外なく出力されるか.
ステップ6
6-A.
次の統計情報と,最終成績の順位を算出してください.
なお,出力順は最終成績順(-score
),もしくはID順(-id
)のいずれかをオプションで指定できるようにしてください.
両方のオプション(-score
と-id
)が指定された場合は,ID順で出力してください.
ファイル名は,GradeChecker6.java
としてください.
なお,入力ファイルが変更され,行数が増減した場合でも適切に処理が行えるようにしてください.
- 単位取得率
- 単位取得者の人数を数え,全体の学生数で割って算出してください. 統計情報として百分率(パーセンテージ)で出力してください.
- 各グレードの人数の全体に占める割合
- 秀,優,良,可,不可,K,※の6種類のグレードが算出されています. 各グレードに属する人数が,全体のうちどれくらいの割合であるのかを算出してください. グレードの人数と同じ行に百分率(パーセンテージ)で出力してください.
- 秀,優,良,可の人数の単位取得者に占める割合
- 秀,優,良,可の4種類のグレードについては,各グレードに属する人数が,単位取得者のうちどれくらいの割合を占めているのかを算出してください. グレードの人数と同じ行に百分率(パーセンテージ)で出力してください.
6-C. ヒント
6-D. 評価項目
- 概要に示した評価項目
- 入力ファイルを変更しても,例外なく実行結果を出力できるか