perl获取0而不是输出

perl获取0而不是输出,perl,if-statement,curly-braces,Perl,If Statement,Curly Braces,我正在处理的文件的列中包含以下信息 正在尝试获取每个名称的名称、平均值、最小值和最大值 Name, Category, Assignment, Score, Possible, Al, test, T1, 90, 100 Ben, test, T1, 80, 100 Al , lab, L1, 76, 100 Ben,

我正在处理的文件的列中包含以下信息 正在尝试获取每个名称的名称、平均值、最小值和最大值

Name,   Category,    Assignment,  Score,   Possible,
Al,        test,        T1,         90,      100
Ben,       test,        T1,        80,      100
Al ,      lab,         L1,         76,      100
Ben,       lab,         L1,         67,      100
我对代码的第一个问题是它一直说在第25行有一个非法的除法,我改变了一些东西,现在我得到了

Name Average Min Max0
作为我的输出,而不是任何实际的数学运算 我不确定我的问题在哪里

#!/usr/bin/perl
my %total;
my %count;
my %min;
my %max;
while(<>){
    chomp;
    @fields = split(/,/, $_);
    if(@fields[0] !~ /Student/){
        $total{@fields[2]} += @fields[5];
        $count{@fields[5]}++;
    }
    if($min{@fields[2]} > @fields[5]){
        $min{@fields[2]} = @fields[5];
    } elsif($min{@fields}[2] == 0){
        $min{@fields[2]} = @fields[5];
    }
    if($max{@fields[2]} < @fields[5]){
        $max{@fields[2]} = @fields[5]
    }
}
print "Name\tAverage\tMin\tMax";
foreach $total(keys %count){
    print $total . "\t" . $total{$type}/$count{$type} . $min{$type} . "\t" . $min{$type} . "\t". $max{$type} . "\n";
}
主要问题是:

  • 您从未将任何内容分配给
    $type
    。(甚至还没有申报)

  • %count
    只有一个元素,因为
    @fields[5]
    始终未定义,因为您的数据只有5个字段

  • $total
    不是计数;这是由
    @fields[5]
    返回的值(字符串化)

  • 标题后不发出换行符


始终使用
严格使用;使用警告

已经描述了OP的错误,接下来的代码演示如何利用哈希来命名数据字段。这种方法应该使代码更易于阅读和理解,并且不需要计算特定字段的数字

use strict;
use warnings;
use feature 'say';

my @fields = qw/Name Category Assignment Score Possible/;
my(%data,$result);

while(<DATA>) {
    next if /$fields[0]/;
    @data{@fields} = split(/[\s,]+/,$_);
    $result->{$data{Assignment}}{min} = $result->{$data{Assignment}}{min} // 100;
    $result->{$data{Assignment}}{max} = $result->{$data{Assignment}}{max} // 0;
    $result->{$data{Assignment}}{min} = $data{Score}
        if $data{Score} < $result->{$data{Assignment}}{min};
    $result->{$data{Assignment}}{max} = $data{Score}
        if $data{Score} > $result->{$data{Assignment}}{max};
    $result->{$data{Assignment}}{total} += $data{Score};
    $result->{$data{Assignment}}{count}++;
}

my @header = qw/Name Average Low High/;
say join("\t",@header);

for( sort keys %$result ) {
    say join("\t",
                (   
                    $_,
                    $result->{$_}{total}/$result->{$_}{count},
                    $result->{$_}{min},
                    $result->{$_}{max}
                )
            );
}

__DATA__
Name,   Category,    Assignment,  Score,   Possible,
Al,        test,        T1,         90,      100
Ben,       test,        T1,        80,      100
Al ,      lab,         L1,         76,      100
Ben,       lab,         L1,         67,      100

当你的数据只有5个字段时,为什么要使用6个字段?哦,糟糕,我忘了在我的文件中添加它们了!不能将字符串
T1
添加到数字
100
。增加
使用严格;使用警告
添加到您的代码中,并修复出现的错误。我继续添加了它,提供了示例数据
$fields[5]
未定义的
,因为它不存在。我故意没有为他们做作业。那里重复键入了很多。
use strict;
use warnings;
use feature 'say';

my @fields = qw/Name Category Assignment Score Possible/;
my(%data,$result);

while(<DATA>) {
    next if /$fields[0]/;
    @data{@fields} = split(/[\s,]+/,$_);
    $result->{$data{Assignment}}{min} = $result->{$data{Assignment}}{min} // 100;
    $result->{$data{Assignment}}{max} = $result->{$data{Assignment}}{max} // 0;
    $result->{$data{Assignment}}{min} = $data{Score}
        if $data{Score} < $result->{$data{Assignment}}{min};
    $result->{$data{Assignment}}{max} = $data{Score}
        if $data{Score} > $result->{$data{Assignment}}{max};
    $result->{$data{Assignment}}{total} += $data{Score};
    $result->{$data{Assignment}}{count}++;
}

my @header = qw/Name Average Low High/;
say join("\t",@header);

for( sort keys %$result ) {
    say join("\t",
                (   
                    $_,
                    $result->{$_}{total}/$result->{$_}{count},
                    $result->{$_}{min},
                    $result->{$_}{max}
                )
            );
}

__DATA__
Name,   Category,    Assignment,  Score,   Possible,
Al,        test,        T1,         90,      100
Ben,       test,        T1,        80,      100
Al ,      lab,         L1,         76,      100
Ben,       lab,         L1,         67,      100
use strict;
use warnings;
use feature 'say';

my $result;

while(<DATA>) {
    next if /^Name/;
    my($assig,$score) = (split(/[\s,]+/,$_))[2,3];
    $result->{$assig}{min} = $result->{$assig}{min} // 100;
    $result->{$assig}{max} = $result->{$assig}{max} // 0;
    $result->{$assig}{min} = $score
        if $score < $result->{$assig}{min};
    $result->{$assig}{max} = $score
        if $score > $result->{$assig}{max};
    $result->{$assig}{total} += $score;
    $result->{$assig}{count}++;
}

my @header = qw/Name Average Low High/;
say join("\t",@header);

for( sort keys %$result ) {
    say join("\t",
                (   
                    $_,
                    $result->{$_}{total}/$result->{$_}{count},
                    $result->{$_}{min},
                    $result->{$_}{max}
                )
            );
}

__DATA__
Name,   Category,    Assignment,  Score,   Possible,
Al,        test,        T1,         90,      100
Ben,       test,        T1,        80,      100
Al ,      lab,         L1,         76,      100
Ben,       lab,         L1,         67,      100
Name    Average Low     High
L1      71.5    67      76
T1      85      80      90