dictionarry

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
Kern1
User
Beiträge: 2
Registriert: Samstag 27. November 2021, 10:11

Ich möchte gerne eine Funktion schreiben um eine DNA Sequenz mithilfe eines Dictionarry in Aminosäuren zu ändern.
Wenn ich nun auf den Key zugreifen möchten, dann erhalte ich die Rückmeldung : Key error
,anstatt es die Aminosäuren in die Liste "aminos" einfügt.

Ich verstehe nicht dass es mir die Richtigen Aminosäuren angibt, wenn ich es lediglich so mache: print(amino_sequence[c[i:i+3]]). Dann stimmt alles.
Aber mit der append Funktion erscheint Key error.
Aus welchem Grund ist es möglich, dass es ohne die append Funktion geht und mit nicht?



def translate_dna(sequence, start, length):

amino_sequence= {'UUU': 'PHE','UUC': 'PHE','UUA': 'LEU','UUG': 'LEU','CUU': 'LEU','CUC': 'LEU','CUA': 'LEU','CUG': 'LEU','AUU': 'ILE','AUC': 'ILE','AUA': 'ILE','AUG': 'MET','GUU': 'VAL','GUC': 'VAL','GUA': 'VAL','GUG': 'VAL','UCU': 'SER','UCC': 'SER','UCA': 'SER','UCG': 'SER','CCU': 'PRO','CCC': 'PRO','CCA': 'PRO','CCG': 'PRO','ACU': 'THR','ACC': 'THR','ACA': 'THR','ACG': 'THR','GCU': 'ALA','GCC': 'ALA','GCA': 'ALA','GCG': 'ALA','UAU': 'TYR','UAC': 'TYR','UAA': 'STOP','UAG': 'STOP','CAU': 'HIS','CAC': 'HIS','CAA': 'GLN','CAG': 'GLN','AAU': 'ASN','AAC': 'ASN','AAA': 'LYS','AAG': 'LYS','GAU': 'ASP','GAC': 'ASP','GAA': 'GLU','GAG': 'GLU','UGU': 'CYS','UGC': 'CYS','UGA': 'STOP','UGG': 'TRP','CGU': 'ARG','CGC': 'ARG','CGA': 'ARG','CGG': 'ARG','AGU': 'SER','AGC': 'SER','AGA': 'ARG','AGG': 'ARG','GGU': 'GLY','GGC': 'GLY','GGA': 'GLY','GGG': 'GLY'}

sequence = sequence.upper()

if valid_sequence(sequence) == True:

b = start
sequence_RNA = sequence.replace("T","U")
c = sequence_RNA[b : b + length + 1]
a = (length + 1) % 3



if a == 0:
i = 0

while i <= len(c):
aminos = []
aminos.append(amino_sequence[c[i:i+3]])
i+=3
return aminos

Besten Dank bereit im Voraus...:)
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

@Kern1,

auf den ersten Blick sieht das so aus als würdest du eine einfache Sache unnötig kompliziert machen.
KeyError bedeutet, dass versucht wird auf einen Dictionary - Key zuzugreifen, den es nicht gibt.
Wenn das mit print() funktioniert, ist bestimmt irgend etwas anders. Der Fehler muss ja auch nicht beim ersten Schleifendurchlauf auftreten. Es reicht ja wenn eins der Element nicht erkannt wird.

Das kann man aber leider nicht genau erkennen, ohne zu wissen was an die Funktion übergeben wird. Was für Werte haben sequence, start, length?
Was "valid_sequence()" für eine Funktion ist, kann man auch nicht erkennen.

In der While-Schleife setzt du bei jedem Durchlauf "aminos" wieder auf eine leere Liste. Selbst wenn append() funktionieren würde, wäre da immer nur ein Element drin.

Was steht denn in der gesamten Fehlermeldung?

Vielleicht kannst du mal mit Worten erklären was der Algorithmus überhaupt machen soll. Dann kann man dir vielleicht eine bessere Lösung vorschlagen.
Benutzeravatar
kbr
User
Beiträge: 1508
Registriert: Mittwoch 15. Oktober 2008, 09:27

@Kern1: Da geht mit den Bezeichnungen einiges durcheinander. Ich vermute, dass du eine DNA Sequenz per Condon-Tabelle in ein Protein überführen möchtest. Dafür solltest du schrittweise vorgehen:

Versuche zunächst die DNA Sequenz in Triple zu zerlegen. Wenn dir das gelingt, dann erstelle das RNA Pendant und mache mit diesem den Lookup in der Condon-Tabelle (die auch so heißen sollte, und nicht "amino_sequence"). Die daraus entnommenen Kennungen kannst du dann anschließend in einer Liste zusammenführen.

