#密码子表
codes={'UUU': ('Phe', 'F'), 'UUC': ('Phe', 'F'), 'UUA': ('Leu', 'L'), 'UUG': ('Leu', 'L'), \
'UCU': ('Ser', 'S'), 'UCC': ('Ser', 'S'), 'UCA': ('Ser', 'S'), 'UCG': ('Ser', 'S'), \
'UAU': ('Tyr', 'Y'), 'UAC': ('Tyr', 'Y'), 'UAA': ('', ''), 'UAG': ('', ''), \
'UGU': ('Cys', 'C'), 'UGC': ('Cys', 'C'), 'UGA': ('', ''), 'UGG': ('Trp', 'W'), \
'CUU': ('Leu', 'L'), 'CUC': ('Leu', 'L'), 'CUA': ('Leu', 'L'), 'CUG': ('Leu', 'L'), \
'CCU': ('Pro', 'P'), 'CCC': ('Pro', 'P'), 'CCA': ('Pro', 'P'), 'CCG': ('Pro', 'P'), \
'CAU': ('His', 'H'), 'CAC': ('His', 'H'), 'CAA': ('Gln', 'Q'), 'CAG': ('Gln', 'Q'), \
'CGU': ('Arg', 'R'), 'CGC': ('Arg', 'R'), 'CGA': ('Arg', 'R'), 'CGG': ('Arg', 'R'), \
'AUU': ('Ile', 'I'), 'AUC': ('Ile', 'I'), 'AUA': ('Ile', 'I'), 'AUG': ('Met', 'M'), \
'ACU': ('Thr', 'T'), 'ACC': ('Thr', 'T'), 'ACA': ('Thr', 'T'), 'ACG': ('Thr', 'T'), \
'AAU': ('Asn', 'N'), 'AAC': ('Asn', 'N'), 'AAA': ('Lys', 'K'), 'AAG': ('Lys', 'K'), \
'AGU': ('Ser', 'S'), 'AGC': ('Ser', 'S'), 'AGA': ('Arg', 'R'), 'AGG': ('Arg', 'R'), \
'GUU': ('Val', 'V'), 'GUC': ('Val', 'V'), 'GUA': ('Val', 'V'), 'GUG': ('Val', 'V'), \
'GCU': ('Ala', 'A'), 'GCC': ('Ala', 'A'), 'GCA': ('Ala', 'A'), 'GCG': ('Ala', 'A'), \
'GAU': ('Asp', 'D'), 'GAC': ('Asp', 'D'), 'GAA': ('Glu', 'E'), 'GAG': ('Glu', 'E'), \
'GGU': ('Gly', 'G'), 'GGC': ('Gly', 'G'), 'GGA': ('Gly', 'G'), 'GGG': ('Gly', 'G')}
def Get_mRNA(): #获取mRNA
mRNA=input("待分析mRNA序列(从5′到3′): ")
print("单字母缩写\t[S]")
print("三字母缩写\t[T]")
while True:
choice=input("选择缩写形式: ")
if choice in ["S", "s", "T", "t"]:
break
print("\n")
return mRNA, choice
def Get_sequences(mRNA): #确定三种读码方式,将mRNA分割为密码子列表
S=list(mRNA)
nt=len(mRNA) #nt表示mRNA序列长度
S1, S2, S3=S.copy(), S.copy(), S.copy()
if nt%3==1: #根据mRNA序列长度确定三种读码方式
del S1[-1], S2[0], S3[:2], S3[-2:]
elif nt%3==2:
del S1[-2:], S2[0], S2[-1], S3[:2]
else:
del S1[0], S1[-2:], S2[:2], S2[-1]
sequences=[S1, S2, S3]
for i in range(len(sequences)): #把分割结果分别写入三种读码方式的列表S1, S2, S3
S=sequences[i]
S_info=[]
for n in range(len(S)-2):
if n%3==0:
codon=S[n]+S[n+1]+S[n+2] #每三个碱基作为一个密码子
S_info.append(codon)
sequences[i]=S_info
return sequences
def Translate(sequences, choice):
start_codon="AUG" #起始密码子
stop_codons=["UAA", "UAG", "UGA"] #终止密码子
peptides_set=set() #合成的肽链可能有重复,以集合形式去重
for S in sequences:
start_indexs=[] #保存每个读码方式的所有初始密码子位置
stop_indexs=[] #保存每个读码方式的所有终止密码子位置
ORF_ranges=[] #记录每个读码方式的可读范围
for i in range(len(S)): #记录所有初始、终止密码子位置
if S[i]==start_codon:
start_indexs.append(i)
elif S[i] in stop_codons:
stop_indexs.append(i)
if start_indexs==[]: #如果没有初始密码子,直接看下一种读码方式
continue
elif stop_indexs==[]: #如果有初始密码子,没有终止密码子,能读到末尾
for start in start_indexs:
ORF_ranges.append((start, len(S)))
else:
for start in start_indexs:
if start<min(stop_indexs): #初始密码子在最左侧终止密码子的左侧
ORF_ranges.append((start, min(stop_indexs)))
elif start>max(stop_indexs): #初始密码子在最右侧终止密码子的右侧
ORF_ranges.append((start, len(S)))
else: #初始密码子在两个终止密码子之间
for n in range(len(stop_indexs)-1):
stop1=stop_indexs[n]
stop2=stop_indexs[n+1]
if stop1<start<stop2: #确定初始密码子位置
ORF_ranges.append((start, stop2))
for r in ORF_ranges: #翻译为肽链
ORF=S[r[0] : r[1]] #获取可读框
if choice=="T" or choice=="t": #根据缩写形式确定肽链
peptide=list(map(lambda codon: codes[codon][0], ORF)) #做从密码子到氨基酸的映射
peptides_set.add("-".join(peptide)) #peptide为列表结构,不能直接存入集合,需要转换为字符串
elif choice=="S" or choice=="s":
peptide=list(map(lambda codon: codes[codon][1], ORF))
peptides_set.add("".join(peptide))
peptides=sorted(list(peptides_set), key=lambda p: len(p)) #按肽链从短到长排序
return peptides
def Show_peptide(peptides, choice):
if peptides==[]: #没有得到肽链
print("无初始密码子!\n")
else:
print("氨基酸序列: ")
for p in peptides:
print(p)
print("\n")
def main():
while True: #无限循环方便多次输入
mRNA, choice=Get_mRNA()
sequences=Get_sequences(mRNA)
peptides=Translate(sequences, choice)
Show_peptide(peptides, choice)
if __name__=="__main__":
main()