Python Schleife bricht vorzeitig ab, wie lösen?
Das Programm liest Labels aus mehreren Dateien aus.
In den Dateien stehen z.B. " A B A C B A C B A C" und das Programm soll alle A-Intervalle bestimmen.
Ein A-Intervall geht bis zum nächsten Buchstaben, also das erste A-Intervall geht von A bis B, das zweite A-Intervall geht von A bis C und so weiter.
Nun bin ich aber auf ein Problem gestoßen, denn sobald ein A am Ende der Datei steht, bricht meine Schleife ab, da es nach einem weiteren Buchstaben sucht, um das Ende des A-Intervalls zu bestimmen. Leider weiß ich nicht, wie ich das Problem lösen kann, so dass das Programm das Ende auch ohne ein folgendes Label erkennt.
for j in range(kal, len(label)):
AEnde = A.sample[j + 1]
AEnde zählt immer um +1 hoch, um die Grenze des Intervalls zu bestimmen. Steht nun ein A am Ende, möchte AEnde also um +1 erhöhen, aber die Datei ist bereits am Ende.
Bitte um Hilfe :)
Kannst du den ganzen Code schicken? Oder zumindest das nötige?
Leider nicht möglich.
3 Antworten
Dein konkretes Problem kann ich dir leider nicht sagen, dafür müsste ich mehr Code sehen.
Aber hier die Lösung für deine Aufgabenstellung:
label = " A B A C B A C B A C A"
label = label.replace(" ", "") # Leertasten entfernen
intervals = []
for i in range(len(label)):
if label[i] == "A" and i < len(label)-1:
intervals.append((label[i], label[i+1]))
print(intervals)
Dein konkretes Problen wird durch diesen Teil hier gelöst:
i < len(label)-1
Das überprüft, ob das A am Ende des Strings steht, oder ob danach noch was kommt.
Dann hast du deine Aufgabe in der Frage absolut falsch formuliert.
"Das Programm soll alle A-Intervalle bestimmten" "Ein A-Intervall geht [vom jeweiligen A] bis zum nächsten Buchstaben".
Genau das macht mein Code. Er liefert eine Liste an A-Intervallen.
Und wie du den Fehler vermeidest wenn das "A" am Ende der Datei steht, hab ich dir auch gezeigt:
i < len(label)-1
Eine völlig vereinfachte "Realisierung" auf Kindergartenniveau, welche nichts mit dem realen Problem gemein hat und so unbrauchbar ist. Vielleicht einfach über das konkrete Problem nachdenken und dazu eine konkrete Antwort liefern.
Wenn du in deiner Frage nur eine vereinfachte Version deines Problems lieferst, und uns nichtmal den nötigen Code zur Verfügung stellst, dann erwarte nicht, dass wir eine Antwort zu einem realen Problem herzaubern können - Wir kennen ja dein reales Problem ja nicht.
Mein Code macht genau das, was du in der Frage beschreibst:
In den Dateien stehen z.B. " A B A C B A C B A C" und das Programm soll alle A-Intervalle bestimmen.
Ein A-Intervall geht bis zum nächsten Buchstaben, also das erste A-Intervall geht von A bis B, das zweite A-Intervall geht von A bis C und so weiter.
A B A C B A C B A C
->
(A B), (A, C), (A C), (A C).
Wenn dir das nicht passt, dann beschreibe die Aufgabe genauer, oder zeig uns deinen Code!
Außerdem ein Wunder, dass du dich hier beschwerst, dass dir mein Code zu einfach ist. Deine Python Kenntnisse sind ja selbst noch auf Kindergartenniveau, wenn ich deine letzten Fragen so ansehe - Du kennst ja nichtmal den Unterschied von Tupel und Liste ...
Anstatt dich zu beschweren dass die Antworten unbrauchbar sind, beschreibe deine unbrauchbare Frage genauer. Peace.
Very nice, der Seitenhieb mit Tupel und Liste hat mich auf die Lösung meines Problems gebracht. Ändert aber nichts an deiner falschen Antwort bzw. "Lösung".
Das freut mich haha. Das ist die hauptsache :D
Und wie gesagt, meine Lösung bezieht sich auf die Frage so wie sie jetzt dasteht. Input ist wie von dir gegeben, Output ist wie von dir gewünscht. Das ganze sinnvoll in dein System einzufügen/anzupassen ist deine Aufgabe.
Du kannst nicht einfach sagen meine Lösung wäre falsch, wenn sie die Frage perfekt beantwortet. Dann ist es deine Frage, die falsch (oder zu ungenau) ist. Das sollte dir bewusst werden wenn du dir mal die anderen Kommentare, die Nachfrage und die Bewertungen meiner Antwort anschaust. :P
Aber bei einer Sache war ich mir tatsächlich unsicher bei meiner Lösung - Was wenn zwei mal A dasteht? Daher hier noch eine Alternativlösung, die die beiden As dann in ein (A, A)-Intervall packt, und das zweite A überspringt, anstatt daraus noch ein (A, ..)-Intervall zu machen:
iRange = (i for i in range(len(label)))
for i in iRange:
if label[i] == "A" and i < len(label)-1:
intervals.append((label[i], label[i+1])) # Mache Intervall aus "A" und nächsten Buchstaben
next(iRange, None) # Überspringe in der Schleife den nächsten Buchstaben
Aber wird dir vermutlich auch nix helfen, wenn meine Annahme stimmt, dass du die Aufgabe in der Frage falsch formuliert hast.
Aber ja, freut mich, dass du jetzt die Lösung gefunden hast. ^^
Bin beim Programmieren schnell angepi**t, wenn etwas nicht klaptt, sorry :D
Vielleicht würde deine Lösung nach ein paar Anpassungen auch funktionieren, das Programm ist sehr umfangreich und es sind dutzend verschachtelte for Schleifen die unterschiedliche Dateien vergleichen und umwandeln. Da möchte man echt nicht nochmal alles durchgehen, sondern möglichst direkt nur das Problem im vorhandenen Code lösen :D
Das "AA" Problem ging mir damals auch durch den Kopf, aber dieser Fall kann niemals auftreten, da es sich um Markierungen bestimmter Zeitabläufe handelt die erst mit der nächsten Markierung enden.
Nochmal das Problem: Datei mit Label Reihenfolge A, B, A, C, B stellt kein Problem dar, da das letzte A das Intervall A bis C zugewiesen werden kann.
Datei mit Label Reihenfolge A, B, A, C, A stellt ein Problem dar, da das Letzte A kein Ende findet.
Mit der Tupel/Liste Geschichte kann ich das Array mit den Labels über append erweitern und der Fall, dass ein A am Ende steht ist ausgeschlossen. Das Programm meckert nun auch nicht mehr, allerdings bin ich mir nicht zu 100% sicher, ob es negative Auswirkungen haben könnte..
In dem Teil des Codes werden die Intervalle bestimmt..
for kal, var in enumerate(annotation.aux_note):
if var == 'A': # start A Bereich
AStart = annotation.sample[kal]
for j in range(kal, len(label)):
AStop = annotation.sample[j + 1]
Kein Ding, das kenn ich auch :D
Könnte man anstatt
for j in range(kal, len(label)):
AStop = annotation.sample[j + 1]
nicht einfach
AStop = annotation.sample[len(label)]
machen? Weil momentan überschreibst du AStop einfach immer, bis j bei len(label)-1 angekommen ist. Da könnte man ja gleich len(label) hernehmen. Oder hast du da was rausgestrichen?
Aber zu deinem Problem, das könnte man doch so lösen, or not? :
for kal, var in enumerate(annotation.aux_note):
if var == 'A' and kal < len(annotation.aux_note)-1: # start A Bereich
AStart = annotation.sample[kal]
for j in range(kal, len(label)):
AStop = annotation.sample[j + 1]
Sagt dir der Begriff "Reguläre Ausdrücke" (regular expressions oder regex) was?
Ich bin mir nicht ganz sicher, was genau du erreichen willst, aber könntest du nicht bei einem A in deinem String (ich denke mal es ist ein String) den Index überprüfen und falls dieser gleich der Länge des Strings-1 ist, hast du das Ende erreicht?
Hat absolut nichts mit meinem Problem bzw. Aufgabe zu tun.