Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Debugging help!

by invaderzard (Acolyte)
on Aug 31, 2012 at 13:47 UTC ( #991008=perlquestion: print w/ replies, xml ) Need Help??
invaderzard has asked for the wisdom of the Perl Monks concerning the following question:

Hi PerlMonks!

I'm not sure if this is a valid question to ask, but I can't debug a program and thus I require your help!

#!/usr/bin/perl use Modern::Perl; use File::Slurp qw/read_file write_file/; my $uniprot = 'D:\\ARP\\Downloads\\uniprot-sfinal.txt'; my $activin = 'D:\\ARP\\Downloads\\Activator-Pfam.txt'; my $antioxin = 'D:\\ARP\Downloads\\AntiOxidant-Pfam.txt'; my $toxinin= 'D:\\ARP\\Downloads\\Toxin-Pfam.txt'; my $activout = 'D:\\ARP\\Downloads\\ActivACNPF.txt'; my $antioxout= 'D:\\ARP\\Downloads\\AntioxACNPF.txt'; my $toxinout= 'D:\\ARP\\Downloads\\ToxinACNPF.txt'; my @activline; my @antioxline; my @toxinline; my %activ = map { /(.+)\s+\|\s+(PF.{5})/; $1 => $2 } read_file $activi +n; my %antiox = map{ /(.+)\s+\|\s+(PF.{5})/; $1 => $2 } read_file $antiox +in; my %toxin = map { /(.+)\s+\|\s+(PF.{5})/;$1=> $2} read_file $toxinin; for ( read_file $uniprot ) { /(.{6})\s+.+=([^\s]+)/; push @activline, "$1 $2 $activ{$1}\n" if $activ{$1}; push @antioxline, "$1 $2 $antiox{$1}\n" if $antiox{$1}; push @toxinline, "$1 $2 $antiox{$1}\n" if $antiox{$1}; } write_file $activout, @activline; write_file $antioxout, @antioxline; write_file $toxinout, @toxinline; print STDOUT "DONE\n";

This is a program I'm writing for my research project. Here's a few lines from each input file:

D:\\ARP\\Downloads\\uniprot-sfinal.txt

Q6GZX4 ORFNames=FV3-001R ;PF04947 Q6GZX3 ORFNames=FV3-002L ;PF03003 Q197F8 ORFNames=IIV3-002R Q197F7 ORFNames=IIV3-003L Q6GZX2 ORFNames=FV3-003R Q6GZX1 ORFNames=FV3-004R Q197F5 ORFNames=IIV3-005L

D:\\ARP\\Downloads\\Activator-Pfam.txt

Q6GZX4 | PF04947.9 Q96355 | PF01486.12 PF00319.13 Q96356 | PF01486.12 PF00319.13 Q39371 | PF01486.12 PF00319.13

D:\\ARP\Downloads\\AntiOxidant-Pfam.txt

D0EYG3 | PF10262.4 E7QVU5 | PF10417.4 PF00578.16 D1JAS4 | PF10417.4 PF00578.16

D:\\ARP\\Downloads\\Toxin-Pfam.txt

C7T183 | PF02950.12 C7T1P5 | PF02950.12 E2E4E4 | PF00918.12 A2PU44 | PF01375.12

The error codes I got were as shown

Use of uninitialized value in list assignment at ARP//positivedatasetextractor.pl line 18

Line 18: my %activ = map { /(.+)\s+\|\s+(PF.{5})/; $1 => $2 } read_file $activin;

Use of uninitialized value in list assignment at ARP//positivedatasetextractor.pl line 20

Line 20: my %toxin = map { /(.+)\s+\|\s+(PF.{5})/;$1=> $2} read_file $toxinin;

Use of uninitialized value $1 in hash element at ARP//positivedatasetextractor.pl Line 23

Line 23: push @activline, "$1 $2 $activ{$1}\n" if $activ{$1};

Use of uninitialized value $1 in hash element at ARP//positivedatasetextractor.pl Line 24

Line 24: push @antioxline, "$1 $2 $antiox{$1}\n" if $antiox{$1};

Use of uninitialized value $1 in hash element at ARP//positivedatasetextractor.pl Line 25

Line 25: push @toxinline, "$1 $2 $antiox{$1}\n" if $antiox{$1};

I know this is pretty long, but I have no idea how to debug this, so I'm posting this here for help. Thanks in advance!

Update: Thanks for your help, everyone! Well, I have further problems which use the same datasets, but is quite unrelated to this matter, so I'll be posting it on another new thread. Thanks again!

Comment on Debugging help!
Select or Download Code
Re: Debugging help!
by aitap (Deacon) on Aug 31, 2012 at 14:01 UTC

    Variables $1, $2, etc. are locally-scoped and they can be invalid after pattern matching. Try rewriting your matches like this:

    $1 => $2 if /(.+)\s+\|\s+(PF.{5})/
    so usage of these variables should be inside the if(){} block, not near the match.

    If you are not sure whether your regexps are right, use Regexp::Debugger or YAPE::Regex::Explain to check them.

    Sorry if my advice was wrong.
      So I've rewritten my code and it looks like this:
      #!/usr/bin/perl use Modern::Perl; use File::Slurp qw/read_file write_file/; my $uniprot = 'uniprot-sfinal.txt'; my $activin = 'Activator-PFAM.txt'; my $antioxin = 'AntiOxidant-PFAM.txt'; my $toxinin= 'Toxin-PFAM.txt'; my $activout = 'ActivACNPF.txt'; my $antioxout= 'AntioxACNPF.txt'; my $toxinout= 'ToxinACNPF.txt'; my @activline; my @antioxline; my @toxinline; my %activ = map { s/\.\d+//g; $1=>$2 if/(.+)\s+\|\s+(.+)/; } read_file + $activin; my %antiox = map { s/\.\d+//g; $1=>$2 if/(.+)\s+\|\s+(.+)/; } read_fil +e $antioxin; my %toxin = map { s/\.\d+//g; $1=>$2 if/(.+)\s+\|\s+(.+)/; } read_file + $toxinin; for ( read_file $uniprot ) { /(.{6})\s+.+=([^\s]+)/; push @activline, "$1 | $2 | $activ{$1}\n" if $activ{$1}; push @antioxline, "$1 | $2 | $antiox{$1}\n" if $antiox{$1}; push @toxinline, "$1 | $2 | $toxin{$1}\n" if $toxin{$1}; } write_file $activout, @activline; write_file $antioxout, @antioxline; write_file $toxinout, @toxinline;
      The error codes changed. Now they say this.
      Odd number of elements in hash assignment at ARP//positivedatasetextra +ctor.pl line 18. Odd number of elements in hash assignment at ARP//positivedatasetextra +ctor.pl line 20. Odd number of elements in hash assignment at ARP//positivedatasetextra +ctor.pl line 23. Odd number of elements in hash assignment at ARP//positivedatasetextra +ctor.pl line 24. Odd number of elements in hash assignment at ARP//positivedatasetextra +ctor.pl line 25.

      The lines with the errors are still the same.

        Do your files have empty lines which don't match your regexps? Try returning empty list (()) in case the regexp didn't match (map will omit the element in this case):
        $ perl -w -MData::Dumper -E'%h = map {if(/(.+)\s+\|\s+(.+)/){$1=>$2}el +se{()}} (<>); print Dumper \%h' Q6GZX4 | PF04947.9 Q96355 | PF01486.12 PF00319.13 Q96356 | PF01486.12 PF00319.13 Q39371 | PF01486.12 PF00319.13 DSFSDF ASD SSSSSSSSSS ^D $VAR1 = { 'Q96355' => 'PF01486.12 PF00319.13', 'Q96356' => 'PF01486.12 PF00319.13', 'Q6GZX4' => 'PF04947.9', 'Q39371' => 'PF01486.12 PF00319.13' };
        Edit: return an empty list
        Sorry if my advice was wrong.
        { s/\.\d+//g; $1=>$2 if/(.+)\s+\|\s+(.+)/; }
        This will supply 2 elements to properly populate the hash if the match succeeds.

        However, on match failure, the return value is undef() (I think), but the important thing is that a single (ODD NUMBER) value is returned, so the hash is not happy.

        Update:
        I would correct it as :

        { s/\.\d+//g; /(.+)\s+\|\s+(.+)/ ? ($1=>$2) : () }

                     I hope life isn't a big joke, because I don't get it.
                           -SNL

Re: Debugging help!
by Marshall (Prior) on Sep 01, 2012 at 12:19 UTC
    The code lost me at bit...
    I would try to avoid this $1, $2 stuff..
    Use match global or split and list assignment..
    Anyway here are some hints on how to post runnable code - you will get better answers, the easier the code is to run and the more clear you explain why it is not producing the right result.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (12)
As of 2014-07-25 19:23 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (174 votes), past polls