Perl вычисляет средние средние значения для любого файла, начинающегося с "class"

Я пишу скрипт perl для домашней работы, который принимает любые файлы, начинающиеся с "class", и распечатывает заголовок класса и среднее значение каждого ученика в файле.

ВХОД:

$cat class1
Sam 90, 95, 82
Max 88, 90, 86
Alex 85, 92, 90
$cat class2
Student1 87, 91, 86
Student2 84, 89, 88
Student3 84, 90, 93

ВЫВОД:

*****class1*****
Sam: 89
Max: 88
Alex: 89
*****class2*****
Student1: 88
Student2: 87
Student3: 89

Текущая попытка скрипта:

#!/usr/bin/perl

@gradefiles = <class*>;

foreach (@gradefiles){
 print "****".$_."****\n";
 my %grades;
 my %average;
 open(DATA, $_) || die "Can't open $_: $!\n";
 while (<data>){
 my ($student, @vals) = split(/\t/);
 $grades{$student} = \@vals;
 }
 keys %grades;
 while(my($k, $v) = each %grades){
 my @igrades = split(',',$v);
 my $total = 0;
 foreach (@igrades){
 $total += $_;
 }
 my $length = @igrades;
 my $avg = $total / $length;

 $average{$k} = \$avg;
 }

 keys %average;
 while(my($k, $v) = each %average){
 print $k." ".$v."\n";
 }
}
</data></class*>

ТЕКУЩИЙ ВЫХОД:

****class1****
Sam 90, 95, 82
SCALAR(0x2036100)
Alex 85, 92, 90
SCALAR(0x202ab38)
Max 88, 90, 86
SCALAR(0x2034710)
****class2****
Student3 84, 90, 93
SCALAR(0x2034740)
Student2 84, 89, 88
SCALAR(0x2034728)
Student1 87, 91, 86
SCALAR(0x202a298)

===== UPDATE ==== мой новый код

#!/usr/bin/perl

@gradefiles = <class*>;

foreach (@gradefiles){
 print "****".$_."****\n";
 my %grades;
 my %average;
 open(DATA, $_) || die "Can't open $_: $!\n";
 while (<data>){
 my ($student, @vals) = split(/\t/);
 $grades{$student} = @vals;
 }

 for my $name (keys %grades){
 my @igrades = split(',',$grades{$name});
 my $total = 0;
 for my $grade (@igrades){
 $total += $grade;
 }
 my $length = @igrades;
 my $avg = $total / $length;

 $average{$name} = $avg;
 }

 for my $name (keys %average){
 print $name.": ".$average{$name}."\n";
 }
}
</data></class*>

Мой новый результат:

****class1****
Sam 90, 95, 82
: 0
Alex 85, 92, 90
: 0
Max 88, 90, 86
: 0
****class2****
Student3 84, 90, 93
: 0
Student2 84, 89, 88
: 0
Student1 87, 91, 86
: 0

РАБОЧИЙ СКРИПТ

#!/usr/bin/perl

@gradefiles = <class*>;

foreach (@gradefiles){
 print "****".$_."****\n";
 my %grades;
 my %average;
 open(DATA, $_) || die "Can't open $_: $!\n";
 while (<data>){
 my ($student, $vals) = split(/\t/);
 $grades{$student} = $vals;
 }

 for my $name (keys %grades){
 my @igrades = split(',',$grades{$name});
 my $total = 0;

 for my $grade (@igrades){
 $total += $grade;
 }
 my $length = @igrades;

 my $avg = $total / $length;

 $average{$name} = $avg;
 }

 for my $name (keys %average){
 print $name.": ".$average{$name}."\n";
 }
}
</data></class*>
2 ответа

Я думаю, что ты немного смущаешься. Вам не нужен какой-либо хэш, который вы строите.

#!/usr/bin/perl

use strict;
use warnings;
use 5.010; # For 'say'

foreach my $class (<class*>) {
 say "****$class****";

 # Three-arg open, lexical filehandle. Modern Perl best practice 
 open my $data, '<', $class or die "Can't open $class: $!\n";

 while (<$data>) {
 my ($student, @data) = split /[\s,]+/;
 say "$student: ", avg(@data);
 }
}

sub avg {
 my $total;
 $total += $_ for @_;

 return $total / @_;
}
</class*>


Вы делаете это:

$average{$k} = \$avg;

Что хранит ссылку на скаляр. Таким образом, когда вы печатаете $average{$k}, вы печатаете ссылку на скаляр, который является SCALAR(0x202a298). Измените строку так:

$average{$k} = $avg;

... и все должно работать.

licensed under cc by-sa 3.0 with attribution.