Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Changing name of ARRAY in each iteration

by cool (Scribe)
on Aug 10, 2006 at 12:34 UTC ( #566603=perlquestion: print w/replies, xml ) Need Help??

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


Dear monks
I am not able to figure out how to give a new name to array for each iteration of 'for' loop. Below is the part of a big code so pl bear with me. I am concerned with 'LINE C' only. This works for LINE A and B perfectly but for LINE C, it is showing
Type of arg 1 to push must be array (not concatenation (.) or string) +at avgshuffle.pl line 36, near "})" Execution of avgshuffle.pl aborted due to compilation errors.
Pl tell me how can I change the array of the problem in every iteration.. and if possible what is the better way of solving this mess.
Thank you for taking out time to read this
for (my $x=1; $x<=5; $x++) { open (AA, "shuffle$x"); # LINE A my $Sequence; while (<AA>) { $Sequence=$_; } close(AA); my %Winenergy = Energy($Sequence,$dinu_r); open (OUT, ">shuffle$x.stb"); # LINE B foreach my $el1(sort{$a <=> $b} keys %Winenergy) { print @energy.$x; push(@energy.$x , $Winenergy{$el1}); #LINE C # print OUT "$el1\t $Winenergy{$el1}\n"; } #print OUT "\n"; close (OUT); } sub Energy { .... } open(FILE,">total_shuffle.stb"); $m=8; for($j=0;$j<$i;$j++) { $avg = ($energy1[$j]+$energy2[$j]+$energy3[$j]+$energy4[$j]+$energy5[$ +j])/5; print FILE "$m\t$avg\n"; $m++; } close (FILE);

formatting added by GrandFather

Replies are listed 'Best First'.
Re: Changing name of ARRAY in each iteration
by davorg (Chancellor) on Aug 10, 2006 at 12:37 UTC

    You almost certainly want a different data structure - perhaps an array of arrays or a hash of arrays. See the Data Structures Cookbook for more detail.

    --
    <http://dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

Re: Changing name of ARRAY in each iteration
by liverpole (Monsignor) on Aug 10, 2006 at 13:14 UTC
    Hi cool,

    First of all, please put the following two lines at the top of your program:

    use strict; use warnings;

    Then, when you rerun the program, you will get a bunch of errors:

    Global symbol "$dinu_r" requires explicit package name at x line 15. Global symbol "@energy" requires explicit package name at x line 20. Global symbol "@energy" requires explicit package name at x line 21. Type of arg 1 to push must be array (not concatenation (.) or string) +at x line 21, near "})" syntax error at x line 29, near "..." Execution of x aborted due to compilation errors.

    Obviously the syntax error at x line 29, near "..." is caused by the "..." you used to show omitted code, so you can ignore that (or, better yet, comment it out).  For the 3 errors containing "requires explicit package name", you should declare them somewhere using "my", and assign them as well.  Until you do, we can't know for sure what the problem in your program is.

    Another thing you should absolutely do is provide error-checking when opening files doesn't work.  If you aren't successful opening an input file, it's pretty pointless to keep going, and trying to read from the input filehandle!  Here's an example of how you can check the results of your open:

    my $input = "shuffle$x"; open (AA, $input) or die "Can't open input '$input' ($!)\n"; # LINE A

    If you can fix these problems, try resubmitting the program.


    s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/

      Dear Liverpole,
      First of all thanx for taking interest in this. Following is the code the way you asked. Now it is showing these errors
      lobal symbol "@energy" requires explicit package name at monk.pl line 29. Type of arg 1 to push must be array (not concatenation (.) or string) at monk.pl line 29, near "})" Execution of monk.pl aborted due to compilation errors.
      By the way, to rephrase my question, as 'second reply' has rightly put it, I am looking to change the array name dynamically... How this can be possible? Pl help..
      #!/usr/bin/perl -w use strict; my $dinu_r; my $energy; my @energy1; my @energy2; my @energy3; my @energy4; my @energy5; my $i; for (my $x=1; $x<=5; $x++) { open (AA, "shuffle$x")or die "Can't open input ($!)\n"; # LINE A my $Sequence; $i=length($Sequence); while (<AA>) { $Sequence=$_; } close(AA); my %Winenergy = Energy($Sequence,$dinu_r); open (OUT, ">shuffle$x.stb"); # LINE B foreach my $el1(sort{$a <=> $b} keys %Winenergy) { push(@energy.$x , $Winenergy{$el1}); #LINE C # print OUT "$el1\t $Winenergy{$el1}\n"; } #print OUT "\n"; close (OUT); } sub Energy{ my ($sequence,$dinu_r) = @_; my %dinu = %$dinu_r; my $frame=1; my $win=15; my $lensequence = length($sequence); #length of the genome sequence my $limit1 = $lensequence-$win+1; #no of windows my $wincenpos = 1+($win-1)/2; #centre postion for the first window my %winenergy = (); my $j = 0; #starting position of the window while($j<$limit1) { my $winseq = substr($sequence,$j,$win); my $energy = 0; for(my $k =0; $k < $win-1; $k++) { my $dinucle_temp = substr($winseq,$k,2); my $dinucle = uc($dinucle_temp); $energy = $energy + $dinu{$dinucle}; }#end for $k my $wincentre = $j+$wincenpos; $winenergy{$wincentre} = $energy; $j = $j+$frame; }#end for $j return %winenergy; } open(FILE,">total_shuffle.stb"); my $m=8; for(my $j=0;$j<$i;$j++) { my $avg = ($energy1[$j]+$energy2[$j]+$energy3[$j]+$energy4[$j]+$energy +5[$j])/5; print FILE "$m\t$avg\n"; $m++; } close (FILE);
        I am looking to change the array name dynamically... How this can be possible?

        It's possible using a Perl feature called "symbolic references", but they are usually a very dangerous idea. So dangerous, in fact, that one of the effects of adding "use strict" to your program (and you should _always_ add "use strict" to your program) is to ban their use.

        I know you think that this is the best solution to your problem, but it really isn't. There's always a better solution.

        --
        <http://dave.org.uk>

        "The first rule of Perl club is you do not talk about Perl club."
        -- Chip Salzenberg

        Looking at this "more complete"(?) version of your code, it's actually easier for me to say how it can be done without trying to use "dynamic array names", and instead using an appropriate data structure (an array of arrays, or AoA). So I'll try to do that by showing how I would rewrite this.

        But in trying to revise your code, I found a number of other problems, which will probably lead to unintended results. So, in addition to recasting the code to use an AoA, I made other changes to improve legibility: moved things around a bit, applied proper indentation (which does matter), used the simpler form of loop control, removed some unnecessary code, and removed your original comments.

        Now, the only comments are the ones I put in, mostly (the "um..." ones) to mark things that make no sense or problems that need to be solved (but I don't know how you should solve them, because I don't know enough about your data or your real goals). This version compiles with no errors or warnings, but when you run it, there will certainly be a run-time error.

        #!/usr/bin/perl -w use strict; my $dinu_r; # um... nothing is ever assigned to this variable my @energyGrid; # this will be the AoA my $i; for my $x ( 1 .. 5 ) { open( AA, "shuffle$x" ) or die "Can't open shuffle$x ($!)\n"; # LI +NE A my $Sequence; $i=length($Sequence); # um... this is always zero while (<AA>) { $Sequence=$_; # um... $Sequence will only be the last line of + "shuffle$x" } close(AA); my %Winenergy = Energy( $Sequence, $dinu_r ); open (OUT, ">shuffle$x.stb"); # LINE B foreach my $el1 (sort{$a <=> $b} keys %Winenergy) { push( @{$energyGrid[$x]} , $Winenergy{$el1} ); #LINE C } close (OUT); } open(FILE,">total_shuffle.stb"); my $m=8; for my $j ( 0 .. $i ) # um... $i is still zero here { my $avg = 0; for my $x ( 1 .. 5 ) { $avg += $energyGrid[$x][$j]; } $avg /= 5; print FILE "$m\t$avg\n"; $m++; } close (FILE); sub Energy { my ($sequence,$dinu_r) = @_; my %dinu = %$dinu_r; # um... $dinu_r was never a hash ref # (and is undef), so this line will cause a run-time error my $win=15; my $limit1 = length( $sequence ) - $win + 1; my $wincenpos = 1 + ($win-1)/2; my %winenergy = (); for my $j ( 0 .. $limit1-1 ) { my $winseq = substr($sequence,$j,$win); my $energy = 0; for my $k ( 0 .. $win-2 ) { my $dinucle_temp = substr($winseq,$k,2); my $dinucle = uc($dinucle_temp); $energy = $energy + $dinu{$dinucle}; } my $wincentre = $j+$wincenpos; $winenergy{$wincentre} = $energy; } return %winenergy; }
Re: Changing name of ARRAY in each iteration
by Velaki (Chaplain) on Aug 10, 2006 at 13:14 UTC

    It looks like you're trying to dynamically create a new array name, e.g. @energyA, @energyB.

    You should probably make it a hash of array references.

    push @{$energy{$x}}, $Winenergy{$ell};

    This way, you'll have %energy, which would contain references to the arrays, for example, $energy{'A'} and $energy{'B'}, etc. Then you could simply dereference them, e.g. @{$energy{'A'}}), to access the elements.

    Hope this helped,
    -v.

    "Perl. There is no substitute."
Re: Changing name of ARRAY in each iteration
by davido (Cardinal) on Aug 10, 2006 at 16:28 UTC

    The point everyone's trying to make to you is that you really don't want to do what you're asking how to do. It's the wrong strategy to solve your problem. You have not come up with a new "good reason" to use symbolic references. The fact is that there is a better way. I know it may be hard to believe. You're asking yourself, "Why don't they just tell me how to do it?" The fact is it's pretty easy to do what you're asking. But think of it this way: If you hang by your fingertips from a wire suspended between two skyscrapers, it's pretty easy to work your way out there onto the wire, but it's also pretty easy to lose your grip and plunge to your death. Do you really want to hang by your fingertips hundreds of feet above the hard pavement? ...I didn't think so.

    Now, what you do want is real references. You can read about them in perlreftut (a tutorial on using references), perlref (full documentation on references), perldsc (Perl datastructure cookbook), and perllol (Perl lists of lists reference).

    The good news is that real references will solve your problem a slightly different way, and will solve the problem while you're feet are still firmly planted on the ground, instead of dangling a thousand feet up from a high wire.


    Dave

      hey its indeed a something great what you are suggesting, but trust me!! I need to read your reply and the links as well at least thrise to estimate mine capabilty to solve the perticular problem. thats what life is :-) will try and come back to you. Meanwhile thank you man for your suggestions and time you have taken out for me.
Re: Changing name of ARRAY in each iteration
by liverpole (Monsignor) on Aug 10, 2006 at 17:57 UTC
    Hi again, cool,

    You still have uninitialized variables (eg. "dinu_r").  Besides that, I don't know what your input file looks like.

    But perhaps this will help to give you an idea about what the other monks are strongly suggesting; namely, that you use a better data structure (eg. a hash of arrays) instead of symbolic references:

    # Near the top of the code my %energy; # Later on ... foreach my $el1(sort{$a <=> $b} keys %Winenergy) { # push(@energy.$x , $Winenergy{$el1}); #LINE C # print OUT "$el1\t $Winenergy{$el1}\n"; $energy{"energy$x"} ||= [ ]; # Initialize a +rray ref push @{$energy{"energy$x"}}, $Winenergy{$el1}; # Save to appr +opriate array }

    Does that help you to get started?


    s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/
Re: Changing name of ARRAY in each iteration
by planetscape (Chancellor) on Aug 10, 2006 at 20:06 UTC

    Perhaps you should tell us why you think it necessary to dynamically alter the name of your array... As it stands, this sounds a lot like an XY Problem...

    planetscape

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://566603]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (7)
As of 2020-02-19 02:02 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    What numbers are you going to focus on primarily in 2020?










    Results (80 votes). Check out past polls.

    Notices?