我正在尝试编写一个子函数,允许用户键入某些内容,该函数将在文件中搜索包含它们的行。我遇到的主要问题是foreach语句中的if语句。我的主要目标是查看用户键入的三个变量是否与文件中的某些列匹配。如果他们这样做,那么某些列将被取出到他们的特定变量。
我的数据如下:
ATOM 4851 O PRO A 715 89.164 76.083 75.292 1.00 99.41 O
ATOM 4852 CB PRO A 715 88.324 78.267 73.865 1.00 95.88 C
ATOM 4853 CG PRO A 715 88.836 78.838 72.540 1.00 95.93 C
例如,如果用户键入PRO A 715,则foreach将遍历所有行,if语句将满足这些条件,然后将取出坐标。
x坐标:89.164,88.324,88.836
y坐标:76.083,78.267,78.838
z坐标:75.292,73.865,72.540
我得到的错误是:
Can't modify logical and (&&) in scalar assignment at ./pdbtool.pl line 75, near ") ) "
我的节目是:
open (FILE, $ARGV[0])
or die "Could not open file\n";
my @newlines;
while ( my $line = <FILE> ) {
if ($line =~ m/^ATOM.*/) {
push @newlines, $line;
}
}
sub reslength {
#User will type in the information
print "Type Residue Name:\n";
my $residue = <STDIN>;
chomp($residue);
print "Type Chain ID:\n";
my $chainid = <STDIN>;
chomp ($chainid);
print "Type Residue Sequence Number\n";
my $resseq = <STDIN>;
chomp ($resseq);
#The function will go through each line and match the info along with pushing it to a new vairable
my @arrayx;
my @arrayy;
my @arrayz;
foreach my $record3(@newlines) {
if ( $residue = substr($record3, 17, 3) && $chainid = substr($record3, 21, 1) && $resseq = substr($record3, 22, 4) ) {
@arrayx = substr($record3, 30, 8);
@arrayy = substr($record3, 38, 8);
@arrayz = substr($record3, 46, 8);
}
}
#Now I will find the distance between these x,y,z coordinates
my $distance = sqrt[(@arrayx(1)-@arrayx(0))^2 + (@arrayy(1)-@arrayy(0))^2 + (@arrayz(1)-@arrayz(0))^2)]
print "$resname with sequence number $resseq in $chainid has length $distance angstroms.\n"
}
答案 0 :(得分:0)
对perl进行问题排查的第1步启用了use strict;
和use warnings;
,因为这会告诉您代码的问题。
您使用sqrt
的代码段几乎肯定是个问题,因为您使用了错误的括号,并省略了分号。
然而另外:
reslength
,将大部分代码放入其中,然后再实际调用它。=
,而不是==
。 =
是一个作业,其中==
是一个比较。 substr
是脆弱的。试试正则表达式或split
。 (
时应使用sqrt
。 [
。 $ARGV[0]
上指定的文件 - 您应该考虑使用<>
执行相同的操作(但也会执行多个文件)。 所以作为10的首发 - 这会将你的坐标读入数组。
#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;
#replace this bit with your 'user input' once you're done testing.
my $residue = 'PRO';
my $chainid = 'A';
my $resseq = '715';
my @coords;
open ( my $input, '<', $ARGV[0] ) or die $!;
while ( <$input> ) {
next unless m/^ATOM/;
my @fields = split;
my ( $res, $chain, $seq, $x_coord, $y_coord, $z_coord ) = @fields[3..8];
next unless $residue eq $res;
next unless $chainid eq $chain;
next unless $resseq eq $seq;
#insert into array of coordinates. Could flip order, and
push ( @{$coords[0]}, $x_coord );
push ( @{$coords[1]}, $y_coord );
push ( @{$coords[2]}, $z_coord );
}
close ( $input );
#print for debugging - what have we read in.
print Dumper \@coords;
my $distance = sqrt ( ( $coords[0][1] - $coords[0][0] ) ^ 2
+ ( $coords[1][1] - $coords[1][0] ) ^ 2
+ ( $coords[2][1] - $coords[2][0] ) ^ 2 );
print "$residue with sequence number $resseq in $chainid has length $distance angstroms.\n"
问题在于,它完全忽略了你的第三行。但是你的代码似乎也是如此,所以我不确定你想用它做什么。
但是这会输出:
PRO with sequence number 715 in A has length 2.44948974278318 angstroms.
答案 1 :(得分:-1)
你不能像这样修改if语句中的变量。 我想你可能想做一个比较检查。
if ( $residue == substr($record3, 17, 3) && $chainid == substr($record3, 21, 1) && $resseq == substr($record3, 22, 4) )
然而,这带来了$ distance的另一个错误 要访问数组中的变量,您应该使用$ array [$ num]
my $distance = sqrt[($arrayx[1]-$arrayx[0])^2 + ($arrayy[1]-$arrayy[0])^2 + ($arrayz[1]-$arrayz[0])^2];
答案 2 :(得分:-2)
我可以看到你正在使用&#34; if&#34;而不是逻辑&#34; == &#34;或&#34; eq &#34;运营商。尝试更改此行:
git
到此:
if ( $residue = substr($record3, 17, 3) && $chainid = substr($record3, 21, 1) && $resseq = substr($record3, 22, 4) )
注意:如果&#34; == &#34;不起作用,尝试使用&#34; eq &#34;代替。我不太熟悉Pearl的逻辑运算符,但我认为它们与Java中的大致相同。