如果在foreach声明

时间:2017-12-12 00:28:47

标签: perl pdb-files

我正在尝试编写一个子函数,允许用户键入某些内容,该函数将在文件中搜索包含它们的行。我遇到的主要问题是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"

}

3 个答案:

答案 0 :(得分:0)

对perl进行问题排查的第1步启用了use strict;use warnings;,因为这会告诉您代码的问题。

您使用sqrt的代码段几乎肯定是个问题,因为您使用了错误的括号,并省略了分号。

然而另外:

  • 您定义了一个子reslength,将大部分代码放入其中,然后再实际调用它。
  • 您在比较中使用=,而不是===是一个作业,其中==是一个比较。
  • 匹配空格分隔的
  • substr是脆弱的。试试正则表达式或split
  • 调用(时应使用sqrt
  • 在查看数组指示时,您应该使用[
  • 您正在打开$ARGV[0]上指定的文件 - 您应该考虑使用<>执行相同的操作(但也会执行多个文件)。
  • 您正在将文件读入数组,然后迭代该数组。为什么不迭代文件?
  • 你应该使用3个参数打开lexical文件句柄。

所以作为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中的大致相同。