perl - 如何将其更改为 "idiomatic"Perl?

标签 perl bioinformatics

我开始深入研究 Perl,但是在编写“Perl-ly”代码而不是用 Perl 编写 C 时遇到了麻烦。如何更改以下代码以使用更多 Perl 习语,我应该如何学习这些习语?

只是对它在做什么的解释:此例程是对齐 DNA 或氨基酸序列的模块的一部分(如果您关心此类事情,请使用 Needelman-Wunch)。它创建了两个二维数组,一个用于存储两个序列中每个位置的分数,另一个用于跟踪路径,以便以后可以重新创建得分最高的对齐方式。它工作得很好,但我知道我做的事情不是很简洁明了。

编辑:这是为了一个任务。我完成了它,但想稍微清理一下我的代码。算法实现细节见on the class website如果你们有兴趣的话。

sub create_matrix {
    my $self = shift;
    #empty array reference
    my $matrix = $self->{score_matrix};
    #empty array ref
    my $path_matrix = $self->{path_matrix};
    #$seq1 and $seq2 are strings set previously
    my $num_of_rows = length($self->{seq1}) + 1;
    my $num_of_columns = length($self->{seq2}) + 1;

    #create the 2d array of scores
    for (my $i = 0; $i < $num_of_rows; $i++) {
        push(@$matrix, []);
        push(@$path_matrix, []);
        $$matrix[$i][0] = $i * $self->{gap_cost};
        $$path_matrix[$i][0] = 1;
    }

    #fill out the first row
    for (my $i = 0; $i < $num_of_columns; $i++) {
        $$matrix[0][$i] = $i * $self->{gap_cost};
        $$path_matrix[0][$i] = -1;
    }
    #flag to signal end of traceback
    $$path_matrix[0][0] = 2;
    #double for loop to fill out each row
    for (my $row = 1; $row < $num_of_rows; $row++) {
        for (my $column = 1; $column < $num_of_columns; $column++) {
            my $seq1_gap = $$matrix[$row-1][$column] + $self->{gap_cost};
            my $seq2_gap = $$matrix[$row][$column-1] + $self->{gap_cost};
            my $match_mismatch = $$matrix[$row-1][$column-1] + $self->get_match_score(substr($self->{seq1}, $row-1, 1), substr($self->{seq2}, $column-1, 1));
            $$matrix[$row][$column] = max($seq1_gap, $seq2_gap, $match_mismatch);

            #set the path matrix
            #if it was a gap in seq1, -1, if was a (mis)match 0 if was a gap in seq2 1
            if ($$matrix[$row][$column] == $seq1_gap) {
                $$path_matrix[$row][$column] = -1;
            }
            elsif ($$matrix[$row][$column] == $match_mismatch) {
                $$path_matrix[$row][$column] = 0;
            }
            elsif ($$matrix[$row][$column] == $seq2_gap) {
                $$path_matrix[$row][$column] = 1;
            }
        }
    }
}

最佳答案

您收到了一些关于语法的建议,但我也建议采用更模块化的方法,如果没有其他原因代码可读性。如果您能够在担心低级细节之前了解全局,那么加快代码速度会容易得多。

您的主要方法可能如下所示。

sub create_matrix {
    my $self = shift;
    $self->create_2d_array_of_scores;
    $self->fill_out_first_row;
    $self->fill_out_other_rows;
}

你也会有几个像这样的小方法:
n_of_rows
n_of_cols
create_2d_array_of_scores
fill_out_first_row
fill_out_other_rows

并且您可以通过定义更小的方法(getter、setter 等)来更进一步。那时,您的中级方法如 create_2d_array_of_scores根本不会直接触及底层数据结构。
sub matrix      { shift->{score_matrix} }
sub gap_cost    { shift->{gap_cost}     }

sub set_matrix_value {
    my ($self, $r, $c, $val) = @_;
    $self->matrix->[$r][$c] = $val;
}

# Etc.

关于perl - 如何将其更改为 "idiomatic"Perl?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1614522/

相关文章:

perl - 系统函数 "ping"和 Perl 中的 Net::Ping 模块之间的区别?

perl - 在 Perl 中捕获 SQL 连接的异常

java - 如何将 Perl 脚本翻译为 Java?

python - Snakemake:将多个输入用于具有多个子组的一个输出的规则

python - 计算 pandas DataFrame 中值的频率

python - Mykrobe 预测器 JSON 到 TSV 转换器

mysql - Bugzilla 中分离客户端的基本权限

perl - mojolicious lite 中的 hypnotoad 辅助函数

python - 使用python在两个字符串中搜索相似词(具有指定长度)的有效方法

java - biojava包导入错误