【ROSALIND】【练Python,学生信】16 寻找蛋白模序

如果第一次阅读本系列文档请先移步阅读【ROSALIND】【练Python,学生信】00 写在前面 谢谢配合~

题目:
寻找蛋白模序(Finding a Protein Motif)
Given: At most 15 UniProt Protein Database access IDs.
所给:最多15个UniProt ID。
Return: For each protein possessing the N-glycosylation motif, output its given access ID followed by a list of locations in the protein string where the motif can be found.
需得:对每个有N-糖基化模序的蛋白,输出ID号,其后输出模序在蛋白序列中的位置。
测试数据
A2Z669
B5ZC00
P07204_TRBM_HUMAN
P20840_SAG1_YEAST
测试输出
B5ZC00
85 118 142 306 395
P07204_TRBM_HUMAN
47 115 116 382 409
P20840_SAG1_YEAST
79 109 135 248 306 348 364 402 485 501 614
背景
蛋白基序的表示方法:[XY]意为X或Y,{X}意为除了X以外任意一种氨基酸。
N-糖基化基序可表示为N{P}[ST]{P}。
UniProt是Universal Protein的英文缩写,是信息最丰富、资源最广的蛋白质数据库。它由整合Swiss-Prot、 TrEMBL 和 PIR-PSD 三大数据库的数据而成。数据主要来自于基因组测序项目完成后,后续获得的蛋白质序列,还包含了大量来自文献的蛋白质的生物功能的信息。
从UniProt数据库获取某个蛋白质信息的网址为http://www.uniprot.org/uniprot/uniprot_id
获取FASTA格式的某个蛋白序列可通过网址http://www.uniprot.org/uniprot/uniprot_id.fasta
思路
(本题不会做,代码全部来自网络╮(﹀_﹀)╭)
可以把该题目拆解成三个问题逐个理解。
第一,获取蛋白fasta格式的序列。利用背景给出的方法我们可以通过UniProt ID得到每个蛋白的序列网址,比如对B5ZC00,网址为https://www.uniprot.org/uniprot/B5ZC00.fasta ,随后利用urllib.request包中提供的方法,可以提取到网页信息。我们直接打开网页可以看到如下信息:

与我们熟悉的fasta格式文件一样,第一行是描述,换行(\n)后是序列以M开头。因此我们遇到的第一个’\nM’肯定是序列开始部分,找到这个索引,加上2即为序列开头M的索引,其后所有内容都是蛋白序列,将格式稍事调整即得到完整序列。
第二,用正则表达式表示模序。题目和背景给出了N-糖基化蛋白模序,因此只需要掌握正则表达式即可(可惜我还未掌握)。
第三,在蛋白序列中匹配模序,有则输出位置。用字符串带的搜索方法即可。
Python知识点
正则表达式(Regular Expression,在代码中常简写为regex、regexp或RE)是计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。即用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。
网络爬虫是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。
代码
import urllib.request
import re
f = open('rosalind_mprt.txt', 'r')
names = f.readlines()
f.close()
i = 0
while i < len(names):
name = str(names[i]).strip()
url = 'http://www.uniprot.org/uniprot/' + name + '.fasta'
req = urllib.request.Request(url)
response = urllib.request.urlopen(req)
the_page = response.read()
start = the_page.find('\nM'.encode())
the_page = str(the_page)
seq = the_page[start + 2:].replace('\\n', '').replace('\'', '')
seq = ' ' + seq
regex = re.compile(r'N(?=[^P][ST][^P])')
out = []
index = 0
while index < len(seq):
index += 1
if re.search(regex, seq[index:]) == None:
break
if re.match(regex, seq[index:]) != None:
out.append(index)
if out != []:
print(name)
print(' '.join([str(i) for i in out]))
i += 1