Debug this little perl program
From BITS wiki
Go back to Perl introductionary training#Exercises
Debug following program
This is a small program in which errors are introduced. In real life, you often reuse code you have written, or even use code of colleagues. These may contain errors: reading the error codes and learning to look for the obvious errors first might benefit you to a great extent.
#!/usr/bin/perl -w $|=1; use strict; ################################################ # This program uses a sliding window # to search local spots in an aminoacid sequence # with large amounts of a specific amino acid. # # Can you correct the mistakes in this program? # Some should be obvious by just looking at the # syntax highlighting. For others, use the # warnings upon executing. In the end, you might # check if the program does what it needs to do. # # joachim.jacob@vib.be ################################################ my $seq="MPYNFCLPSLSCRTSCSSRPCVPPSCHSCTLPGACNIPANVSNCNWFCEGSFNGSEKETM QFLNDRLASYLEKVRQLERDNAELENLIRERSQQQEPLLCPSYQSYFKTIEELQQKILCT KSENARLVVQIDNAKLAADDFRTKYQTELSLRQLVESDINGLRRILDELTLCKSDLEAQV ESLKEELLCLKSNHEQEVNTLRCQLGDRNVEVDAAPTVDLNRVLNETRSQYEALVETNRLL LLLLEVEQWFTTQTEELNKQVVSSSEQLQSYQAEIIELRRTVNALEIELQAQHNLRDSLENTL TESEARYSSQLSQVQSLITNVESQLAEIRSDLERQNQEYQVLLDVRARLECEINTYRSLL ESEDCNLPSNPCATTNACSKPIGPCLSNPCTSCVPPAPCTPCAPRPRCGPCNSFVR "; my $windowlength=20; # length sliding window (must be shorter than sequencelength) my $AAoi="L"; # Aminoacid of interest my $AAamount=0.38 # report cutoff of percentage within window (percentage) my (%number,$window); my $seqlen = length($seq); for( my $mover=0;$mover<=($seqlen-$windowlength);$mover++){ # let window slide over sequence #print "\nOk\tMover=$mover\n"; $window=substr($seq,$mover,$windowlength); # getting sequence under window #print "\nSequence under window: $window\n"; %number=(); # reset hash my $count=$window=~tr/$AAoi/$AAoi/g; #print "Test counter: $count in $window\n"; my $content=$count/$windowlength; #print "\n$AAoi content= $content\n"; if ( $content > $AAamount){ print "Found $window with $AAoi-content of $content at position $mover.\n; } } print "\nProgram finished succesfully!\n"; exit 0;
One solution
One solution |
---|
Before looking at the code, let's run it as it is. We will take a look at the error messages that will appear. Copy/paste the code into a file and run it with perl. |
"Bareword found where operator expected at test.pl line 91, near "tr/$AAoi/$AAoi/g"". Let's take a look at this one. In paragraph 16 of your Perl Quick Reference Guide you see that tr/ only accepts 'c','d' or 's' as modifiers at the end, not a 'g'. Hence, Perl does not recognise 'g', and calls it a bareword. So one thing to do for sure, is to remove the 'g'. Next, the SEARCHLIST and REPLACEMENTLIST of tr/ has a scalar ($AAoi) in it: unfortunately, tr/ does not allow scalars in the LISTS (would be powerful though). So, we have to replace the construction with "my $count=$window=~tr/L/L/;". Important, to avoid confusion, we will remove the line: my $AAoi="L"; # Aminoacid of interest also. Check for more occurrence of $AAoi and replace them with 'L'. |
When we run now: "Backslash found where operator expected at test.pl line 113, near "print "\" (Might be a runaway multi-line "" string starting on line 105) (Do you need to predeclare print?)". This is an error which we could have noticed by looking at the code. The last printed line in the for loop does not ends with a ". All text below that line is colored as text, while being functions. So we add an appropriate " on line 105, as nicely suggested by Perl: ..." at position $mover.\n"; The next error is related to the first, so this will disappear by solving the first. |
Next error: "syntax error at test.pl line 69, near "my ". This is a little trickier. When we look at that line, nothing seems wrong. In fact, nothing IS wrong on that line. When you encounter something like that, always have a look at the previous line of code. Aha! You see? Most common beginner's mistake: forgot the ";" at the end of the line. |
When we run the program now, we see appearing "Program finished succesfully!". Seems odd, because we have no output? This is an important lesson: before using a program, always test it on data that you know, and check that the output displays what you expect. The sequence provided in the program contains some L residues. Let's print the sequence first to the output window. Add print $seq,"\n";. You see what he displays? A sequence with gaps! Let's remove all white spaces first. You could do this with $seq =~ s/\W+//g;. |
Nice! Now let's play with the parameters to check the behaviour of the program. For example, let's change scalar $$AAamount to 0.30.
#!/usr/bin/perl -w $|=1; use strict; ################################################ # This program uses a sliding window # to search local spots in an aminoacid sequence # with large amounts of a specific amino acid. # # Can you correct the mistakes in this program? # Some should be obvious by just looking at the # syntax highlighting. For others, use the # warnings upon executing. In the end, you might # check if the program does what it needs to do. # # joachim.jacob@vib.be ################################################ my $seq="MPYNFCLPSLSCRTSCSSRPCVPPSCHSCTLPGACNIPANVSNCNWFCEGSFNGSEKETM QFLNDRLASYLEKVRQLERDNAELENLIRERSQQQEPLLCPSYQSYFKTIEELQQKILCT KSENARLVVQIDNAKLAADDFRTKYQTELSLRQLVESDINGLRRILDELTLCKSDLEAQV ESLKEELLCLKSNHEQEVNTLRCQLGDRNVEVDAAPTVDLNRVLNETRSQYEALVETNRLL LLLLEVEQWFTTQTEELNKQVVSSSEQLQSYQAEIIELRRTVNALEIELQAQHNLRDSLENTL TESEARYSSQLSQVQSLITNVESQLAEIRSDLERQNQEYQVLLDVRARLECEINTYRSLL ESEDCNLPSNPCATTNACSKPIGPCLSNPCTSCVPPAPCTPCAPRPRCGPCNSFVR "; $seq =~ s/\W+//g; print $seq,"\n"; my $windowlength=20; # length sliding window (must be shorter than sequencelength) my $AAamount=0.30; # report cutoff of percentage within window (percentage) my (%number,$window); my $seqlen = length($seq); for( my $mover=0;$mover<=($seqlen-$windowlength);$mover++){ # let window slide over sequence #print "\nOk\tMover=$mover\n"; $window=substr($seq,$mover,$windowlength); # getting sequence under window #print "\nSequence under window: $window\n"; %number=(); # reset hash my $count=$window=~tr/L/L/; #print "Test counter: $count in $window\n"; my $content=$count/$windowlength; #print "\n$AAoi content= $content\n"; if ( $content > $AAamount){ print "Found $window with L-content of $content at position $mover.\n"; } } print "\nProgram finished succesfully!\n"; exit 0; |