Seite 3 von 3

Verfasst: Sonntag 11. Oktober 2009, 12:49
von BlackJack
Also ich habe es in die `fold()`-Funktion getan:

Code: Alles auswählen

#!/usr/bin/env python
# coding: utf-8
"""Ported from a piece of Perl code.
"""
from collections import defaultdict

BONDS = dict(GU=1, UG=1, AU=2, UA=2, CG=3, GC=3)


def fold(rna):
    c = defaultdict(int)
    for length in xrange(5, len(rna) + 1):
        for i in xrange(0, len(rna) - length + 1):
            j = i + length - 1
            c[i, j] = max(c[i + 1, j],
                          BONDS.get(rna[i] + rna[j], 0) + c[i + 1, j - 1],
                          max(c[i, k] + c[k + 1, j] for k in xrange(i + 1, j)))
    return c


def trace_back(rna):
    
    c = fold(rna)

    def _trace_back(i, j):
        c_ij = c[i, j]
        if c_ij == 0:
            result = '.' * (j - i + 1)
        elif c_ij == c[i + 1, j]:
            result = '.' + _trace_back(i + 1, j)
        elif c_ij == BONDS.get(rna[i] + rna[j], 0) + c[i + 1, j - 1]:
            result = '(' + _trace_back(i + 1, j -1) + ')'
        else:
            for k in xrange(i + 1, j):
                if c_ij == c[i, k] + c[k + 1, j]:
                    result = _trace_back(i, k) + _trace_back(k + 1, j)
                    break
            else:
                assert False
        return result
    
    result = _trace_back(0, len(rna) - 1)
    assert len(result) == len(rna)
    return result


def main():
    rna = ('CUCUCGGUAGCCAAGUUGGUUUUAAGGCGCAAGACUGAAUUUACCACUACGAAACUUGAGA'
           'UCGGGCGUUCGACUCGCCCCCGGGAGACCA')
    expected = ('.((((((...))(((((((((((..(...))))))(((...)..)))(...)))))'
                ')))))(((((.(..((...)).)))))((...)))')
    result = trace_back(rna)
    print rna
    print result
    print result == expected


if __name__ == '__main__':
    main()
Und ich habe den Index von `i` um eins nach unten verschoben, um dieses hässliche "Füll-'X'" loszuwerden.

Verfasst: Montag 12. Oktober 2009, 00:38
von mit
Leider habe ich übersehen, dass dafaultdict erst für 2.5 gibt, aber ich verwende immer noch 2.4. Deshalb habe ich versucht dafaultdict durch:

Code: Alles auswählen

 c = [[0 for col in range(j)] for row in range(i)] 
zu ersetzen, aber leider ohne Erfolg:

Code: Alles auswählen

#!/usr/bin/env python
# coding: utf-8
"""Ported from a piece of Perl code.
"""


BONDS = dict(GU=1, UG=1, AU=2, UA=2, CG=3, GC=3)


def fold(rna):
  # create i x j matrix
  i = len(rna)
  j = len(rna)
  c = [[0 for col in range(j)] for row in range(i)]
  
  for length in xrange(5, len(rna) + 1):
    for i in xrange(0, len(rna) - length + 1):
      j = i + length - 1
      c[i][ j] = max(c[i + 1][ j],
                    BONDS.get(rna[i] + rna[j], 0) + c[i + 1][ j - 1],
                    max(c[i][ k] + c[k + 1][ j] for k in xrange(i + 1, j)))
    return c


def trace_back(rna):
   
    c = fold(rna)

    def _trace_back(i, j):
        c_ij = c[i][ j]
        if c_ij == 0:
            result = '.' * (j - i + 1)
        elif c_ij == c[i + 1][ j]:
            result = '.' + _trace_back(i + 1, j)
        elif c_ij == BONDS.get(rna[i] + rna[j], 0) + c[i + 1][ j - 1]:
            result = '(' + _trace_back(i + 1, j -1) + ')'
        else:
            for k in xrange(i + 1, j):
                if c_ij == c[i][ k] + c[k + 1][ j]:
                    result = _trace_back(i, k) + _trace_back(k + 1, j)
                    break
            else:
                assert False
        return result
   
    result = _trace_back(0, len(rna) - 1)
    assert len(result) == len(rna)
    return result


def main():
    rna = ('CUCUCGGUAGCCAAGUUGGUUUUAAGGCGCAAGACUGAAUUUACCACUACGAAACUUGAGA'
           'UCGGGCGUUCGACUCGCCCCCGGGAGACCA')
    expected = ('.((((((...))(((((((((((..(...))))))(((...)..)))(...)))))'
                ')))))(((((.(..((...)).)))))((...)))')
    result = trace_back(rna)
    print rna
    print result
    print result == expected


if __name__ == '__main__':
    main()

Ich bekomme nämlich nur False zurück. Was habe ich falsch gemacht?

Verfasst: Montag 12. Oktober 2009, 01:24
von EyDu
mit hat geschrieben:Leider habe ich übersehen, dass dafaultdict erst für 2.5 gibt, aber ich verwende immer noch 2.4. Deshalb habe ich versucht dafaultdict durch:

Code: Alles auswählen

 c = [[0 for col in range(j)] for row in range(i)] 
zu ersetzen, aber leider ohne Erfolg:
Wie soll das auch funktionieren, wenn nicht einmal "length" oder "rna" darin vorkommen, bzw. die Indizes später angepasst werden?

Aktualisiere einfach auf 2.5, kopiere dir den Code von defaultdict oder schreibe es selber. Letzteres sind nur wenige Zeilen Code.

Verfasst: Montag 12. Oktober 2009, 07:18
von cofi
Alternativ kannst du auch die Methoden `get` oder `set_default` benutzen, um das Verhalten eines defaultdicts zu emulieren.

Verfasst: Mittwoch 14. Oktober 2009, 03:07
von mit
Habe auf Python 2.5 upgedatet und es funktioniert. Vielen Dank.