http://qs1969.pair.com?node_id=1218764

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

I have an array of 100 floating point values. I rounded the values to the tenths place in order to create more matches on my histogram. I was wondering how to get these values in an array and put them into a histogram. I have previously checked other posts on PerlMonks, but I end up with errors in my code. I am relatively new to programming in general and I might lack certain programming etiquette or syntax.

use strict; use warnings; use Data::Dumper; use 5.010; use GD::Graph::histogram; use YAML; use CGI ':standard'; sub main { my $input = 'distance.txt'; unless(open(INPUT, $input)) { die "\nCannot open input\n"; } my @data; while(my $line = <INPUT>) { chomp $line; my @rounded = sprintf ("%.1f\n", $line); push @data, @rounded; my ( $filename, @data ) = @_; my $graph = new GD::Graph::histogram(400,600); $graph->set( y_label => 'Count', x_label => 'Distances', title => 'Histogram', x_labels_vertical => 1, bar_spacing => 0, shadow_depth => 1, shadowclr => 'dred', transparent => 0, ) or warn $graph->error; my $image = $graph->plot(\@data) or die $graph->error; open( IMG, '>' . $filename ) or die $!; binmode IMG; print IMG $image->png; } } main();

These are the error messages I have been receiving.

Subroutine main::Dump redefined at /System/Library/Perl/5.18/CGI.pm li +ne 308. Use of uninitialized value $min in subtraction (-) at /Library/Perl/5. +18/GD/Graph/histogram.pm line 110, <INPUT> line 1. Use of uninitialized value $max in subtraction (-) at /Library/Perl/5. +18/GD/Graph/histogram.pm line 110, <INPUT> line 1. Use of uninitialized value $max in numeric le (<=) at /Library/Perl/5. +18/GD/Graph/histogram.pm line 118, <INPUT> line 1. Use of uninitialized value $upper in numeric le (<=) at /Library/Perl/ +5.18/GD/Graph/histogram.pm line 118, <INPUT> line 1. Use of uninitialized value $lower in addition (+) at /Library/Perl/5.1 +8/GD/Graph/histogram.pm line 119, <INPUT> line 1. Use of uninitialized value $max in numeric le (<=) at /Library/Perl/5. +18/GD/Graph/histogram.pm line 122, <INPUT> line 1. Use of uninitialized value in string eq at /Library/Perl/5.18/GD/Graph +/histogram.pm line 42, <INPUT> line 1. Use of uninitialized value in subtraction (-) at /Library/Perl/5.18/GD +/Graph/histogram.pm line 59, <INPUT> line 1. Use of uninitialized value in addition (+) at /Library/Perl/5.18/GD/Gr +aph/histogram.pm line 59, <INPUT> line 1. Use of uninitialized value $filename in concatenation (.) or string at + /Users/Joshua/eclipse-workspace/PlottingPoints/Histogram line 40, <I +NPUT> line 1. No such file or directory at /Users/Joshua/eclipse-workspace/PlottingP +oints/Histogram line 40, <INPUT> line 1.

2018-07-20 Athanasius added code tags around error messages

Replies are listed 'Best First'.
Re: Histogram Creation
by toolic (Bishop) on Jul 18, 2018 at 16:03 UTC
    I can't reproduce your output, but here is a simplified version of your code that creates an output PNG file for me (if I input some simple numbers in a file):
    use strict; use warnings; use GD::Graph::histogram; my $input = 'distance.txt'; unless(open(INPUT, $input)) { die "\nCannot open input\n"; } my @data; while(my $line = <INPUT>) { chomp $line; push @data, sprintf ("%.1f\n", $line); } my $graph = new GD::Graph::histogram(400,600); $graph->set( y_label => 'Count', x_label => 'Distances', title => 'Histogram', x_labels_vertical => 1, bar_spacing => 0, shadow_depth => 1, shadowclr => 'dred', transparent => 0, ) or warn $graph->error; my $image = $graph->plot(\@data) or die $graph->error; open( IMG, '>' . 'out.png' ) or die $!; binmode IMG; print IMG $image->png;

    Post a few lines of your input file (inside "code" tags).

    Your $filename variable is undefined because you didn't pass any arguments to your "main" sub. @_ holds args passed to a sub. Also, you keep clobbering your @data when you assign it to @_ (which is empty).

Re: Histogram Creation
by Your Mother (Archbishop) on Jul 18, 2018 at 17:04 UTC

    Regarding Subroutine main::Dump redefined at /System/Library/Perl/5.18/CGI.pm line 308

    YAML is bringing &Dump into main:: and then when you use CGI ":standard"; it also exports its own &Dump (with the :standard set you're calling). In your particular code, you're using neither so remove either or both. Or use them with empty import lists, e.g., use CGI ();.

    moo@cow[625]~>perl -mYAML -MCGI=:standard -we 1 # ^^^ No problem, -m means "use YAML ()" moo@cow[626]~>perl -MYAML -MCGI=:standard -we 1 Subroutine main::Dump redefined at /home/moo/perl5/lib/perl5/CGI.pm li +ne 296.
Re: Histogram Creation
by hippo (Bishop) on Jul 18, 2018 at 16:10 UTC
    my ( $filename, @data ) = @_;

    Can you explain what this line is supposed to do?

    A reply falls below the community's threshold of quality. You may see it by logging in.
Re: Histogram Creation
by talexb (Chancellor) on Jul 19, 2018 at 14:09 UTC

    On a stylistic note, the layout that you've used:

    sub main { .. some code .. .. more code .. } main();
    drives me absolutely bananas.

    The routine main is not, and never will be, a sub-routine. main is main. The main-line program. That's what gets run.

    How about instead structuring it as

    { .. some code .. .. more code .. }
    By definition, that's implicitly main. You could even pretend it's a shell script (from whence Perl came), and do this:
    .. some code .. .. more code ..

    My personal preference is to have braces, if only to remind me that this is a procedure (even if it is really close to a shell script).

    Alex / talexb / Toronto

    Thanks PJ. We owe you so much. Groklaw -- RIP -- 2003 to 2013.

      My personal preference is to have braces ...

      My practice for largeish scripts is to have a block with a nice, big label on it and protection for unexpected exit from the block:

      MAIN: { ... exit; # normal script exit } # end MAIN loop die "unhandled script exit"; # subroutines ############################################### ...


      Give a man a fish:  <%-{-{-{-<