如何解决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 举报,一经查实,本站将立刻删除。