Thank you so much @thackl
Hi all,
I'm having sequences stored in two arrays @seq1 and @seq2 and I have to compare sequence @seq2 with all the indexes in the @seq1 and print the mismatched bases in each position.
These are my sequences:
@seq1 = "UAUGUACCGACCUUAUUCUCCU AUGUACCGACCUUAUUCUCCUG UGUACCGACCUUAUUCUCCUGU GUACCGACCUUAUUCUCCUGUG UACCGACCUUAUUCUCCUGUGA ACCGACCUUAUUCUCCUGUGAU CCGACCUUAUUCUCCUGUGAUC CGACCUUAUUCUCCUGUGAUCU GACCUUAUUCUCCUGUGAUCUA ACCUUAUUCUCCUGUGAUCUAC CCUUAUUCUCCUGUGAUCUACU CUUAUUCUCCUGUGAUCUACUA UUAUUCUCCUGUGAUCUACUAU UAUUCUCCUGUGAUCUACUAUA "
@seq2 = " UGGAGUGUGACAAUGGUGUUUG"
and this is my code:
foreach (0..length(@seq1))
{
my $char = substr($seq2,$_,1);
if($char ne substr($seq1, @_,1))
{
$result .="$char";
}
else
{
$result .="";
}
}
print $result, "\n";
I'm getting errors. I would be grateful if anyone help me to complete this and to rectify my error. Thank you
2 answers
I'm fully aware that the code below does not quality as an appropriate teaching example - I'm simply a fan of a little bit of bit magic when it comes to string comparison.
#!/usr/bin/env perl
use warnings;
use strict;
my $q = "UGGAGUGUGACAAUGGUGUUUG";
my @r = qw(
UAUGUACCGACCUUAUUCUCCU
AUGUACCGACCUUAUUCUCCUG
UGUACCGACCUUAUUCUCCUGU
);
foreach my $r (@r) {
my $xb = $r ^ $q; # compare
$xb =~ tr/\0\377/\0\377/c; # bitmask with mm=1, m=0
my $xs = $r & $xb; # mismatches
$xs =~ tr/\0/ /; # add gaps
print "ref: ", $r,"\n";
print "qry: ", $q,"\n";
print "mis: ", $xs,"\n\n";
}
produces:
ref: UAUGUACCGACCUUAUUCUCCU
qry: UGGAGUGUGACAAUGGUGUUUG
mis: AUGUACC CU AU C CCU
ref: AUGUACCGACCUUAUUCUCCUG
qry: UGGAGUGUGACAAUGGUGUUUG
mis: AU UACCGAC UUAUUCUCC
ref: UGUACCGACCUUAUUCUCCUGU
qry: UGGAGUGUGACAAUGGUGUUUG
mis: U CC ACCUU UC CC GU
[EDIT] Not a working solution - see comments above [/EDIT]
The following code snippet runs and gives you the desired result even though your approach is highly inefficient.
However, as @thackl mentioned, you made some horrible severe mistakes in your code! I do not want to be rude, but: read an introduction to Perl and learn some basics in programming before you proceed! Without that, your code will continue to be messy, fail, and you will waste time - yours and ours. Sorry.
#!/usr/bin/perl
use strict;
use warnings;
# Split the string sequence into an array
my @seq1 = split('', "UAUGUACCGACCUUAUUCUCCUAUGUACCGACCUUAUUCUCCUGUGU...");
my @seq2 = split('', "UGGAGUGUGACAAUGGUGUUUG");
# Determine the length of the shorter sequence
my $length;
if( scalar(@seq1) < scalar(@seq2) ){
$length = scalar(@seq1);
}
else {
$length = scalar(@seq2);
}
# Iterate the arrays and store results
my $result = '';
foreach (0 .. ($length - 1)){
if($seq1[$_] ne $seq2[$_]){
$result .= $seq2[$_];
}
else {
$result .= " ";
}
}
print $result, "\n";
Although I support your advice on reading Perl intros, I wouldn't call the above mistakes "horrible". To me this looks like a classic "hands-on" Perl learning attempt. However, given the technical nature of the posted question and the fact that sequences in question need not to be RNA/DNA/AA for the algorithm to be applied, I believe that the OP should try to post the question on a more suited forum like PerlMonks, where I believe she/he will get a more of an "educative" advice on how to tackle the problem and what would be a more efficient solution, especially since the OP has shown the attempt to resolve it.
mxs
Probably, "horrible" was too rude then - I changed it. But I hold up the demand for learning PERL basics. Coming from a computer science background, I think it is crucial to understand the very basics of the programming language in use, e.g., not to mix strings with arrays (at least in PERL), check for array lengths, etc.
+1 for asking for help in the PERL programming community (e.g. PerlMonks) - even though I think they will be even more picky about the coding style ;-)
@landesfeind Thank you for your reply. I'm new to perl and I'm on the process of learning so I have just tried using codes already given in some other websites for my problem but it didn't work.. that's why I posted my query here. This is also a process of learning. Learning from experienced person will help us more than books. And your script gives solution for the first index alone (i.e., first 22characters) I need to compare @seq2 from position 1 to n in @seq1 (i.e., from 1 to 22 then from 2 to 23 then from 3 to 24 and so on..) 1, 2 3... are characters in @seq1. Thank you.
I would recommend Modern Perl, O'Reilly's Learning Perl, or Beginning Perl by Curtis Poe for learning Perl. It is better to get a good introduction from a solid book than try to learn from a 15 year old web article, which is likely to lead to more frustration and problems (it teaches the wrong way to do things right from the beginning).
Log in to answer this question.
Why is there a
@_inif($char ne substr($seq1, @_,1)).And also, storing a single sequence string in an array (@seq1) does not make sense. Your code has a couple of problemsIt's not clear, but it's actually a white space quoted list
Yeah, I figured as much, but it took me some time ;). This also means that @landesfeind's solutions won't work...
Sorry, I didn't got that, in particular because there is also a white space when initializing
@seq2and because both@seq1and@seq2are later accessed using$andsubstr(). I assumed the white spaces to be mistakes or formatting errors.As I was bitching around, I would gladly adjust my code in the answer to match the desired output - if one can specify how it should look like. Probably more like the following?
which prints
thanks a lot @landesfeind