# tabulation.pl
# 内容 :　クラス別科目別成績データ集計
# Copyright (c) 2002-2011 Mitsuo Minagawa, All rights reserved.
# (minagawa@fb3.so-net.ne.jp)  
# 使用方法 : c:\>perl tabulation.pl
#
open(IN1,"input.txt");	
open(OUT1,">total.txt");	
#   
#入力データ:以下の5項目
#
#　クラス,出席番号,氏名,科目コード,点数
#   
#集計用データ:
#                   $sum[0-3][0-3][0-4]   
#                       1次元目=>１組:0、２組:1、３組:2、合計:3の4項目  
#                       2次元目=>国語から社会までの5科目   
#                               国語:01、算数:02、理科:03、社会:04、英語:05
#                       3次元目=>生徒数、最高点、最低点、平均点の4項目
#   
#テーブルの初期化   
#最低点の初期値として、100点を設定する。    
#   
for	($i	=	0;	$i	<=3;	$i++)			{		
	for	($j	=	0;	$j	<=4;	$j++)		{		
		for	($k	=	0;	$k	<=3;	$k++)	{		
			if		($k		==		2)		{
					$sum[$i][$j][$k]	=	100;	#最低点の初期値
			}	
			else							{
					$sum[$i][$j][$k]	=	0;	
			}	
		}	
	}	
}	
#   
#メイン処理 
#   
while($line1	=	<IN1>)					{	
	chomp($line1);	
	@in1	=	split('\t',$line1);	
#   
#クラスの振り分け   
#   
	if		($in1[0]	eq	"1")			{	#"1"は１組
			$i	=	0;	
	}	
	elsif	($in1[0]	eq	"2")			{	#"2"は２組
			$i	=	1;	
	}	
	elsif	($in1[0]	eq	"3")			{	#"3"は３組
			$i	=	2;	
	}	
#   
#科目の振り分け 
#   
	if		($in1[3]	eq	"01")	{	#国語	
			$j	=	0;	
	}	
	elsif	($in1[3]	eq	"02")	{	#算数	
			$j	=	1;	
	}	
	elsif	($in1[3]	eq	"03")	{	#理科	
			$j	=	2;	
	}	
	elsif	($in1[3]	eq	"04")	{	#社会	
			$j	=	3;	
	}	
	elsif	($in1[3]	eq	"05")	{	#英語	
			$j	=	4;	
	}	
#   
#   
#生徒数
#   
	$sum[$i][$j][0]++;		#クラス別の生徒数
	$sum[3][$j][0]++;		#全クラスの生徒数
#   
#最高点(初期値:0)  
#   
		if	($sum[$i][$j][1]	<	$in1[4])	{
			$sum[$i][$j][1]		=	$in1[4];		#クラス別科目別の最高点
		}	
		if	($sum[3][$j][1]		<	$in1[4])	{	
			$sum[3][$j][1]		=	$in1[4];		#全クラスの科目別の最高点
		}	
#   
#最低点(初期値:100)    
#   
		if	($sum[$i][$j][2]	>	$in1[4])	{	
			$sum[$i][$j][2]		=	$in1[4];		#クラス別科目別の最低点
		}	
		if	($sum[3][$j][2]		>	$in1[4])	{	
			$sum[3][$j][2]		=	$in1[4];		#全クラスの科目別の最低点
		}	
#   
#平均点(初期値:0)(最後に生徒数で割る)  
#   
		$sum[$i][$j][3]			+=	$in1[4];		#クラス別科目別の合計点
		$sum[3][$j][3]			+=	$in1[4];		#全クラスの科目別の合計点
	}	
#   
#平均点算出 
#   
for	($i	=	0;	$i	<=3;	$i++)		{		
	for	($j	=	0;	$j	<=4;	$j++)	{		
#   
#   クラス別科目別で生徒数がゼロなら、最高点と最低点、平均点をブランクにする。    
#   それ以外は、クラス別科目別の平均点を算出する。    
#   
		if		($sum[$i][$j][0]	==	0)			{	
				$sum[$i][$j][1]		=	"";		#クラス別科目別の最高点
				$sum[$i][$j][2]		=	"";		#クラス別科目別の最低点
				$sum[$i][$j][3]		=	"";		#クラス別科目別の平均点
		}	
		else										{	
				$sum[$i][$j][3]		=	sprintf("%5.2f",$sum[$i][$j][3]	/	$sum[$i][$j][0]);
		}	
	}	
}	
#   
#成績データ出力 
#   
#　各列の項目
@out1_title	=	("項目","国語","算数","理科","社会","英語");		
#
#　各行の項目
@out1_item	=	("生徒数","最高点","最低点","平均点");
#
for	($i	=	0;	$i	<=3;	$i++)		{		
	for	($k	=	0;	$k	<=3;	$k++)	{		
		if			($k		==	0)			{	
			if		($i		==	0)			{
					print	OUT1	"１組\n";
			}
			elsif	($i		==	1)			{
					print	OUT1	"２組\n";
			}
			elsif	($i		==	2)			{
					print	OUT1	"３組\n";
			}
			elsif	($i		==	3)			{
					print	OUT1	"総合計\n";
			}

			$out1	=	join("\t",@out1_title);		#クラス名等出力
			print	OUT1	"$out1\n";	
		}	
		@out1	=	();	
		push(@out1,$out1_item[$k]);					#各行の項目名セット

		for	($j	=	0;	$j	<=4;	$j++)	{		
				push(@out1,$sum[$i][$j][$k]);		#各行の値セット
		}	
		$out1	=	join("\t",@out1);
		print	OUT1	"$out1\n";	
	}	
}	
close(IN1);	
close(OUT1);