Probiere einen Schritt nach dem anderen. Schreibe nicht alles auf einmal. Du kannst die Schritte auch in Teil-Funktionen auslagern, das kann das Verständnis erleichtern.
P_Python
User
Beiträge: 19
Registriert: Donnerstag 11. November 2021, 19:45

Du solltest auf jeden Fall, bevor du auf einen Schlüssel eines Dictionarys zugreifst, prüfen, ob es den Schlüssel im Dictionary überhaupt gibt.
Dann kannst du im Fehlerfall noch den nicht vorhandenen/gefundenen Schlüssel in einer Fehlermeldung ausgeben, vielleicht hilft das dir.

Code: Alles auswählen

  while i <= len(c):
        aminos = []
        key = c[i:i+3]
        if key not in amino_sequence:
            print(f'Key:{key} is not in amino_sequence')
            return
        aminos.append(amino_sequence[c[i:i+3]])
        i+=3
        return aminos
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

@P_Python: das wuerde ich so nicht sehen. Wenn die Konsquenz des nicht-vorhandenseins ein Abbruch ist, so wie auch bei dir, dann ist eine Ausnahme auszuloesen genau der richtige Weg. Wenn der Aufrufer dann immer noch weiter machen will, dann kann er die fangen. Und sonst kommt ja eine Fehlermeldung automatisch. Dein Code hingegen verschleiert nun, dass etwas schief gegangen ist, und man *muss* erstmal den Rueckgabewert pruefen. Keine echter Fortschritt.
P_Python
User
Beiträge: 19
Registriert: Donnerstag 11. November 2021, 19:45

@__deets__
Das soll ja auch nur dazu dienen den Schlüssel zu finden der den Programmabbruch verursacht hat. Da ich ja das vollständige Programm nicht kenne, konnte ich ja in der Bedingung nichts vernünftiges eintragen. Später, für den Echteinsatz, muss das natürlich geändert werden.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

@P_Python diese Information steckt in der Ausnahme KeyError doch drin:

Code: Alles auswählen

17:16 $ python3
Python 3.8.10 (default, Sep 28 2021, 16:10:42) 
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> {}["unbekannt"]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'unbekannt'
Kein Grund, den Code umzuschreiben.
P_Python
User
Beiträge: 19
Registriert: Donnerstag 11. November 2021, 19:45

@__deets__
Stimmt, war mir nicht bewusst.
Aber prüfen, ob der key im Dictionary ist, würde ich auf jeden Fall
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Warum? Meine Gruende das nicht zu tun habe ich ja dargelegt. Wenn du einen Key *erwartest*, dann kannst du doch eh nichts machen an der Stelle. Du verkomplizierst nur deinen Code. Was also ist dein guter Grund?
P_Python
User
Beiträge: 19
Registriert: Donnerstag 11. November 2021, 19:45

Du hast doch vorher selbst gesagt, um evtl. eine Exception zu fangen. Ob man es hier braucht, wissen wir beide nicht, da wir die Anforderungen nicht wissen.
Benutzeravatar
__blackjack__
User
Beiträge: 14078
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@P_Python: Was meinst Du mit „um evtl. eine Exception zu fangen“? Dazu braucht man nichts prüfen, die wird doch automatisch ausgelöst wenn man versucht auf einen nicht vorhandenen Schlüssel zuzugreifen.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Benutzeravatar
kbr
User
Beiträge: 1508
Registriert: Mittwoch 15. Oktober 2008, 09:27

@P_Python: Die Anwendung lässt sich zumindest ein wenig erahnen. Wenn zu einer angegeben DNA Sequenz kein passender Eintrag gefunden werden kann, dann liegt ein Fehler im Input vor, oder im Mapping. Das ist definitv ein Grund für eine Exception. Die aufrufende Routine muss dann damit umgehen können, falls dies eine erwartbare Situation sein sollte.
P_Python
User
Beiträge: 19
Registriert: Donnerstag 11. November 2021, 19:45

Prinzipiell kann man ja einen Fehlerfall auf 3 Arten abhandeln:

1) nicht abfangen wie es ja momentan ist.
2) verhindern, dass die Exception KeyError überhaupt entsteht, indem man abfragt, ob der Schlüssel im Dictionary ist. Im Else-Zweig kann man dann, je nach Erfordernissen, reagieren(abbbrechen, protokollieren und weiter..)
3) mit try/except gezielt den KeyError abfangen und wie unter 2) beschrieben reagieren

Da wird es wohl auf die spezielle Situation ankommen, welche Methode man anwendet
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du hast aber vorgeschlagen IMMER zu prüfen. 🤷🏼‍♂️
Antworten