2

このトピックに関する他の質問を調べましたが、私が理解しようとしていることに実際に対処するものを見つけることができませんでした。

問題はこれです:私は、DNAの2つの相補的な鎖でパリンドロームを探し、識別された各パリンドロームの位置と長さを返すプログラムを作成しようとしています。

たとえば、シーケンスTTGATATCTTが与えられた場合、プログラムは補数(AACTATAGAA)を見つけ、2番目のインデックスが6文字の回文の始まりであることを識別します。

私はプログラミングにまったく慣れていないので、まったく間抜けに見えるかもしれませんが、私が思いついたコードは次のようになります。

'''This first part imports the sequence (usually consisting of multiple lines of text)
from a file. I have a feeling there's an easier way of doing this, but I just don't
know what that would be.'''

length = 4
li = []
for line in open("C:/Python33/Stuff/Rosalind/rosalind_revp.txt"):
    if line[0] != ">":
        li.append(line)
seq = (''.join(li))

'''The complement() function takes the starting sequence and creates its complement'''

def complement(seq):
    li = []
    t = int(len(seq))
    for i in range(0, t):
        n = (seq[i])
        if n == "A":
            li.append(n.replace("A", "T"))        
        if n == "T":
            li.append(n.replace("T", "A"))
        if n == "C":
            li.append(n.replace("C", "G"))
        if n == "G":
            li.append(n.replace("G", "C"))
    answer = (''.join(li))
    return(answer)

'''the ip() function goes letter by letter, testing to see if it matches with the letter
x spaces in front of it on the complementary strand(x being specified by length). If the
letter doesn't match, it continues to the next one. After checking all possibilities for
one length, the function runs again with the argument length+1.'''

def ip(length, seq):
    n = 0
    comp = complement(seq)
    while length + n <= (len(seq)):
        for i in range(0, length-1):
            if seq[n + i] != comp[n + length - 1 - i]:
                n += 1
                break
            if (n + i) > (n + length - 1 - i):
                print(n + 1, length)
                n += 1
    if length <= 12:
        ip(length + 1, seq)

ip(length, seq)

短いシーケンス(たとえば、TCAATGCATGCGGGTCTATATGCAT)で開始すると、完全に実行されますが、シーケンスが長いと、必ず次のエラーメッセージが表示されます。

Traceback (most recent call last):
  File "C:/Python33/Stuff/Ongoing/palindrome.py", line 48, in <module>
    ip(length, seq)
  File "C:/Python33/Stuff/Ongoing/palindrome.py", line 39, in ip
    if seq[n + i] != comp[n + length - 1 - i]:
IndexError: string index out of range

このメッセージは、プログラムが可能な4文字のパリンドロームのチェックを終了した後、長さ+1の関数を開始する前に表示されます。

メッセージの内容はわかりますが、なぜ届くのかわかりません。なぜこれは一部の文字列で機能し、他の文字列では機能しないのですか?私は過去1時間、シーケンスの文字数が奇数か偶数か、4の倍数であるか、4の倍数であるかなどに違いがあるかどうかを確認してきました。困惑しました。私は何が欠けていますか?

どんな助けでもいただければ幸いです。

PS問題は、1ベースの番号付けを使用するRosalind Webサイト(Rosalind.info)から発生します。したがって、最後にprint(n + 1、length)があります。

4

1 に答える 1

3

次のIndexError最後の行を変更することで、を回避できます。

if line[0] != ">":
    li.append(line)

if line[0] != ">":
    li.append(line.rstrip())

コードの先頭近く。これにより、ファイルから読み取られた末尾の空白、特に改行がseq文字列の一部になるのを防ぎます。complement()関数がそれらを無視して削除するため、それらが含まれていると問題が発生します。したがって、answer返される文字列は必ずしも入力引数と同じ長さではありません。これによりcompseqinip()関数でとが同じ長さになりません。

あなたは尋ねませんでしたが、これが私があなたのコードを短くしてそれをより「Pythonic」にする方法です:

COMPLEMENT = str.maketrans("ATCG", "TAGC")
LENGTH = 4

with open("palindrome.txt") as input:
    seq = ''.join(line.rstrip() for line in input if line[0] != ">")

def complement(seq): return seq.translate(COMPLEMENT)

def ip(length, seq):
    n = 0
    comp = complement(seq)
    while length + n <= len(seq):
        for i in range(0, length-1):
            if seq[n + i] != comp[n + length - 1 - i]:
                n += 1
                break
            if n + i > n + length - 1 - i:
                print(n + 1, length)
                n += 1
    if length <= 12:
        ip(length + 1, seq)

print(repr(seq))
print(repr(complement(seq)))
ip(LENGTH, seq)

ところで、print()最後に追加されたこれらの2つの関数呼び出しは、何が悪かったのかについての手がかりを与えてくれました。

于 2013-03-17T16:28:00.357 に答える