Ubuntu14.04 安装、配置nginx

Nginx是一款轻量级、高性能web服务器,它占用内存少,并发能力强。越来越多的网站使用Nginx作为web服务器。
Nginx依赖以下模块:
1. gzip模块需要 zlib 库
2. rewrite模块需要 pcre 库
3. ssl 功能需要openssl库
Nginx可以使用系统中已经安装的库,也可以自行指定。
下载Nginx,pcre,openssl,zlib源文件,然后通过如下命令安装:

tar zxvf nginx-1.11.0.tar.gz
tar zxvf pcre-8.38.tar.gz
tar zxvf openssl-1.0.1j.tar.gz
tar zxvf zlib-1.2.8.tar.gz
cd nginx-1.11.0
./configure --with-pcre=../pcre-8.38 --with-openssl=../openssl-1.0.1j --with-zlib=../zlib-1.2.8
sudo make & make install

Nginx默认安装在/usr/local/下,也可以在configure时使用–prefix参数指定安装路径。
Nginx安装后,Nginx文件夹的目录结构如下:

.
|-- conf
|   |-- fastcgi.conf
|   |-- fastcgi.conf.default
|   |-- fastcgi_params
|   |-- fastcgi_params.default
|   |-- koi-utf
|   |-- koi-win
|   |-- mime.types
|   |-- mime.types.default
|   |-- nginx.conf
|   |-- nginx.conf.default
|   |-- scgi_params
|   |-- scgi_params.default
|   |-- uwsgi_params
|   |-- uwsgi_params.default
|   `-- win-utf
|-- html
|   |-- 50x.html
|   `-- index.html
|-- logs
|   |-- access.log
|   `-- error.log
`-- sbin
    `-- nginx

conf文件夹下是配置文件,html文件夹是网站默认根目录,logs文件夹下是日志文件,sbin文件夹下是Nginx可执行程序。
启动Nginx:

sudo /usr/local/nginx/sbin/nginx             #启动Nginx
sudo /usr/local/nginx/sbin/nginx -s stop     #停止Nginx
sudo /usr/local/nginx/sbin/nginx -s reload   #重启Nginx

启动Nginx后,访问127.0.0.1,可以看到欢迎页面。
nginx
nginx.conf是主配置文件
worker_process表示工作进程的数量,一般设置为cpu的核数
worker_connections表示每个工作进程的最大连接数
server{}块定义了虚拟主机
listen监听端口
server_name监听域名
location{}指定网站文件的位置
index指定首页index文件的名称,可以配置多个,以空格分开。如有多个,按配置顺序查找。

Python运算符和优先级

运算符 说明
yield X 生成器函数结果(返回send()值)
lambda args1:X 匿名函数生成器(调用后返回X)
X if Y else Z 三元选择(当Y为真时计算X,否则计算Z)
X or Y 逻辑或
X and Y 逻辑与
not X 逻辑非
X in Y, X not in Y 成员是否在可迭代对象中
X is Y, X is not Y 对象等价测试
X Y, X >= Y 大小比较
X == Y, X != Y 相等运算符
X | Y 集合并
X ^ Y 集合对称差
X ^ Y 集合交
X << Y, X >> Y 将X左/右移Y位
X + Y, X – Y 加,减
X * Y, X / Y, X // Y, X % Y 乘,除,整除,取余
-X, +X 负,正
~X 按位非补(倒置)
X ** Y 乘方
X[i] 索引(序列,映射,其他)
X[i:j:k] 切片
X(args) 调用(函数,方法,类和其他可调用对象)
X.attr 属性引用
(…) 元组,表达式,生成器表达式
[…] 列表,列表内涵
{…} 字典,集合,字典与集合内涵

参考:
《Python袖珍指南》(第五版)

Python常用转义字符

转义字符 含义 转义字符 含义
\newline 忽略换行 \t 水平制表符
\\ 反斜杠(\) \v 竖直制表符
\’ 单引号(‘) \N{id} Unicode dbase id
\” 双引号(“) \uhhhh Unicode 16位十六进制
\a 蜂鸣(Bell) \Uhhhhhhhh Unicode 32位十六进制
\b 空格 \xhh Hex(最多两位数字)
\f 换页 \ooo Octal(达到三位数字)
\n 换行 \0 Null(非字符串结尾)
\r 回车 \other 非转义字符

这里的大部分转义字符跟linux系统保持一致!
\Uhhhhhhhh严格采用8个十六进制数字(h)。\u和\U只可以用在Unicode字符串文字中。

BED格式转GTF格式

# -*- coding: utf-8 -*-
"""
Created on Fri Dec 25 19:43:00 2015
@author: biochen
"""
import sys, getopt, csv
# get parameter
opts, args = getopt.getopt(sys.argv[1:], "hi:o:s:")
input_file = ""
output_file = ""
source = ""
for op, value in opts:
    if op == "-i":
        input_file = value
    elif op == "-o":
        output_file = value
    elif op == "-s":
        source = value
    elif op == "-h":
        print("Usage: python3 BED2GTF.py -i input.bed -o output.gtf -s source")
        sys.exit()
BED_in_file = open(input_file, "r")
GTF_out_file = open(output_file, "w")
BED = csv.reader(BED_in_file, dialect = "excel-tab")
GTF = csv.writer(GTF_out_file, dialect = "excel-tab", quotechar = "'")
for item in BED:
    transcript = []
    transcript.append(item[0])
    transcript.append(source)
    transcript.append("transcript")
    transcript.append(int(item[1]) + 1)
    transcript.append(int(item[2]) + 1)
    transcript.append(item[4])
    transcript.append(item[5])
    transcript.append(".")
    transcript.append('transcript_id "' + item[3] + '";')
    GTF.writerow(transcript)
    exon_number = int(item[9])
    exon_size = list(map(int, (filter(lambda x:x and len(x.strip()) > 0, item[10].split(",")))))
    exon_start = list(map(int, (filter(lambda x:x and len(x.strip()) > 0, item[11].split(",")))))
    for i in range(exon_number):
        exon = []
        exon.append(item[0])
        exon.append(source)
        exon.append("exon")
        exon.append(int(item[1]) + exon_start[i] + 1)
        exon.append(exon[3] + exon_size[i] - 1)
        exon.append(item[4])
        exon.append(item[5])
        exon.append(".")
        exon.append('transcript_id "' + item[3] + '\";')
        GTF.writerow(exon)
BED_in_file.close()
GTF_out_file.close()

GTF格式转BED格式

 # -*- coding: utf-8 -*-
"""
Created on Wed Dec 16 11:03:05 2015
@author: biochen
"""
import sys, getopt, csv, re
opts, args = getopt.getopt(sys.argv[1:], "hi:o:")
for op, value in opts:
    if op == "-i":
        GTF_in_File_Name = value
    elif op == "-o":
        BED_in_File_Name = value
    elif op == "-h":
        print("Usage: python3 GTF2BED.py -i input.gtf -o output.bed")
        sys.exit()
GTF_in_file = open(GTF_in_File_Name, "r")
BED_out_file = open(BED_in_File_Name, "w")
GTFs = csv.reader(GTF_in_file, dialect = "excel-tab")
BEDs = csv.writer(BED_out_file, dialect = "excel-tab")
transcripts = {}
for GTF in GTFs:
    if GTF[2] == "exon":
        transcript_id = re.findall('transcript_id "([^;]*)"', GTF[8])[0]
        if transcript_id in transcripts:
            transcripts[transcript_id][6].append([int(GTF[3]), int(GTF[4])])
        else:
            transcripts[transcript_id] = []
            transcripts[transcript_id].append(GTF[0])
            transcripts[transcript_id].append(GTF[3])
            transcripts[transcript_id].append(GTF[4])
            transcripts[transcript_id].append(GTF[5])
            transcripts[transcript_id].append(GTF[6])
            transcripts[transcript_id].append(transcript_id)
            transcripts[transcript_id].append([[int(GTF[3]), int(GTF[4])]])
for transcript in transcripts:
    transcripts[transcript][6].sort()
    transcript_start = transcripts[transcript][6][0][0]
    transcript_end = transcripts[transcript][6][len(transcripts[transcript][6]) - 1][1]
    exon_sizes = ""
    exon_starts = ""
    for exon in transcripts[transcript][6]:
        exon_size = exon[1] - exon[0] + 1
        exon_start = exon[0] - transcript_start
        exon_sizes = exon_sizes + str(exon_size) + ","
        exon_starts = exon_starts + str(exon_start) + ","
    BED = []
    BED.append(transcripts[transcript][0])
    BED.append(transcript_start - 1)
    BED.append(transcript_end)
    BED.append(transcripts[transcript][5])
    BED.append(transcripts[transcript][3])
    BED.append(transcripts[transcript][4])
    BED.append(transcript_start - 1)
    BED.append(transcript_end)
    BED.append("0, 0, 0")
    BED.append(len(transcripts[transcript][6]))
    BED.append(exon_sizes)
    BED.append(exon_starts)
    BEDs.writerow(BED)
GTF_in_file.close()
BED_out_file.close()

Python计算Rank(秩)

在统计学中,有时候我们需要求一组数据的Rank,如非参检验、Spearman相关性等。Rank中文意思叫做顺序,更专业点的叫法是”秩”。这里介绍一下用Python求Rank。
先看一个简单的例子:

>>> a = [1.0, 5.6, 3.5, 9.7, 7.8]
>>> # rank_a = [1, 3, 2, 5, 4]
...
>>> rank_a = sorted(range(len(a)), key = a.__getitem__)
>>> rank_a
[0, 2, 1, 4, 3]
>>> rank_a = [i + 1 for i in rank_a]
>>> rank_a
[1, 3, 2, 5, 4]

上面的例子中,列表a中的元素是没有重复的,直接排序即可。如果有重复元素怎么办呢?最简单的办法是使用SciPy提供的rankdata()函数。

>>> from scipy.stats import rankdata
>>> rankdata([0, 2, 3, 2])
array([ 1. ,  2.5,  4. ,  2.5])
>>> rankdata([0, 2, 3, 2], method='min')
array([ 1,  2,  4,  2])
>>> rankdata([0, 2, 3, 2], method='max')
array([ 1,  3,  4,  3])
>>> rankdata([0, 2, 3, 2], method='dense')
array([ 1,  2,  3,  2])
>>> rankdata([0, 2, 3, 2], method='ordinal')
array([ 1,  2,  4,  3])

rankdata()函数返回一个array对象,默认的方法是average,即相同元素的Rank值取算术平均数,同时rankdata()函数还提供了其他方法。
如果觉得安装SciPy库太麻烦,我们也可以自己实现。下面的代码计算重复元素的Rank使用的方法是average,返回一个列表。

def rank_simple(vector):
    return sorted(range(len(vector)), key=vector.__getitem__)
def rankdata(vector):
    n = len(vector)
    ivec = rank_simple(vector)
    svec = [vector[rank] for rank in ivec]
    sumranks = 0
    dupcount = 0
    newvector = [0] * n
    for i in range(n):
        sumranks = sumranks + i
        dupcount = dupcount + 1
        if i == n - 1 or svec[i] != svec[i + 1]:
            averank = sumranks / float(dupcount) + 1
            for j in range(i - dupcount + 1, i + 1):
                newvector[ivec[j]] = averank
            sumranks = 0
            dupcount = 0

Python列表推导式

Python进阶之一就是学会写列表推导式。列表推导式用较为优雅的方式生成列表,从而避免冗余代码,不过对于新手来讲,代码的可读性不高。我们先看下面一段示例。

>>>a = [1, 2, 3, 4]
>>>b = [item * 2 for item in a]
>>>b
[2, 4, 6, 8]

上述代码将一个列表中每一个元素加倍生成一个新的列表,可以写成如下更容易理解的形式:

>>>a = [1, 2, 3, 4]
>>>b = []
>>>for item in a:
...     b.append(item * 2)
...
>>>b
[2, 4, 6, 8]

结果是一样的,但是列表推导式所需的代码更少。如果我们只想保留偶数并加倍,可以这么写:

>>>a
[1, 2, 3, 4]
>>>b = [item * 2 for item in a if item % 2 == 0]
>>>b
[4, 8]

总结一下,Python列表推导式的模式为[expression for item in sequence if conditions]。列表推导式放在[]中;首先是一个表达式,定义了对每一个元素要做什么;接下来是一个for循环,从一个序列中依次拿出一个元素;最后是if条件,可以没有if条件。[]改为()得到的是一个生成器(generator),改为{}得到一个字典或者集合。
用列表推导式可以写出更有创意的代码,当然如果代码很难被读懂,应该尽量实现更好可读性的代码。可读性高的代码才更加具有生命力。

Python字典(dict)的setdefault()方法

如果需要统计一个字符串中每一个字符出现的次数,我会写出如下的代码:

Strings = "Welcome to my blog: blog.biochen.com!"
count = {}
for character in Strings:
	if character in count:
		count[character] = count[character] + 1
	else:
		count[character] = 0
		count[character] = count[character] + 1
print(count)

需要初始化字典中的元素的场景还是很常见的,似乎用if..else…看起来比较傻。不过Python内置了字典(dict)的setdefault()方法,上述代码可以写成这样子:

Strings = "Welcome to my blog: blog.biochen.com!"
count = {}
for character in Strings:
	count.setdefault(character, 0)
	count[character] = count[character] + 1
print(count)

dict.setdefault(key, default=None)的作用是,如果健不在字典中,将会添加健,并将值设置为默认值。
不过用if…else…比用setdefault()速度要快!!!
 

Python实现DNA序列互补、反向、反向互补

DNA有两条链,但是通常我们只用其中一条链来表示,另外一条链是它的反向互补序列。利用Python我们可以轻松地实现DNA序列的反向、互补、及反向互补。
定义函数DNA_complement()实现DNA序列互补配对,函数DNA_reverse() 实现DNA序列反向。

def DNA_complement(sequence):
    sequence = sequence.upper()
    sequence = sequence.replace('A', 't')
    sequence = sequence.replace('T', 'a')
    sequence = sequence.replace('C', 'g')
    sequence = sequence.replace('G', 'c')
    return sequence.upper()
def DNA_reverse(sequence):
    sequence = sequence.upper()
    return sequence[::-1]

我们来演示一下:

>>> DNA = "acctgCaG" #原序列
>>> DNA_complement(DNA) #互补序列
'TGGACGTC'
>>> DNA_reverse(DNA) #反向序列
'GACGTCCA'
>>> DNA_reverse(DNA_complement(DNA)) #反向互补序列
'CTGCAGGT'