Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Dear All, I need a help to add a feature to my perl script. the script takes as input a file & finds the maximum & minimum value of it. Based on the min and max value you can defined the scale by using the bin size. (user input) For example bin size is 30 and min -100ps max 100ps then the scale to be -100 to -80, -80 to -60, -60 to -40, -40 to -20, -20 to 0, 0 to 20, 20 to 40, 40 to 60, 60 to 80, 80 to 100 Count the number of points falling in the scale range and display the file similar as shown below.
-60 < x <= -30 ( 6273 pts) |** -30 < x <= 0 ( 44623 pts) |******** 0 < x <= 30 ( 55626 pts) +********** 30 < x <= 60 ( 11244 pts) |**
please find the code below,
my $file = $ARGV[0]; # input file my $bin = $ARGV[1]; # bin size normally 20 or 30 my $outfile = "temp.stat"; open (IN_LOG,"$file") || die "cannot open $file for reading: $!"; open (OUT_LOG,">$outfile") || die "cannot open $outfile for writing: $ +!"; my $colName; my @array; while (<IN_LOG>) { push (@array,$_); } } my @sortArray = sort { $a <=> $b } @array; $max = $sortArray[-1]; $min = $sortArray[0]; print OUT_LOG "#- - - - - - - - - - - - - - - - - - - - -\n"; print OUT_LOG "#MAX : $max \n"; print OUT_LOG "#MIN : $min \n"; print OUT_LOG "#- - - - - - - - - - - - - - - - - - - - -\n"; $temp=$max-$bin; while ($max>=$min) { $i=0; print OUT_LOG "\n$max > $bin < $temp:"; foreach $val (@array) { if($val<=$max && $val>=$temp) { $i+=1; } } $max= $temp; $temp=$temp-$bin; print OUT_LOG " $i pts "; my $star = int($i/500) + 0.5; $var= '*' x $star; print OUT_LOG "| $var\n "; } close IN_LOG; close OUT_LOG; close MYFILE;
currently i am able to sort the array & find the maximum & minimum values but not able to generate the scale/chart as shown above. the sampe of input file will be (as it is a huge file)
45.980 -34.99 89.00 35.87 75.00 -30.173 -40.178
thanks.

Replies are listed 'Best First'.
Re: generate a chart using the data
by hda (Chaplain) on Apr 17, 2009 at 10:49 UTC
    Hi,

    Reinventing the wheel can be a good way to learn. However, if you are in a rush, why not trying one of these:

    GD::Graph::Histogram

    http://search.cpan.org/~whizdog/GDGraph-histogram-1.1/lib/GD/Graph/histogram.pm

    or

    Perl Data Language (PDL) in connection with PGPLOT or PLplot.

    Hope this helps

Re: generate a chart using the data
by dHarry (Abbot) on Apr 17, 2009 at 11:23 UTC

    Your code does not compile it seems you have one "}" too many. Some variables you declare with my but most of them not?! I think you would benefit from adding:

    use warnings; use strict;

    It will catch/report various issues with your code.

Re: generate a chart using the data
by Utilitarian (Vicar) on Apr 17, 2009 at 11:16 UTC
    Does this also fail when used on a huge file?
    Your division by 500 means you're expecting multiples of 500 points in each range.

    This code does not work as presented, the

    while (<IN_LOG>) { push (@array,$_); } }
    should probably read
    while (<IN_LOG>) { chomp; push (@array,$_); }
    Try temporarily removing the $i/500 when using test data. To see what I mean, or set a suitable divisor print $i before division and see what sort of numbers are in each range

    Though this does throw open the option of creating a suitable divisor on the basis of the max value of $i relative to display/paper size, saving a record, @{@records[$count]}=( $max, $min $pts) which could then scale the highest value of $pts back to an acceptable value on printing to your log file.