課題:学習記録の集計
study.logにある次の形式の行を読み込み、科目ごとの学習時間を合計してください。
study.logTEXT
2026-10-08,Perl,40
2026-10-09,Perl,35
2026-10-09,SQL,20出力は科目名の順に並べ、全体の合計時間も表示します。壊れた行、時間が数値でない行、空の科目名はエラーとして行番号付きで報告してください。
小さく分けて実装する
- まず配列を使って固定データ1行を分割し、科目と時間を表示する。
- ファイルを1行ずつ読み、
split /,/, $lineで項目へ分ける。 - ハッシュの値へ時間を加算し、合計値も更新する。
- 数値チェック、項目数チェック、空行の扱いを追加する。
- 入力ファイルをテスト用に複数用意し、期待する出力と比較する。
設計のヒント
「1行を解析する処理」と「全体を集計する処理」をサブルーチンへ分けるとテストしやすくなります。エラーを見つけたらすぐ終了するか、他の行も調べて最後に一覧表示するかを先に決めます。
最小の解答例
practice.plPERL
use strict;
use warnings;
open my $fh, '<:encoding(UTF-8)', 'study.log'
or die "開けません: $!";
my %total;
my $line_number = 0;
while (my $line = <$fh>) {
$line_number++;
chomp $line;
my ($date, $subject, $minutes) = split /,/, $line;
if (!defined $minutes || $subject eq '' || $minutes !~ /^\d+$/) {
warn "行\${line_number}をスキップしました\n";
next;
}
$total{$subject} += $minutes;
}
for my $subject (sort keys %total) {
print "$subject: $total{$subject}分\n";
}
close $fh;実行COMMAND / OUTPUT
perl practice.pl
Perl: 75分
SQL: 20分ファイルを開く処理、行番号、形式が不正な行の報告まで含めた、単体で実行できる最小の解答例です。さらに、入力ファイルが空の場合や同じ科目がない場合のテストも追加してみましょう。
発展課題
月別集計、科目別ランキング、CSV出力、コマンドライン引数、テスト自動化へ発展させましょう。Web画面に結果を表示する場合は、入力値の検証と出力のエスケープを行い、処理と表示を分離します。