DNA to protein Script gibt kein vernünftiges Ergebnis

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
anonym113

Fehler 1: Die Protein Sequenz ist immer nur max. 10 Zeichen lang & Fehler 2: Es wird meistens keine vernünftige Protein Sequenz ausgegeben

Code:

Code: Alles auswählen

file = open('dna.txt', 'r')
dna = file.read()

print("DNA Sequence: ", dna)

protein_list = {"TTT": "F", "CTT": "L", "ATT": "I", "GTT": "V",
                "TTC": "F", "CTC": "L", "ATC": "I", "GTC": "V",
                "TTA": "L", "CTA": "L", "ATA": "I", "GTA": "V",
                "TTG": "L", "CTG": "L", "ATG": "M", "GTG": "V",
                "TCT": "S", "CCT": "P", "ACT": "T", "GCT": "A",
                "TCC": "S", "CCC": "P", "ACC": "T", "GCC": "A",
                "TCA": "S", "CCA": "P", "ACA": "T", "GCA": "A",
                "TCG": "S", "CCG": "P", "ACG": "T", "GCG": "A",
                "TAT": "Y", "CAT": "H", "AAT": "N", "GAT": "D",
                "TAC": "Y", "CAC": "H", "AAC": "N", "GAC": "D",
                "TAA": "STOP", "CAA": "Q", "AAA": "K", "GAA": "E",
                "TAG": "STOP", "CAG": "Q", "AAG": "K", "GAG": "E",
                "TGT": "C", "CGT": "R", "AGT": "S", "GGT": "G",
                "TGC": "C", "CGC": "R", "AGC": "S", "GGC": "G",
                "TGA": "STOP", "CGA": "R", "AGA": "R", "GGA": "G",
                "TGG": "W", "CGG": "R", "AGG": "R", "GGG": "G"
                }

protein_seq = ""

for i in range(3, len(dna) - (3 + len(dna) % 3), 3):
    if protein_list[dna[i:i + 3]] == "STOP":
        break
    protein_seq += protein_list[dna[i:i + 3]]

print("Protein Sequence: ", protein_seq)
Dies ist eine private Interessenssache nach 20 Stunden wach sein

Danke im Voraus, wenn mir jemand erklären kann, was falsch gemacht wurde und wie ich den Fehler behebe. Stichpunkte ohne Codebeispiel werden mir nicht viel bringen :)
Sirius3
User
Beiträge: 17767
Registriert: Sonntag 21. Oktober 2012, 17:20

Ohne den Input zu kennen, kann man auch nicht sagen, warum das nach 10 Zeichen stoppt.
Dateien, die man öffnet, sollte man auch wieder schließen.
Benutzeravatar
__blackjack__
User
Beiträge: 13133
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@getQueryString: Das mit dem Schliessen der Datei geht am einfachsten wenn man sie gar nicht (selber) öffnet. `pathlib.Path` hat eine Methode die das öffnen, einlesen, und schliessen komplett übernimmt.

Grunddatentypen haben nichts in Namen verloren, schon gar nicht wenn sie noch nicht einmal stimmen. `protein_list` ist ja gar keine Liste.

Wiederholt in Schleifen Zeichenketten erweitern ist ineffizient weil Zeichenketten unveränderbar sind, da also jedes mal unnötigerweise immer mehr Zeichen in eine neue Zeichenkette kopiert werden müssen. Der idiomatische Weg ist das sammeln der Teilzeichenketten in einer Liste, die dann am Ende mit der `join()`-Methode von Zeichenketten zusammengefügt werden.

Zwischenstand:

Code: Alles auswählen

#!/usr/bin/env python3
from pathlib import Path


