转载 | 流程脚本编写规范(以perl为例)

Posted 生信Rookie

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了转载 | 流程脚本编写规范(以perl为例)相关的知识,希望对你有一定的参考价值。

本文转发自 简书APP的王子哥哥的博客

原文链接:https://www.jianshu.com/p/aeb7541f769c?utm_campaign=hugo&utm_medium=reader_share&utm_content=note&utm_source=weixin-friends&from=groupmessage&isappinstalled=0


流程是介于脚本与软件的一组代码文件,所以在写流程的时候要知道脚本的基本结构以及软件开发的基本常识。前者要掌握,后者要了解。


出于掌握的需要,重温一下:

  • Name:脚本名字

  • DescripCon:对脚本简介

  • Version:作者、版本及日期

  • Usage:用法及参数说明(参数较多可以分类或者按首字母排序)

  • Note:注意事项


Example:使用例子

#!/usr/bin/perl -w
# 加载时间管理,参数管理,文件名和路径处理的基础包,无须安装
use POSIX qw(strftime);
use Getopt::Std;
use File::Basename;
###############################################################################
#命令行参数据的定义和获取,记录程序初始时间,设置参数默认值
#Get the parameter and provide the usage.
my $rename = "perl $Bin/rename.pl"  # 在开头一个集中的位置,记录所用程序路径
my $R = "$Bin/RScript"
###############################################################################
my %opts;
getopts( 'i:o:d:h:', \%opts );
&usage unless ( exists $opts{i} && exists $opts{o} );
my $start_time=time;
print strftime("Start time is %Y-%m-%d %H:%M:%S\n", localtime(time));
print "Input file is $opts{i}\nOutput file is $opts{o}\n";
print "Database file is $opts{d}\n" if defined($opts{d});
$opts{h}=1 unless defined($opts{h});
###############################################################################
#读入的数据或注释文件,用于与输入文件比较或注释(可选),提供三种方式
#Read the database in memory(opt)
###############################################################################
#open DATABASE,"<$opts{d}";
# 1. 散列结构数据库,要求数据文件有唯一ID并且无顺序要求
#my %database; #database in hash
#while (<DATABASE>) {
#    chomp;
#    my @tmp=split/\t/;
#    $database{$tmp[1]}=$tmp[2];
#}
# 2. 数组结构数据库,无唯一ID,但有顺序要求
#my (@tmp1,@tmp2); #database in array
#while (<DATABASE>) {
#    chomp;
#    my @tmp=split/\t/;
#    push @tmp1,$tmp[1];
#    push @tmp2,@tmp[2];
#}
#close DATABASE;
# 3. 批量数据文件,读取一批有相似结构的文件
#open a list file
#my %list;
#my @filelist=glob "$opts{i}";
#foreach $file(@filelist){
#    open DATABASE,"<$file";
#    $file=basename($file);
#    while (<DATABASE>) {
#        my @tmp=split/\t/;
#        $list{$file}{nr}++;
#    }
#    close DATABASE;
#}
###############################################################################
#Main text.
###############################################################################
# 正文部分,读取输入文件,列出输入和输入文件的三行作为示例,方便编程处理数据
open INPUT,"<$opts{i}";
#chrm0    snppos1          ref2     mat_gtyp3        pat_gtyp4        c_gtyp5  phase6   mat_all7 pat_all8 cA9  cC10   cG11   cT12   winning SymCls  SymPval BindingSite     cnv
#1       4648    C       A       C       M       PHASED  C       A       0       11      0       0       M       Asym    0.0009765625    -1      0.902113
open OUTPUT,">$opts{o}";
#chrm    snppos          ref     mat_gtyp        pat_gtyp        c_gtyp  phase   mat_all pat_all cA      cC      cG      cT      winning SymCls  SymPval BindingSite     cnv
#1       4648    C       A       C       M       PHASED  C       A       0       11      0       0       M       Asym    0.0009765625    -1      0.902113
my %count;
# h参数用于去除有文件头的行
while ($opts{h}>0) { #filter header
   <INPUT>;
   $opts{h}--;
}
# 输入和输入处理部分,常用按行读取处理并输入,默认按tab分割数据
while (<INPUT>) {
   chomp;
   my @tmp=split/\t/;
   print OUTPUT "$tmp[0]\t$tmp[1]\n";
}
close INPUT;
close OUTPUT;
###############################################################################
#Record the program running time!
# 输出程序运行时间
###############################################################################
my $duration_time=time-$start_time;
print strftime("End time is %Y-%m-%d %H:%M:%S\n", localtime(time));
print "This compute totally consumed $duration_time s\.\n";
###############################################################################
#Scripts usage and about.
# 程序的帮助文档,良好的描述是程序重用和共享的基础,也是程序升级和更新的前提
###############################################################################
sub usage {
   die(
       qq!
Usage:    template.pl -i inpute_file -o output_file -d database -h header num
Function: Template for Perl
Command:  -i inpute file name (Must)
         -o output file name (Must)
         -d database file name
         -h header line number,s default 0
Author:   Zhang San, zhangsan_bio\@163.com, QQ:1102279384
Version:  v1.0
Update:   2018/04/09
Notes:    
\n!
   )
}


为什么要规范流程的编写呢?

  • 可读性

  • 流程的维护、升级和调试

  • 代码的重复利用


怎样规范流程编写?

  • 目录结构

  • README 流程发布/更新时间,版本,创建人,记录流程版本,更新信息的文件

  • bin/主流程脚本及一些重要的配置文件

  • database/使用的数据库,可在lib或配置文件中

  • doc/测试报告、说明书、参考文献等说明性资料

  • report/商业项目流程交付所需的文档

  • example/运行例子.包含:脚本、输入数据、example、output/输出结果展示、运行例子等

  • 路径引用及接口

  • 在开头一个集中的位置,记录所用程序路径

  • 对于更新较快的数据库,或者被调用的脚本涉及数据库路径问题,最好留一个用参数设置来输入路径的接口(以备以前的数据要用)

  • 注释及变量命名规则

  • 文件名称统一用英文字母(大小写)、数字和下划线的组合

  • 每个全局变量必须有注释说明其作用(命名本身就应有注释的作用)
    在函数的开头写函数的使用说明

  • 一个脚本中不同的功能,用注释线隔开

  • 模块化编程

  • 一个脚本完成一项简单的任务

  • 模块话编程及把算法独立写成方法,提高了代码的重用

  • 模块间连接:串行、并行。

  • 思维导图、流程图

  • 流程开发及升级规划

  • 文献调研

  • 工作量评估

  • 伪代码、流程图、框架

  • 代码编写与调试

  • 流程测试

  • 文档撰写

  • 发布

  • 执行与监督与反馈

  • 在编程中修炼自己

  • 在小修小补中优化,在质的飞跃中升级

  • 版本管理


再度重申基本代码结构:

#!/usr/bin/perl    –w
#调用库,配置环境变量
use lib/xxx/;或者BEGIN{push @INC,/xxx/;}
use    xxx包;
#==========================================
获取输入参数
使用说明
参数初始化(赋默认值)
输入文件或参数检测
获取引用软件路径
#==========================================
主程序
#==========================================
子程序


以上是关于转载 | 流程脚本编写规范(以perl为例)的主要内容,如果未能解决你的问题,请参考以下文章

Postman接口测试脚本编写规范

shell脚本规范

FFH小熊派驱动调用流程(以调用LED灯驱动为例)

Apache服务器中运行CGI程序的方法,文中以Perl脚本作为示例

3-Perl 基础语法

以管理员身份运行 cgi perl 脚本