http://www.perlmonks.org?node_id=1014935

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

There seem to be no compilation errors, but once the filename is input, the screen just... does nothing. I have to restart the terminal to get anything done. What am I doing wrong? I'm writing a program to compare an input string against a list, and calculating occurrence and frequency of that particular element. I have the code, it's a little messy, and I would appreciate ALL the help you have. Also, why is , 'S' showing up as a highlighted + sign? Updated the while loop but the values don't seem to be incrementing, the output shows 0, 0, 0 and 1, 2 for the first column instead of showing A, C, D..

#!/usr/bin/perl-w use warnings; use diagnostics; print "Enter the file containing the amino acid sequence \n"; my $filename = <STDIN>; chomp $filename; unless (open(FILENAME, $filename)) { print "File $filename not found. Exiting program \n"; exit; } my @AASeq=<FILENAME>; my $length = @AASeq; close FILENAME; my @AAMatrix = ('A','C','D','E','F','G','H','I','K','L','M','N','P','Q +','R','S','T','V','W','Y'); my @AAOcc = (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); my @AAFreq = (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); my $i=0; my $counter=0; #Counter for the initialized matrix while ($counter<=$length) { for ($i=0; $i<=19; $i++) { if( $AASeq[$counter]=~ $AAMatrix[$i]) { ++$AAOcc[$counter]; next; } } ++$counter; } #Calculating frequency of amino acid occurrence my $x=0; for ($x=0; $x<=19; $x++) { $AAFreq[$x] = $AAOcc[$x]/$length; } #Printing out the final array print "AMINO ACID \t OCCURRENCE \t FREQUENCY "; my $y=0; for ($y=0; $y<=19; $y++) { print "$AAMAtrix [$y] \t\t $AAOcc[$y] \t\t $AAFreq[$y] \t\t\n"; }

Replies are listed 'Best First'.
Re: Code won't proceed after input.
by toolic (Bishop) on Jan 23, 2013 at 15:51 UTC
    Your while loop is an infinite loop because you never increment the $counter variable inside the loop.

    See also Basic debugging checklist

    UPDATE:

    I would appreciate ALL the help you have.
    You can use qw to cut down on some typing:
    my @AAMatrix = qw( A C D E F G H I K L M N P Q R S T V W Y );

    You can use map and Range Operators to cut down on some more typing:

    my @AAOcc = map { 0 } 1 .. 20;

        Or better yet IMHO:

        >perl -wMstrict -le "my @AAMatrix = qw( A C D E F G H I K L M N P Q R S T V W Y ); ;; my @AAOcc = (0) x @AAMatrix; print qq{@AAOcc}; " 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Re: Code won't proceed after input.
by choroba (Cardinal) on Jan 23, 2013 at 16:15 UTC
    The main problem of your code has been solved. However, there are lots of other things that can be improved:
    • Use the 3 argument version of open with lexical filehandles. Also, the open or die idiom is much more readable and common than your unless structure.
    • Do not use the same name for various types of things (scalar and array variable in this case).
    • If you can process the file line by line, do not slurp it all into memory.
    • Use hashes to count numbers of occurrences.
    Here is how I would approach your problem:
    #!/usr/bin/perl use strict; use warnings; print "Enter the file containing the sequence: "; my $filename = <STDIN>; chomp $filename; open my $FH, '<', $filename or die "Cannot open $filename: $!"; my @chars = qw(A C D E F G H I K L M N P Q R S T V W Y); my $length; my $char_regex = join q(), @chars; $char_regex = qr/[$char_regex]/; my %occ; while (my $line = <$FH>) { for my $char (split //, $line) { next unless $char =~ $char_regex; $length++; $occ{$char}++; } } print "AMINO ACID \t OCCURRENCE \t FREQUENCY\n"; for my $char (@chars) { $occ{$char} //= 0; print "$char \t\t $occ{$char} \t\t ", $occ{$char} / $length, "\n" +; }
    BTW, the plus sign at 'S' just means your line is too long and has been wrapped. You can adjust your line length in your settings.
    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

      THanks, but I have a couple of questions : what does q() and qr// do?

Re: Code won't proceed after input.
by RichardK (Parson) on Jan 23, 2013 at 16:24 UTC

    Isn't this the wrong index ? ++$AAOcc[$counter]; should it be  ++$AAOcc[$i]?

Re: Code won't proceed after input.
by Anonymous Monk on Jan 23, 2013 at 21:30 UTC
    Line 19's @AAMatrix is not the same array as referenced in line 57's $AAMAtrix$y. Case matters. And "$AAMAtrix$y" is not the same as ""$AAMAtrix $y".