微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

perl 得到 0 而不是输出

如何解决perl 得到 0 而不是输出

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

Name,Category,Assignment,score,Possible,Al,test,T1,90,100
Ben,80,100
Al,lab,L1,76,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";
}

预期输出

Name Average   Low High
Q1       83    76    90
L1       73.5  67    80

解决方法

主要问题:

  • 您从不向 $type 分配任何内容。 (它甚至没有声明)。

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

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

  • 您不会在标题后发出换行符。

始终使用 use strict; use warnings;

,

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,80,100
Al,lab,L1,76,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",100

输出

Name    Average Low     High
L1      71.5    67      76
T1      85      80      90

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。