2

我正在用 Perl 为我的作业编写一个小程序,而且我是 Perl 的新手。

我编写的代码为我提供了我需要的完全相同的值,但是在创建条形图时出现此错误。

Invalid data set: 0 at line 67

第 67 行在下面的代码中标有注释。

x轴中存储的值是:

40 44 48 52 64 76 83 104 105 148 149 249 431 665 805 1420 1500 

y_axis 是:

16 1  1 6 1 1 1 1 1 1 1 1 1 1 1 2 5 

这是我的代码:

use GD::Graph::bars;

open(CHECKBOOK,"c:\\Perl\\bin\\ip_packet_trace1.txt");

my $counter = -1;
my @sizearray = {};
while ($record = <CHECKBOOK>) {
    @array = split(/\t/,$record);
    $counter++;
    $sizearray[$counter] = $array[6];

}

$counter++;

my @array1 = sort {$a <=> $b} @sizearray;
print "$counter\n";
print "@array1\n";


my @freq = {0...0};

foreach $elem (@array1){

    my $s = $freq[$elem]+1;

    $freq[$elem] = $s;
}


my $size = @freq;
my @x_axis = {};
my @y_axis = {};

my $count2 = -1;


for($i = 1; $i < $size; $i++){

    my $elem = $freq[$i];

    if($elem  and $elem > 0  ){

        $count2++;

        $x_axis[$count2] =  $i;

        $y_axis[$count2] = $elem;
    }

}


print "@x_axis \n";
print "@y_axis \n";




my $mygraph = GD::Graph::bars->new(500, 300); # line 67

$mygraph->set(x_label     => 'Month',

y_label     => 'Number of Hits',

title       => 'Number of Hits in Each Month in 2002',

) or warn $mygraph->error;

my @data = {@x_axis,@y_axis};



my $myimage = $mygraph->plot(\@data) or die $mygraph->error;

open(IMG, '>C:\\image\\file.gif') or die $!;

binmode IMG;

print IMG $myimage->gif;

close IMG;
4

4 回答 4

3

我认为你的任务@data可能是罪魁祸首。

my @data = {@x_axis,@y_axis};

这将创建一个包含一个元素的数组。那一个元素是一个哈希。GD::Graph文档显示您需要一个数组数组。daotoad如前所述,这就是Data::Dumper派上用场的地方。尝试以下方法:

use Data::Dumper;
my @x_axis = 1...100;
my @y_axis = "a"..."z";
my @data = {@x_axis,@y_axis};
warn Dumper(\@data);

您可以看到数据是如何被解释的,并看到它与GD::Graph 示例不同:

@data = ( 
    ["1st","2nd","3rd","4th","5th","6th","7th", "8th", "9th"],
    [    1,    2,    5,    6,    3,  1.5,    1,     3,     4],
    [ sort { $a <=> $b } (1, 2, 5, 6, 3, 1.5, 1, 3, 4) ]
  );
于 2009-04-06T16:18:57.047 回答
2

use strictuse warnings。如果您使用这些 pragma,您在此代码中遇到的许多麻烦事都会被标记出来。

您还花费了大量精力来追加到数组的末尾。您可以push在不知道最后一项的索引的情况下使用它来执行此操作。像这样使用 push 可以让你简化你的代码。

用于()制作一个空数组(实际上是很好的列表)。用于[]进行数组引用。用于{}进行哈希引用。您一直在许多地方使用哈希引用。

最好使用词法文件句柄而不是全局文件句柄。使用全局文件句柄就是使用不必要的全局变量,这是自找麻烦。还要检查您对 的调用是否成功open

open( my $fh, '<', 'path/to/file)
    or die "Unable to open data file - $!\n";

当您使用数据结构时,Data::Dumper 是一个有用的模块,可以查看发生了什么。

use Data::Dumper;

my $foo = {
  bar => [ 0..5],
  baz => { a..z },
};

my @qux = ( [qw/a b c d/], [0..5] );

print Dumper $foo;
print Dumper \@qux;

perldsc另外,看看perlreftut他们有很好的例子来说明如何使用引用和嵌套数据结构。

于 2009-04-06T15:58:09.453 回答
1

我不太确定我在看什么,但我突然想到一件事:您正在将数组初始化为哈希引用:

hektor ~ $ perl -e '@sizearray = {}; print @sizearray, "\n"'
HASH(0x8031c0)

如果你想要的只是一个空数组,你可以简单地说:

my @sizearray;

如果你想明确它是新的和空的,你需要括号;见下文。(然而,正如布拉德在评论中所说,这是多余的。您可能应该习惯于查看和编写更简单的版本。)

my @sizearray = ();

数组存储有序列表,列表放在括号中。查看perldoc perldata更多。

于 2009-04-06T12:08:44.683 回答
1

K. 我测试并修改了你的代码。下面的代码有效。大家提到的数组部分很重要,但不是你唯一的问题。cpan 中的示例是一个匿名数组,因此您只需传递 2 个对 @data 的引用,而不是传递 @data 2 个数组。

#!/usr/bin/perl
#
use GD::Graph::bars;

my $size = @freq;
my @x_axis = qw(40 44 48 52 64 76 83 104 105 148 149 249 431 665 805 1420 1500);
my @y_axis = qw(16 1  1 6 1 1 1 1 1 1 1 1 1 1 1 2 5);

my $mygraph = GD::Graph::bars->new(500, 300); # line 67
$mygraph->set(x_label     => 'Month',
            y_label     => 'Number of Hits',
            title       => 'Number of Hits in Each Month in 2002',
) or warn $mygraph->error;
my @data = (\@x_axis,\@y_axis); # the important part.
my $myimage = $mygraph->plot(\@data) or die $mygraph->error;

open(IMG, '>helping_graph.gif') or die $!;
binmode IMG;
print IMG $myimage->gif;
close IMG;
于 2009-04-06T20:31:20.403 回答