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
| [reply] |
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$..$/
| [reply] [d/l] [select] |
|
|
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);
| [reply] [d/l] |
|
|
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
| [reply] |
|
|
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;
}
| [reply] [d/l] |
|
|
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."
| [reply] [d/l] [select] |
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.
| [reply] |
|
|
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.
| [reply] |
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$..$/
| [reply] [d/l] |
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...
| [reply] |