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

Hi, Monks. I'm very new to Perl and programing. But I'm stuck right now. First, the code:
#!/usr/bin/perl use warnings; no warnings 'uninitialized'; #Calculating Protein Mass ($input) = $ARGV[0]; open ($in, "<", $input) || die "Can't open \"$input\".\nError = $!.\n" +; $protein = <$in>; my(%mass_values) = ( 'A' => 71.03711, 'C' => 103.00919, 'D' => 115.02694, 'E' => 129.04259, 'F' => 147.06841, 'G' => 57.02146, 'H' => 137.05891, 'I' => 113.08406, 'K' => 128.09496, 'L' => 113.08406, 'M' => 131.04049, 'N' => 114.04293, 'P' => 97.05276, 'Q' => 128.05858, 'R' => 156.10111, 'S' => 87.03203, 'T' => 101.04768, 'V' => 99.06841, 'W' => 186.07931, 'Y' => 163.06333, ); my $mass = ""; for(my $i=0;$i<length($protein);$i+=1) { $codon = substr($protein,$i,1); $mass .= "$mass_values{$codon}\n"; } print $mass; ($result) = $ARGV[1]; open ($out, ">", $result) || die "Can't write to \"$result\".\nError = + $!.\n"; print $out "$mass"; close "$out"; exit;

This program is for this problem: http://rosalind.info/problems/prtm/

In order to run it, you need a protein string file, but you need to be registered to get one from rosalind, but here is the data string I'm using: https://justpaste.it/1cfuo

Now, this program I've written is just a modification of some codes I found here and there (And I kinda understand how it works). There is probably better ways of doing it, so just say if you see a quicker and easier solution!

Anyway, I'm stuck at the part were I have to sum up all the numbers. Right now, if I run it, I will just get a long list of numbers like this:

103.00919

131.04049

113.08406

57.02146

186.07931

128.09496

156.10111

97.05276

etc.

But I've no idea how to sum it all up. I've tried to make it into an array, but then I get errors saying "this is not a number", because I think perl thinks all of the different numbers is one element, and not 1000 different elements...

Anyway, I did complete the problem by "writing"(stole and modified) a separate program to sums it all up:

#!/usr/bin/perl use strict; use warnings; # given a file with a number on each row, print the sum of the numbers my $sum = 0; my $filename = "result.txt"; open(my $fh, "<", $filename) or die "Could not open '$filename'\n"; while (my $line = <$fh>) { $sum += $line; } print "The total value is $sum\n";

(I did try to put the above code into the first program, so that the program writes to the results file, then opens the results file, and then does the addition. But for some reason, I get the wrong answer doing it this way, like it skips adding some numbers for some reason...

But I feel that this is something that can be done easily with just one perl program. But it was just my way of bodging it.

Anyway, hope someone can correct me and explain my mistakes!

Replies are listed 'Best First'.
Re: Adding values in a variable
by Laurent_R (Canon) on Oct 15, 2017 at 20:37 UTC
    Hi bisimen,

    your error is in this line:

    $mass .= "$mass_values{$codon}\n";
    This line concatenates all the masses (interleaved with a new line), whereas you want to sum them up. So, in the end, you get a large string with all the masses, each on its own line. Just replace concatenation with addition:
    $mass += $mass_values{$codon};
    and your first program should do what you want, without the need for the second one.

    There are other improvements that could be made: use strict, don't use no warnings 'uninitialized'; just to silence the warnings, but try to remove the warnings by understanding where they come from (possibly a new line character at the end of your string in the file), chomp the line you read from the input file, use split to get the individual letters of the protein string (see choroba's example above).

      Thanks! This was helpful. And yes, using chomp on the protein string did remove the warning.
Re: Adding values in a variable
by choroba (Cardinal) on Oct 15, 2017 at 19:11 UTC
    You can iterate directly over the characters of the protein by splitting it:
    my $protein = <>; my $sum; $sum += $mass{$_} for split //, $protein; print $sum;

    Good luck with Rosalind, I liked it a lot!

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
      Good luck with Rosalind, I liked it a lot!
      I'm just afraid the effort is to waste when you just slashdot your way trough it without a real understanding. But then, then OP is probably being humble? That, or having a real talent to steal, as I can't see red flags except for no strict.


      holli

      You can lead your users to water, but alas, you cannot drown them.
Re: Adding values in a variable
by bisimen (Acolyte) on Oct 15, 2017 at 18:55 UTC
    I managed to solve it
    #!/usr/bin/perl use warnings; no warnings 'uninitialized'; #Calculating Protein Mass ($input) = $ARGV[0]; open ($in, "<", $input) || die "Can't open \"$input\".\nError = $!.\n" +; $protein = <$in>; my(%mass_values) = ( 'A' => '71.03711 ', 'C' => '103.00919 ', 'D' => '115.02694 ', 'E' => '129.04259 ', 'F' => '147.06841 ', 'G' => '57.02146 ', 'H' => '137.05891 ', 'I' => '113.08406 ', 'K' => '128.09496 ', 'L' => '113.08406 ', 'M' => '131.04049 ', 'N' => '114.04293 ', 'P' => '97.05276 ', 'Q' => '128.05858 ', 'R' => '156.10111 ', 'S' => '87.03203 ', 'T' => '101.04768 ', 'V' => '99.06841 ', 'W' => '186.07931 ', 'Y' => '163.06333 ', ); for(my $i=0;$i<length($protein);$i+=1) { $codon = substr($protein,$i,1); $mass = $mass_values{$codon}; $sum += $mass; } print $sum; ($result) = $ARGV[1]; open ($out, ">", $result) || die "Can't write to \"$result\".\nError = + $!.\n"; print $out "$sum"; close "$out"; exit;
    Just changed things some things, then it worked. Don't really know why. Still appreciate input / alternative methods