цикл завершается неудачно при увеличении строки из элементов в списке - PullRequest
2 голосов
/ 26 января 2011

У меня проблема с генератором последовательности. У меня есть файл, где каждая строка содержит один фрагмент (8 букв). Я загружаю его из файла в список, где каждый элемент представляет собой один фрагмент. Это ДНК, поэтому так и должно быть:

1. Принимает первый 8-буквенный элемент
2. Проверьте элемент, в котором первые 7 букв совпадают с последними 7 буквами в первой.
3. Добавьте восьмую букву из второго элемента в последовательность.

Это должно выглядеть так:

ATTGCCAT
 TTGCCATA
  TGCAATAC

Итак, последовательность: ATTGCCATAC

К сожалению, он добавляет только один элемент. :( Первый элемент задан (мы знали это). Я делаю это таким образом, его первым в файле (первая строка).

Вот код:

from os import sys
import random

def frag_get(seqfile):
    frags = []
    f_in = open(seqfile, "r")
    for i in f_in.readlines():
        frags.append(i.strip())
    f_in.close()
    return frags

def frag_list_shuffle(frags):
    random.shuffle(frags)
    return frags

def seq_build(first, frags):
    seq = first
    for f in frags:
        if seq[-7:] == f[:7]:
            seq += f[-1:]
    return seq

def errors():
    pass



if  __name__ == "__main__":
    frags = frag_get(sys.argv[1])
    first = frags[0]
    frags.remove(first)
    frags = frag_list_shuffle(frags)
    seq = seq_build(first, frags)
    check(sys.argv[2], seq)
    spectrum(sys.argv[2], sys.argv[3])

Я удалил функции проверки и спектра, потому что это простые вычисления, например Сравнение длины, так что это не то, что вызывает проблемы, как я думаю.

Я буду очень благодарен за помощь!

С уважением, Матеуш

Ответы [ 3 ]

3 голосов
/ 26 января 2011

Поскольку ваши фрагменты перемешаны, ваш алгоритм должен это учитывать; в настоящее время вы просто просматриваете фрагменты один раз, что вряд ли включает несколько фрагментов, если они не в правильном порядке. Например, скажем, у вас есть 5 фрагментов, на которые я буду ссылаться по порядку в вашей последовательности. Теперь фрагменты немного вышли из строя:

1 - 3 - 2 - 4 - 5

Ваш алгоритм будет начинаться с 1, пропустить 3, затем совпадать с 2, добавляя базу в конце. Затем он проверяет 4 и 5, а затем заканчивает, не достигая фрагмента 3.

Вы могли бы легко это исправить, запуская цикл каждый раз, когда добавляете базу, однако это будет очень плохо масштабироваться для большого количества баз. Вместо этого я бы порекомендовал загружать ваши фрагменты в trie , а затем каждый раз искать базу данных для поиска следующего фрагмента, пока вы не добавите одну базу для каждого фрагмента или вы больше не сможете найти соответствующий фрагмент.

1 голос
/ 26 января 2011

работает для меня:

>>> seq = "ATTGCCAT"
>>> frags = ["TTGCCATA", "TGCCATAC"]
>>> for f in frags:
...         if seq[-7:] == f[:7]:
...             seq += f[-1:]
... 
>>> seq
'ATTGCCATAC'

В вашем примере есть орфографическая ошибка, TGCAATAC должен быть TGCCATAC.Но исправляя это работает.

0 голосов
/ 27 января 2011

Ради интереса и интереса я переписал проблему, используя ОО.Посмотрите, что вы думаете:

import collections
import sys
import random

usage = """
Usage:
    sequence fname expected

Where
    fname:     name of file containing fragments
    expected:  result-string which should be obtained by chaining from first fragment.
"""

class Frag(str):
    MATCHLEN = 7

    def __new__(cls, s=''):
        return str.__new__(cls, s.strip())

    def head(self):
        return Frag(self[:Frag.MATCHLEN])

    def tail(self):
        return Frag(self[Frag.MATCHLEN:])

    def nexthead(self):
        return Frag(self[-Frag.MATCHLEN:])

    def check(self, s):
        return self.__eq__(s)

    def __add__(self, s):
        return Frag(str(self).__add__(s))

class Fraglist(list):
    @classmethod
    def fromFile(cls, fname):
        with open(fname, "r") as inf:
            lst = [Frag(ln) for ln in inf]
        return cls(lst)

    def shuffle(self):
        random.shuffle(self)

class Sequencer(object):
    def __init__(self, seq=None):
        super(Sequencer, self).__init__()
        self.sequences = collections.defaultdict(list)
        if seq is not None:
            for frag in seq:
                self.sequences[frag.head()].append(frag.tail())

    def build(self, frag):
        res = [frag]
        match = frag.nexthead()

        while match in self.sequences:
            next = random.choice(self.sequences[match])
            res.append(next)
            match = (match + next).nexthead()

        return Frag(''.join(res))

def main():
    if len(sys.argv) != 3:
        print usage
        sys.exit(-1)
    else:
        fname = sys.argv[1]
        expected = sys.argv[2]

        frags = Fraglist.fromFile(fname)
        frag1 = frags.pop(0)
        frags.shuffle()

        seq = Sequencer(frags)
        result = seq.build(frag1)

        if result.check(expected):
            print "Match!"
        else:
            print "No match"

if __name__=="__main__":
    main()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...