■ CGI初歩の初歩

■ CSVデータをソートして表示する

#!/usr/local/bin/perl

#------------------------------------------------------------------------------
$title = "テスト結果";
#------------------------------------------------------------------------------

print "Content-type: text/html\n\n";

    print <<"EOM";
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=Shift_JIS">

<title>$title</title>

<META http-equiv="Content-Style-Type" content="text/css">

</HEAD>
<BODY>

<table border=1 width="80%" align="center" CELLSPACING="0" CELLPADDING="2">
<tr>
<td width="6%">順位</td>
<td width="10%">氏名</td>
<td width="14%" align=\"right\">国語</td>
<td width="14%" align=\"right\">数学</td>
<td width="14%" align=\"right\">社会</td>
<td width="14%" align=\"right\">理科</td>
<td width="14%" align=\"right\">英語</td>
<td width="14%" align=\"right\">合計</td>
</tr>\n
EOM

&Disp;

print <<"EOM";
</table>
</BODY>
</HTML>
EOM

exit;

#
# CSVファイルからデータを読み込みソートして表示する
#
sub Disp {
    if( !open(IN, "mm.txt") ) {
        print "データファイルがオープンできません<BR>\n";
    }
    else {
        $i = 0;
        while ($line = <IN>) {
            # 読み込んだデータを分離する
            my ($name, $kokugo, $sansuu, $shakai, $rika, $eigo) = split(/,/,$line);
            # 合計を計算する
            my $goukei = $kokugo + $sansuu + $shakai + $rika + $eigo;
            # データに合計を加え、それを$dataに格納する
            $csv = join(",",$name,$kokugo,$sansuu,$shakai,$rika,$eigo,$goukei);
            push(@data, $csv);
        }
        close(IN);

        # データをソートする キーは合計の欄
        @sorted_data = sort
                      {   (split ",", $b)[6]
                                 <=>
                          (split ",", $a)[6]
                      }
                      @data;

        # データを表示する
        my $count = 1;
        my $prev_goukei = -1;
        foreach $i (@sorted_data) {
            ($name,$kokugo,$sansuu,$shakai,$rika,$eigo,$goukei) = split(/,/,$i);

            # 合計が同じときは順位は元のままにする
            if( $goukei != $prev_goukei) {
                $juni = $count;
            }

            print <<"EOM";
<tr>
<td width="6%" align=\"right\">$juni</td>
<td width="10%">$name</td>
<td width="14%" align=\"right\">$kokugo</td>
<td width="14%" align=\"right\">$sansuu</td>
<td width="14%" align=\"right\">$shakai</td>
<td width="14%" align=\"right\">$rika</td>
<td width="14%" align=\"right\">$eigo</td>
<td width="14%" align=\"right\">$goukei</td>
</tr>\n
EOM

            $prev_goukei = $goukei;
            ++$count;
        }
    }
}

表示するCSVファイル
飯田,73,69,75,86,89
安倍,79,69,42,74,71
保田,76,77,87,71,93
矢口,75,77,70,87,53
石川,70,62,64,69,73
吉澤,65,53,39,61,52
辻,45,78,51,51,24
加護,42,51,48,50,60
高橋,66,72,55,79,74
紺野,87,89,96,93,48
小川,77,85,64,71,58
新垣,57,38,49,48,66

実行結果

テスト結果
順位 氏名 国語 数学 社会 理科 英語 合計
1 紺野 87 89 96 93 48 413
2 保田 76 77 87 71 93 404
3 飯田 73 69 75 86 89 392
4 矢口 75 77 70 87 53 362
5 小川 77 85 64 71 58 355
6 高橋 66 72 55 79 74 346
7 石川 70 62 64 69 73 338
8 安倍 79 69 42 74 71 335
9 吉澤 65 53 39 61 52 270
10 新垣 57 38 49 48 66 258
11 加護 42 51 48 50 60 251
12 45 78 51 51 24 249

 一つ前のスクリプトで合計を表示するようにしましたが、このスクリプトでは合計でソートして表示するように機能アップしてみました。合わせて順位も表示するようにしています。まず、データを読み込み合計を計算します。計算結果の合計をデータに付加して、それを$dataに格納していきます。その後、sortを使ってソートします。このスクリプトでは降順にソートしています。最後に順位を付けて表示しています。
 順位は合計が同じ場合を考慮して、一つ前の人の合計と比較しながら、順位付けしていかなければならないので、ちょっと面倒ですね。このデータファイルでは偶々合計が同じになることが無いので、テスト用に別のデータファイルを作って確認しました。