in reply to Re^2: enumerating values for slopes
in thread enumerating values for slopes

Although it probably does not have any consequences here, I would suggest that you avoid using the $a (and $b) variable, because $a and $b are special purpose global variables used for sorting data (and a few other specific uses).

Replies are listed 'Best First'.
Re^4: enumerating values for slopes
by Aldebaran (Curate) on Sep 23, 2014 at 05:04 UTC
    $ perl slope5.pl Can't use string ("4.3125") as an ARRAY ref while "strict refs" in use + at ../utils1.pm line 39. $ cat slope5.pl #!/usr/bin/perl -w use strict; use 5.010; use Math::Trig; BEGIN { push @INC, ".."; } use utils1; my @AoA; my $aoa_ref = \@AoA; my @vector = (4.3125, 0.4375); push @AoA, @vector; @vector = (4.375, 0.375); push @AoA, @vector; @vector = (4.4375, 0.375); print_aoa($aoa_ref); __END__ $

    Thought I would be comparing hypotenuses to heights but can't see why perl doesn't this is ok.

      The error occurs in the module, but the coding error is actually located in your calling program. When you do this:
      my @vector = (4.3125, 0.4375); push @AoA, @vector; @vector = (4.375, 0.375); push @AoA, @vector;
      you are not creating an array of arrays (AoA), but a simple array whose 4 elements are:
      (4.3125, 0.4375, 4.375, 0.375)
      You need to push on @AoA a reference to @vector:
      my @vector = (4.3125, 0.4375); push @AoA, \@vector; @vector = (4.375, 0.375); push @AoA, \@vector;
      or build
      directly an array reference:
      push @AoA, [4.3125, 0.4375]; push @AoA, [4.375, 0.375];
      I guess this should solve your issue.

      As I said earlier, you should avoid using the $a and $b variables, they are special variables used among other things for sorting, they behave differently from other variables, and using as you do them might lead to difficult-to-track bugs. You may use $c or $d, if you like, this will not be a problem, but I would personally put a more meaningful name helping comprehension of what they represent.

      Update: As pointed below by farang the first method above for building an AoA is actually buggy. Use the second one. Thanks to farang for picking that.

        You need to push on @AoA a reference to @vector:
        my @vector = (4.3125, 0.4375); push @AoA, \@vector; @vector = (4.375, 0.375); push @AoA, \@vector;
        That way is buggy, though, as the redefinition of @vector will clobber the first pushed array element. This is explained under COMMON MISTAKES in perldsc, "taking a reference to the same memory location repeatedly".

        So both lines above should instead use a square bracket reference.

        push @AoA, [ @vector ];

        $ perl sill2.pl elt 0 0 is 0.4375 elt 0 1 is 4.3125 elt 0 2 is bath-left elt 1 0 is 0.375 elt 1 1 is 4.375 elt 1 2 is bath-middle elt 2 0 is 0.375 elt 2 1 is 4.4375 elt 2 2 is bath-right bath-left has slope 5.82263230478133 bath-middle has slope 4.91710033552881 bath-right has slope 4.84767847916148 $ cat sill2.pl #!/usr/bin/perl -w use strict; use 5.010; use Math::Trig; BEGIN { push @INC, ".."; } use utils1; my @AoA; my $aoa_ref = \@AoA; my $vector_ref = [0.4375, 4.3125, "bath-left"]; push @AoA, $vector_ref; $vector_ref = [0.375, 4.375, "bath-middle"]; push @AoA, $vector_ref; $vector_ref = [0.375,4.4375, "bath-right"]; push @AoA, $vector_ref; print_aoa($aoa_ref); for my $i ( 0 .. $#AoA ) { my $ratio = $AoA[$i][0]/$AoA[$i][1]; my $rad = asin($ratio); my $degrees = rad2deg($rad); my $name = $AoA[$i][2]; say "$name has slope $degrees"; } __END__ $

        This might be the most robust version of this material.

      Your error is in the ../utils1.pm module, but you don't show the code for that module. Difficult to help you in such conditions.
        $ cd .. $ pwd /home/fred/Desktop/root3/pages/sills/template_stuff $ ls aimages config1.pm lime1.css pm4.txt basketball1.css football1.pm mango1.css rebus1.tmpl bathfan1.css football2.pm marvin1.css rebus2.tmpl blue1.css footer_center2.txt math1.pm rebus3.tmpl bom footer_center_begin.txt nibley1.pm rebus4.tmpl bottom1.txt footer_center.txt oibottom.txt rory1.css captions giles1.css oitop.txt ruscaptions ceres1.css hc_input2.txt pears1.css sills1.css code1.tmpl hc_input.txt plum1.css utils1.pm code2.tmpl html1.pm pluto1.css utils1.pm~ code3.tmpl lemon1.css pm1.txt watermelon1.cs +s $ cat utils1.pm package utils1; require Exporter; use config1; our @ISA = qw(Exporter); our @EXPORT = qw( invert_aoa print_hash print_aoa highest_number get_list zip_lists p_tag); sub invert_aoa{ use strict; use warnings; use 5.010; my $a = shift; my @AoA = @$a; my $k = $#AoA; #say "k is $k"; my @BoB; for my $i ( 0 .. $#AoA ) { my $aref = $AoA[$i]; my $x = $#{$aref}; #say "x is $x"; for my $j ( 0 .. $#{$aref} ) { $BoB[$j][$i]= $AoA[$i][$j]; } } my $b = \@BoB; return $b; } sub print_aoa{ use strict; use warnings; use 5.010; my $a = shift; my @AoA = @$a; for my $i ( 0 .. $#AoA ) { my $aref = $AoA[$i]; for my $j ( 0 .. $#{$aref} ) { print "elt $i $j is $AoA[$i][$j]\n"; } } return $a; } sub highest_number{ use strict; use File::Basename; use Cwd; my ($aref, $filetype, $word) = @_; my $number; my @matching; my $ext = ".".$filetype; push (@matching, 0); #min returned value for my $file (@{$aref}) { #print "file is $file\n"; if ($file =~ /^$word(\d*)$ext$/){ #print "matching is $file\n"; push (@matching, $1); } } @matching = sort @matching; my $winner = pop @matching; return $winner } sub print_hash{ my $hash_ref = shift; print "subroutine says this is your hash: \n"; my %hash = %$hash_ref; while ( (my $key,my $value) = each %hash ) { print "key: $key, value: $hash{$key}\n"; } } sub get_list{ use strict; use warnings; use 5.010; use File::Slurp; my $file = shift; my @lines = read_file($file); chomp(@lines); s/^\s+|\s+$//g for @lines; @lines = grep length, @lines; return @lines; } sub zip_lists { use strict; use warnings; use 5.010; use List::MoreUtils qw( zip ); my ($file1, $file2) = @_; my @file1lines = get_list($file1); my @file2lines = get_list($file2); say "keys are @file1lines"; say "values are @file2lines"; my %hash = zip @file1lines, @file2lines; return \%hash; } sub p_tag { use strict; use warnings; my $text = shift; my $before = '<p>'; my $after = '</p>'; my $return = $before.$text.$after; return \$return; } 1; $

      What I found when field measuring was that it was much more attainable to get hypotenuses and heights, so that left me looking for arcsin. I had hoped to get this processed as an AoA, but I'm not quite there yet....

      $ perl slope8.pl bath-left theta is 5.82263230478133 bath-middle theta is 4.91710033552881 bath-right theta is 4.84767847916148 dining-south theta is 15.2575232904564 john-north theta is 16.0133944239485 middle-front theta is 24.6243183521641 south-front theta is 14.4775121859299 $ cat slope8.pl #!/usr/bin/perl -w use strict; use 5.010; use Math::Trig; BEGIN { push @INC, ".."; } use utils1; my @AoA; my $aoa_ref = \@AoA; my $tja = 0.4375/4.3125; say "bath-left"; my $hja = asin $tja; my $degrees = rad2deg($hja); say "theta is $degrees"; $tja = 0.375/4.375; $hja = asin $tja; say "bath-middle"; $degrees = rad2deg($hja); say "theta is $degrees"; say "bath-right"; $tja = 0.375/4.4375; $hja = asin $tja; $degrees = rad2deg($hja); say "theta is $degrees"; say "dining-south"; $tja = 1.25/4.75; $hja = asin $tja; $degrees = rad2deg($hja); say "theta is $degrees"; say "john-north"; $tja = 1.0/3.625; $hja = asin $tja; $degrees = rad2deg($hja); say "theta is $degrees"; say "middle-front"; $tja = 1.875/4.5; $hja = asin $tja; $degrees = rad2deg($hja); say "theta is $degrees"; say "south-front"; $tja = 1.125/4.5; $hja = asin $tja; $degrees = rad2deg($hja); say "theta is $degrees"; __END__ $