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

Hello everyone! I just started using perl in school and we have to create an alignement table for sequences. I made the whole structure and I understand what I have to do, put i don't exacty know how to print it
#!/usr/bin/perl + + use strict; use warnings; my $S=" MSATPLTQEQKKA"; my $T=" MNATLTQQTKA"; my $n=length($S); my $m=length($T); my @seq1=split("",$S); my @seq2=split("",$T); print"\n\t "; print"@seq1\n"; print"\t "; for (my$j=0;$j<$n;$j=$j+1){ print" $j"; } print"\n\t 0"; print"\n\t"; $initialvalue=0; if($seq1[$i]==$seq2[$j]){ $match=0 if (($seq1[$i-1],$seq2[$j])>($seq1[$i],$seq2[$j-1])||($seq1[$i-1],$se +q2[$j-1]) $add=1 print"$initialvalue+$match+$add\n" } else($seq1[$i]!=$seq2[$j]{ $initialvalue= $initialvalue+1 if (($seq1[$i-1],$seq2[$j])>($seq1[$i],$seq2[$j-1])||($seq1[$i-1],$ +seq2[$j-1]) $add=1 print"$match+$add+$initialvalue\n" } print"\n"; for (my$k=0;$k<$m;$k=$k+1){ print"$seq2[$k] $k\n"; }
The thing is that each element must be an addition to the minimum between the upper element, the diagonal one and the one on the left, Thank you and I'm sorry for my bad English!!

Replies are listed 'Best First'.
Re: Perl Array
by kcott (Archbishop) on Oct 11, 2015 at 03:49 UTC

    G'day baconyluv5,

    Welcome to the Monastery.

    Firstly, I can see without even running it, that the code you've posted won't compile! So you'll need to deal with whatever messages Perl gives you and fix the problems.

    While you're learning, you'll find the diagnostics pragma will provide a lot more information for warning and error messages. It's a developer tool: don't leave it in your production code (that includes the code you hand in for marking/assessment/whatever).

    The first problem that stood out was that you've used $i without declaring it. I thought that was maybe a typo and you'd meant $j; however, you've used both of those variables in more than one line, so my initial guess wasn't right.

    Another problem occurs in various comparisons. Perl uses different operators for numeric and string comparisons. You've used numeric comparison operators throughout: I'm pretty sure those (or, at least, a fair number of them) should be string comparisons. perlop documents all the operators. For this specific issue, you'll want the Equality Operators and Relational Operators sections.

    I also see code like this in two places:

    for (my$j=0;$j<$n;$j=$j+1)

    That looks more like C than Perl. Try writing those lines more like:

    for my $j (0 .. $n - 1)

    The .. is a range operator. You may have already noticed it if you followed the perlop link I provided earlier. It's in the Range Operators section.

    There's other parts of your code that look like they probably need attention; although, what that might be may change after you deal with the issues I've already pointed out. In fact, they may become apparent to you as you apply fixes: a good learning exercise. You can always ask later if you find yourself stumped.

    I'd recommend you take a step back and read through "perlintro -- a brief introduction and overview of Perl". It's not that long: you'd do well to read it all but do at least read down to, and including, the Builtin operators and functions section.

    "... and I'm sorry for my bad English!"

    Actually, I wish more native English speakers made as few mistakes and you've done here. "alignement" (which should be: alignment) was the only spelling mistakes I noticed. Perl (capitalised) is the name of the language; perl (all lowercase) is the filename of the program (as you have in your shebang line: /usr/bin/perl).

    There are however two things you omitted. You should show the error and warning messages and also tell us about the expected output. Take a look at "How do I post a question effectively?" - it explains these things in more detail.

    Finally, you talked about "an alignement table for sequences" [sic]. That's something that's technical and not directly related to Perl. Many monks, who could answer the coding part of your question, may read no further than your first sentence because they don't know what that is. Either describe it in a few short sentences or provide a link that will help us understand the concept sufficiently to help with your question.

    — Ken

Re: Perl Array
by Anonymous Monk on Oct 11, 2015 at 02:33 UTC

    Is this what you are looking for?

    #!/usr/bin/perl # http://perlmonks.org/?node_id=1144405 use Algorithm::Diff qw(traverse_sequences); use strict; use warnings; my $S=" MSATPLTQEQKKA"; my $T=" MNATLTQQTKA"; my @from = split //, shift // $S; my @to = split //, shift // $T; my $top = ''; my $bottom = ''; traverse_sequences( \@from, \@to, { MATCH => sub {print $from[shift()]}, MATCH => sub {$top .= $from[shift()]; $bottom .= $to[pop()]}, DISCARD_A => sub {$top .= $from[shift()]; $bottom .= ' '}, DISCARD_B => sub {$top .= ' '; $bottom .= $to[pop()]}, } ); print "$top\n$bottom\n";

    This outputs:

    MS ATPLTQEQK KA M NAT LTQ Q TKA

    These two sequences are aligned by common character.

    Please show inputs and desired output when you ask for help.
    Giving several test cases is always a good idea.

      extra MATCH removed

      #!/usr/bin/perl # http://perlmonks.org/?node_id=1144405 use Algorithm::Diff qw(traverse_sequences); use strict; use warnings; my $S=" MSATPLTQEQKKA"; my $T=" MNATLTQQTKA"; my @from = split //, shift // $S; my @to = split //, shift // $T; my $top = ''; my $bottom = ''; traverse_sequences( \@from, \@to, { MATCH => sub {$top .= $from[shift()]; $bottom .= $to[pop()]}, DISCARD_A => sub {$top .= $from[shift()]; $bottom .= ' '}, DISCARD_B => sub {$top .= ' '; $bottom .= $to[pop()]}, } ); print "$top\n$bottom\n";