in reply to Re: Hash of Hash Redux
in thread Hash of Hash Redux

That works like a charm. Thanks very much for the help!

I have another thing...of course...the life of a noobie

I want to now make @ind, @chroma @chromb interactive for each population

I call the sub with
for my $poper (1 .. $popCt) { input(); gener(@chroma, @chromb, @ind); }
Here is the sub...
sub input { my ($upper, $lower); my $center = 1; print 'Enter lower bound: '; chomp ($lower = <STDIN>); print 'Enter upper bound: '; chomp ($upper = <STDIN>); my $ranpop; while ($center--) { $ranpop = int rand($upper - $lower + 1) + $lower; print $ranpop . "\n"; my @ind = (1...$ranpop); my $limiter = 50; while ($ranpop) { my $genea = int rand ($limiter); push(my @chroma, $genea); my $geneb = int rand ($limiter); push(my @chromb, $geneb); $ranpop--; } return @chroma, @chromb, @ind; } }
Again this should work, but I am lost again. The @chroma, @chromb, @ind will then go into the hash maker that you all got working for me

Also you all can yell at me all you want about use strict...no perl books have told me how to do that! I am flying without a net! Any good references?

Replies are listed 'Best First'.
Re^3: Hash of Hash Redux
by johngg (Canon) on Oct 31, 2007 at 19:20 UTC
    I am not sure what you are trying to do in terms of the algorithm but there are a few problems with your code.

    Firstly, you do push(my @chroma, $genea); and push(my @chromb, $geneb); inside the scope of the while ($ranpop) { ... } loop. That means that each time around the loop you create new lexically scoped arrays to push data onto and by the time you get to the return they are out of scope so inaccessible.

    Secondly, I'm not sure what you are doing with the

    my $center = 1; ... while ($center--) { ... return ... ; }

    That loop is meaningless as it stands because it is going to terminate early with the return and would only run the once anyway. If your $center is more than 1 it will still do the same thing as the return will always leave the subroutine. Perhaps the return should me moved to after the loop.

    Thirdly, if you want to return more than one array (or hashes for that matter) from a subroutine you must return them by reference because from the caller's point of view, the three arrays you return come back as one big list. Do it something like this.

    sub makeArrays { my @arrA = ( 1 .. 6 ); my @arrB = qw{ fred joe bill pete }; my @arrC = ( 1, 3, q{abc}, 8 ); return \@arrA, \@arrB, \@arrC; } my ( $refToArrA, $refToArrB, $refToArrC ) = makeArrays(); my @newArrA = @$refToArrA; my $elemTwoOfArrB = $refToArrB->[2];

    I hope this is of use.

    Cheers,

    JohnGG

      Yes it was of pleanty of use. But tell me, am I trying to do the impossible? Here is where I am right now...without the help my comp would go out the window
      use warnings; use strict; use Data::Dumper; my $popCt = 4; my %HoH; for (1 .. $popCt) { my ( $refToArrA, $refToArrB, $refToArrC ) = makeArrays(); &gener(); } print Data::Dumper->Dumpxs([\%HoH], [q{*HoH}]); sub makeArrays { my ($upper, $lower); print 'Enter lower bound: '; chomp ($lower = <STDIN>); print 'Enter upper bound: '; chomp ($upper = <STDIN>); my @chroma; my @chromb; my $ranpop; $ranpop = int rand($upper - $lower + 1) + $lower; print $ranpop . "\n"; my @arrA = ( 1 .. $ranpop ); my $limiter = 50; my @holda; my @holdb; while ($ranpop) { my $genea = int rand ($limiter); push(@holda, $genea); my $geneb = int rand ($limiter); push(@holdb, $geneb); $ranpop--; } my @arrB = ( @holda ); my @arrC = ( @holdb ); return \@arrA, \@arrB, \@arrC; } sub gener { my @newind = @$refToArrA; my @newchroma = @$refToArrB; my @newchromb = @$refToArrC; for my $pop ( 1 .. $popCt ) { $HoH{$pop} = { individual => [ @newind ], chromasome1 => [ @newchroma ], chromasome2 => [ @newchromb ], }; } }
      In an ideal world I would have 4 populations with 4 different sets of individuals with 4 different sets of chromosome A and B's. At this point I feel like I am going about this all wrong...

      I know strict and warnings are returing things...but I don't know what they mean, google only helps so much.

      I really appreciate the help, but tell me if I ask the impossible.

        I know strict and warnings are returing things...but I don't know what they mean, google only helps so much.

        So in other words, you see these three messages and you don't know what they mean?

        Global symbol "$refToArrA" requires explicit package name at /tmp/junk +.pl line 53. Global symbol "$refToArrB" requires explicit package name at /tmp/junk +.pl line 54. Global symbol "$refToArrC" requires explicit package name at /tmp/junk +.pl line 55.
        You can figure out that lines 53, 54 and 55 are the first three lines after "sub gener". Now, you do have to read a bit about what "my" does in perl, so that you can figure out that in your main "for" loop (over "1 .. $popCt"), the three variables declared there with "my (...)" are not visible (are inaccessible, do not exist) outside the scope of the for loop. Those variables need to be passed to the "gener()" sub as parameters, so that the sub will have access to them, because the "gener" sub is defined outside the scope of the for loop. So do it like this:
        for ( 1 .. $popCt ) { my ( $refToArrA, $refToArrB, $refToArrC ) = makeArrays(); &gener( $refToArrA, $refToArrB, $refToArrC ); } # ... sub gener { my ( $refToArrA, $refToArrB, $refToArrC ) = @_; ... }
        That will get rid of the syntax errors (which were imposed because you have "use strict;" at the top). I don't know whether the script does exactly what you want, but it does run, and produces output in a coherent way.
Re^3: Hash of Hash Redux
by GrandFather (Saint) on Oct 31, 2007 at 20:00 UTC

    Strictures (strict and warnings) turn on various extra checking for dubious practices or programming errors. use strict requires (among many other things) that variables are declared (using my) and that various techniques that often cause confusion or have been made redundant in newer versions of Perl are not used.

    use warnings makes various run time checks. The most important one is that variables have been initialized before their contents are used. Together these two strictures provide an extremely useful early warning system for many common coding mistakes. Always use strictures in Perl. ;)


    Perl is environmentally friendly - it saves trees