您好我正在为我的Bioinformatics类编写这个程序,在那里我从文本文件中获取序列,然后改变序列。之后,我想通过比较碱基对进行比较以得分。我编写了所有代码,但我不明白为什么我一直得到0的分数。我假设我的代码部分处理这个是错误的,因为我初始化了$sum = 0;
我想知道是否我可以帮助解决这个问题,以便我的代码正常工作。这是我正在使用的序列。
AGGGCACCTCTCAGTTCTCATTCTAACACCACATAATTTTTATTTGTATTATTCAGATTTTTCATGAACTTTTCCACAT
AGAATGAAGTTGACATTGTTATTTCTCAGGGTCTCGGTTCACCAGTATTTGACAAACTTGAAGCTGAACTAGCTAAAGC
use strict;
my $sum = 0;
my @seq;
my $seqString;
my $seqShuf;
my $line;
unless(open FILE, "test_seq.txt")
{
print "Cannot open file!";
exit;
}
while (chomp($line = <FILE>))
{
next if (/^>/);
@seq = <FILE>;
}
$seqString = join("",@seq);
chomp($seqShuf = shuffle_string($seqString));
$seqShuf =~ s/\s+//g;
#print "Original sequence is:\n";
#print "$seqString\n";
#print "Mutated Sequence is:\n";
#print "$seqShuf\n";
my @shufSeq = split("", $seqShuf, length($seqShuf));
my %test = (
AA => 0,
AG => -1,
AT => -2,
AC => -2,
GA => -1,
GG => 0,
GT => -2,
GC => -2,
TA => -2,
TG => -2,
TT => 0,
TC => -1,
CA => -2,
CG => -2,
CT => -1,
CC => 0
);
my @base_pairs = make_base_pairs(@seq, @shufSeq);
foreach my $bp (@base_pairs)
{
$sum += $test{$bp};
}
print "@base_pairs\n";
print "The score is ", $sum, "\n";
# Shuffles original sequence
sub shuffle_string
{
my ($string) = @_;
my $length = length $string;
for (my $i = 0; $i < $length-1; $i++)
{
my $j = random_int ($i, $length-1);
my $tmp = substr($string, $i, 1);
substr($string, $i, 1) = substr($string, $j, 1);
substr($string, $j, 1) = $tmp;
}
return $string;
}
# created random int between two parameters
sub random_int
{
(my $par1, my $par2) = @_;
my $num = (1+$par1) + int(rand($par2 - $par1));
}
# aligns base pairs based on index location
sub make_base_pairs
{
(my @orig, my @shuf) = @_;
my $idx = 0;
my @bps;
foreach my $base (@orig)
{
push @bps, $base , $shuf[$idx];
$idx++;
}
return @bps;
}
答案 0 :(得分:2)
不幸的是,简单的perl错误的数量,更不用说一些算法错误,无法列出。只需研究并比较下面的代码。
这是清理过的代码。它可能仍然有一些错误,但至少它打印非零[请原谅无偿的风格清理]:
#!/usr/bin/perl
use strict;
my $sum = 0;
my @seq;
my $seqString;
my $seqShuf;
my $line;
open(FILE, "test_seq.txt") or
die("unable to open file -- $!\n");
while ($line = <FILE>) {
chomp($line);
push(@seq,split(//,$line));
}
close(FILE);
my @shufSeq = shuffle_string(@seq);
#print "Original sequence is:\n";
#print "$seqString\n";
#print "Mutated Sequence is:\n";
#print "$seqShuf\n";
my %test = (
AA => 0,
AG => -1,
AT => -2,
AC => -2,
GA => -1,
GG => 0,
GT => -2,
GC => -2,
TA => -2,
TG => -2,
TT => 0,
TC => -1,
CA => -2,
CG => -2,
CT => -1,
CC => 0
);
my @base_pairs = make_base_pairs(\@seq, \@shufSeq);
foreach my $bp (@base_pairs)
{
###printf("DEBUG bp='%s'\n",$bp);
$sum += $test{$bp};
}
print("base_pairs: ",join(" ",@base_pairs),"\n");
print "The score is ", $sum, "\n";
# Shuffles original sequence
sub shuffle_string
{
my (@string) = @_;
my $length = @string;
for (my $i = 0; $i < $length-1; $i++) {
my $j = random_int ($i, $length-1);
my $tmp = $string[$i];
$string[$i] = $string[$j];
$string[$j] = $tmp;
}
@string;
}
# created random int between two parameters
sub random_int
{
my($par1,$par2) = @_;
my $num = (1+$par1) + int(rand($par2 - $par1));
$num;
}
# aligns base pairs based on index location
sub make_base_pairs
{
my($orig,$shuf) = @_;
my $idx = 0;
my @bps;
foreach my $base (@$orig) {
push(@bps,$base . $shuf->[$idx]);
$idx++;
}
return @bps;
}
<强>更新强>
非常感谢你们。这是我的第一个编程课程,它在整个学期里一直在杀我。我将继续查看代码和编辑,以摆脱一些额外的错误。
以下是一些其他注释,可能有助于理解我所做的更改的机制。
现在该程序基本上正常工作,您可以检查您的随机化和随机码是否在算法上足够(即足够随机和随机播放)。
例如,我认为shuffle的最后一个元素总是是原始元素的最后一个元素,因为i
循环是< $length-1
而不是{{1 }}。我试图通过再循环一次来解决这个问题,但是在阵列上遇到了一个越界。
文件I / O:
读取文件数据和拆分单个字符的代码非常惯用。
在您的代码中,< $length
只会为您提供一个包含最后一行文本的数组[因为第一行是由@seq = <FILE>
提取的。)
循环$line = <FILE>
值不是循环的最佳标准。它[也许,有点]有效,但我从来没有这样做过。
chomp
无效,因为它会在next if
上运行而不是$_
[为什么要这样做?]。
所以,最后,$line
将有一个元素是最后一行[没有一个换行符],而不是每个文件的所有字符分成一个字符@seq
元素。
由于@seq
仍然有换行符,这可能是您之后有第二个@seq
的原因
<强>随机强>
对chomp
的主要更改是通过索引到数组而不是使用shuffle_seq
在标量内交换来操作。在您的代码中,您在substr
上执行了join
只是为了致电@seq
,然后对结果做了shuffle_seq
。通过让split
处理数组,事情就更简单了。
<强>语法:强>
我之前从未见过shuffle_seq
语法[它可能有效 - 我没有检查]。我只使用(my $par1, my $par2) = @_;
<强> make_base_pair:强>
在您的my($par1,$par2) = @_;
, make_base_pairs
和@seq
的所有元素中,最终会出现在make_base_pair的@shufSeq
中其@orig
将为空。
我将序列更改为@shuf
[在函数内部进行了相应的更改]。这会将标量引用传递给每个数组,而不是传递数组值。
请注意,对于引用,在函数内部,访问的语法更改为make_base_pair(\@seq,\@shufSeq)
和@$orig
通过这些更改,算法结果更可能是正确的。
如果没有它们,$shuf->[$idx]
仍然可以运行,但它有一个最终的错误就是节目制作者:
您的make_base_pairs
会在每个循环中添加两个元素:push
[记住X,""
为空]。因此,最终结果是一个单个char元素[或empty]和 not 数组元素的数组,它们是你想要的两个字符。
我对推送的更改:@shuf
使用perl的字符串连接运算符:push(@bps,$base . $shuf->[$idx]);
来连接.
和base
[这是一个单一的每个字符]产生两个字符输出元素。
主要的错误是shuf
返回的数组中有 no 两个字符元素,因此对它们求和的循环可能从不产生非零