def main():
    dna = Path("dna.txt").read_text(encoding="ascii")
    print("DNA Sequence:", dna)

    amino_acid_triple_to_protein = {
        "AAA": "K",
        "AAC": "N",
        "AAG": "K",
        "AAT": "N",
        "ACA": "T",
        "ACC": "T",
        "ACG": "T",
        "ACT": "T",
        "AGA": "R",
        "AGC": "S",
        "AGG": "R",
        "AGT": "S",
        "ATA": "I",
        "ATC": "I",
        "ATG": "M",
        "ATT": "I",
        "CAA": "Q",
        "CAC": "H",
        "CAG": "Q",
        "CAT": "H",
        "CCA": "P",
        "CCC": "P",
        "CCG": "P",
        "CCT": "P",
        "CGA": "R",
        "CGC": "R",
        "CGG": "R",
        "CGT": "R",
        "CTA": "L",
        "CTC": "L",
        "CTG": "L",
        "CTT": "L",
        "GAA": "E",
        "GAC": "D",
        "GAG": "E",
        "GAT": "D",
        "GCA": "A",
        "GCC": "A",
        "GCG": "A",
        "GCT": "A",
        "GGA": "G",
        "GGC": "G",
        "GGG": "G",
        "GGT": "G",
        "GTA": "V",
        "GTC": "V",
        "GTG": "V",
        "GTT": "V",
        "TAA": "STOP",
        "TAC": "Y",
        "TAG": "STOP",
        "TAT": "Y",
        "TCA": "S",
        "TCC": "S",
        "TCG": "S",
        "TCT": "S",
        "TGA": "STOP",
        "TGC": "C",
        "TGG": "W",
        "TGT": "C",
        "TTA": "L",
        "TTC": "F",
        "TTG": "L",
        "TTT": "F",
    }
    assert len(amino_acid_triple_to_protein) == 64

    protein_sequence = []
    for i in range(3, len(dna) - (3 + len(dna) % 3), 3):
        protein = amino_acid_triple_to_protein[dna[i : i + 3]]
        if protein == "STOP":
            break
        protein_sequence.append(protein)

    print("Protein Sequence:", "".join(protein_sequence))


if __name__ == "__main__":
    main()
Was genau soll die Berechnung beim `range()` denn bewirken? Dir ist klar, dass da das letzte vollständige und eventuell unvollständige Tripel am Ende nicht erfasst werden‽ Ist das gewollt, oder sollte das vielleicht doch bis zum letzten vollständigen Tripel gehen? In dem Falle sollte man vielleicht nicht so kompliziert rechnen, sondern einfach in der Schleife prüfen ob das Tripel vollständig ist und falls nicht, abbrechen.
“There will always be things we wish to say in our programs that in all known languages can only be said poorly.” — Alan J. Perlis
anonym113

__blackjack__ hat geschrieben: Sonntag 3. Januar 2021, 15:52 Ah OK.. Es funktioniert soweit, nur dass es nicht weiter als 8 Zeichen rechnet. Ich habe mit

Code: Alles auswählen

import random

def random_dna_sequence(length):
    return ''.join(random.choice('ACTG') for _ in range(length))


def base_frequency(dna):
    d = {}
    for base in 'ATCG':
        d[base] = dna.count(base) / float(len(dna))
    return d


for _ in range(3000):
    dna = random_dna_sequence(100)
    print(dna, base_frequency(dna))
    data = open("dna.txt", "a")
    print(data.write(dna))
    data.close()
3000 Zeichen autogenerieren lassen. 🤔
Mad.
Benutzeravatar
__blackjack__
User
Beiträge: 13133
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@getQueryString: Das generiert 300.000 Zeichen, nicht nur 3.000. Und es hängt sie an die Datei an, d.h. wenn da schon etwas drin steht, sind es am Ende mehr Zeichen.

Da sollte man eher die Datei *einmal* öffnen, zum Schreiben, und alle Zeichen hineinschreiben. Statt die Datei 3.000 mal zu öffnen und zu schliessen.

Man sollte Dateien mit ``with`` zusammen verwenden, wann immer das möglich ist.

`data` ist kein guter Name für ein Dateiobjekt. Das wäre eher ein allgemeiner Name für die Daten die in eine Datei geschrieben oder daraus gelesen werden.

Den Rückgabewert von `write()` auszugeben macht eher wenig Sinn.

`random.choices()` spart etwas Code.

Der `float()`-Aufruf ist überflüssig.

`d` ist kein guter Name. Da sich das als „dict comprehension“ ausdrücken lässt, braucht man auch nicht zwingend einen Namen.

Für die Verteilung würde sich `collections.Counter` anbieten.

Ungetestet:

Code: Alles auswählen

#!/usr/bin/env python3
import random
from collections import Counter

BASES = "ACTG"


def random_dna_sequence(length):
    return "".join(random.choices(BASES, k=length))


def base_frequency(dna):
    base_to_count = Counter(dna)
    return {base: base_to_count[base] / len(dna) for base in BASES}


def main():
    with open("dna.txt", "w", encoding="ascii") as file:
        for _ in range(3000):
            dna = random_dna_sequence(100)
            print(dna, base_frequency(dna))
            file.write(dna)


if __name__ == "__main__":
    main()
“There will always be things we wish to say in our programs that in all known languages can only be said poorly.” — Alan J. Perlis
Antworten