Verzweiflung

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
timbo16
User
Beiträge: 6
Registriert: Freitag 6. August 2010, 13:22

Manchmal hat man einen Bug und man kommt einfach nicht dahinter. Meist liegt es daran, dass Dinge passieren die man nciht versteht. Ich fürchte ich bin so weit. Für mich ist das jetzt schon seit ein paar Stunden Sackgasse. Bitteschön:

Code: Alles auswählen

		for index in index_list:
			temp_varvaluelist=[]
			temp_breaklist1=[]
			temp_breaklist2=[]
			for i in range(len(self.Header_Vars_List)):
				temp_varvaluelist.append(self.Header_Vars_List[i][index])
			if float(self.var_th2_list[index])>0.0:
				temp_breaklist2 = self.find_breaks2(temp_varvaluelist,float(self.var_th2_list[index]))
				for i in range(len(self.Header_break2_List)):
					log("i und index: "+str(i)+" - "+str(index),"debug")
					log("Var: "+self.var_name_list[index]+" -> "+self.Header_Vars_List[i][index],"debug")
					log("schreibe: "+str(temp_breaklist2[i]),"debug")
					self.Header_break2_List[i][index]=temp_breaklist2[i]
					log("\t\t Wert vorletzes mal: "+str(self.Header_break2_List[i-2][index]),"debug")
					log("\t\t Wert jetzt: "+str(self.Header_break2_List[i][index]),"debug")
			del temp_varvaluelist
			del temp_breaklist1
			del temp_breaklist2
Kann sein, dass das Problem wo anders im Code liegt, aber ich fange mal mit dem Teil an. Der Codeteil ist innerhalb einer Klassenfunktion. Das sollte aber nichts an der Sache ändern. Oder vielleicht gerade deswegen?

Meine Frage erst mal ist hier schon was faul?

Das Problem:
- Die Fkt find_breaks2 gibt eine Liste zurück und funktioniert. Die Liste hat x 0 und 1en nach einem bestimmten Muster.
- Die 0en und 1en will ich jetzt in die verschachtelte Liste self.Header_break2_List schreiben. Mit log() schriebe ich immer alle Zwischenstände mit in eine Datei, damit ich den aktuellen Zustand des Scrupts debuggen kannn.
- log("schreibe: "+str(temp_breaklist2),"debug") sagt mir also, dass er den richtigen Wert schreibt. 0 bzw.1. an die Stelle self.Header_break2_List[index].
- Alles scheint zu klappen
- Aber wenn ich die verschachtelte Liste später iterativ auslese ist sie völlig falsch beschrieben.
Diese zwei Zeile sind nun das Problem:

Code: Alles auswählen

					log("\t\t Wert vorletzes mal: "+str(self.Header_break2_List[i-2][index]),"debug")
					log("\t\t Wert jetzt: "+str(self.Header_break2_List[i][index]),"debug")
Die geben mit in meiner debug-Datei nämlich an, dass der Vorletzte geschriebene Wert den gleichen Wert annimmt wie der aktuelle. Wenn also bei i=100 eine 1 geschieben wird und bei i=102 eine 0, dann steht plötzlich bei i=100 auch eine 0 drin, obwohl ich ja nicht neu überschreibe.

Ich hoffe das Problem ist nicht völlig unverständlich... Evtl. ist mehr Code drum herum nötig um das Problem zu erfassen...


Grrrr.....

Bin völlig ratlos. Bin für jeden Hinweis sehr dankbar.
Zuletzt geändert von Anonymous am Freitag 6. August 2010, 13:50, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Code-Tags gesetzt.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Wenn ich den Code sehe ueberkommt mich auch Verzweiflung.
Du willst dir `string formatting`, `enumerate` und PEP 8 anschaun und die `del`s sind ueberfluessig.

Mein erster Gedanke waere, dass du bei Zuweisungen von Listen eigentlich deren Inhalt kopieren willst, das wuerde jedenfalls deine Kopplung erklaeren, schau dir mal die `id` von deinen "verschiedenen" Listen an.
BlackJack

Also mir sieht das etwas zu unübersichtlich aus, insbesondere auch wegen der Zeilenlängen und weil die deshalb "kammartig" umgebrochen werden.

``for i in range(len(obj))`` ist in 99% der Fälle eine unnötige Indirektion -- man kann in Python direkt über die Elemente einer Liste iterieren ohne eine Indexvariable zu bemühen.

Die ``del``-Anweisungen am Ende sind ebenfalls ungewöhnlich. Was immer Du damit bezwecken wolltest -- Du tust es sehr wahrscheinlich nicht.

Insgesamt klingt das so als wenn Du eine Liste wiederverwendest an einer Stelle wo Du eine neue anlegen solltest. Immer dran denken: In Python werden bei Zuweisungen oder Parameterübergaben nie irgendwelche Objekte kopiert, wenn das nicht explizit selbst macht.

Edit: Der Code mal "pythonischer" ohne die Indizes und ohne die `log()`\s:

Code: Alles auswählen

        for index in index_list:
            temp_varvaluelist = [xs[index] for xs in self.Header_Vars_List]
            th2_value = float(self.var_th2_list[index])
            if th2_value > 0.0:
                temp_breaklist2 = self.find_breaks2(temp_varvaluelist,
                                                    th2_value)
                for break2, tmp_break2 in zip(self.Header_break2_List,
                                              tmp_breaklist2):
                    break2[index] = tmp_break2
timbo16
User
Beiträge: 6
Registriert: Freitag 6. August 2010, 13:22

Vielen Dank schon mal fuer das Feedback.

Werde mir `string formatting`, `enumerate` und PEP 8 mal ansehen. Kann gerade aber nichts mehr ausprobieren, weil ich den Rechner gewechselt habe, also spaeter. Dann gucke ich mir noch mal genau die keys der listen an.

Also mein Problem scheint zu sein:
Hier schriebt er den korrekten Wert
self.Header_break2_List[index]=temp_breaklist2
fuer z.B. i=100 und index=4
Im naechsten Iterationsschritt schreibt er wieder den korrekten Wert fuer i=101 und index=4
Wenn ich aber den letzten Wert bei i=100 und index=4 auslese steht da auf einmal nicht mehr der alte korrekte wert, sondern der den ich aktuell in i=100 und index=4 geschrieben habe.
BlackJack

Was steht denn in `self.Header_break2_List` drin? Sind das Listen? Kann es sein dass es nicht verschiedene Listen sind, sondern immer die selbe? Schau Dir doch mal *alle* an und nicht nur das aktuelle und das vorhergehende `i`. Wie sieht der Quelltext aus, der diese Liste(n) erzeugt?
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Nur nochmal zur Verdeutlichung, was BlackJack und Cofi meinen:

Code: Alles auswählen

>>> a = [1, 1, 1, 1, 1]
>>> b = a
>>> b[2] = 5
>>> a
[1, 1, 5, 1, 1]
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
timbo16
User
Beiträge: 6
Registriert: Freitag 6. August 2010, 13:22

BlackJack hat geschrieben:Was steht denn in `self.Header_break2_List` drin? Sind das Listen? Kann es sein dass es nicht verschiedene Listen sind, sondern immer die selbe? Schau Dir doch mal *alle* an und nicht nur das aktuelle und das vorhergehende `i`. Wie sieht der Quelltext aus, der diese Liste(n) erzeugt?
self.Header_Vars_List ist eine Liste (immer die selbe!) mit i Elementen. Jedes Element ist wieder eine Liste bestehend aus 200 Nullen. In dem Code oben will ich nun in jede der i Listen jeweils an der Stelle index einen mit self.find_breaks2() ermittelten Wert der 1 oder 0 betragen kann setzen. An Stellen die nicht in der Schleife "for index in index_list:" auftauchen bleiben die urspruenglich gesetzten 0en. Soweit zu meinem Vorhaben. Eigentlich ganz einfach... Dachte ich...

"Schau Dir doch mal *alle* an..."
Wenn ich alle ansehe dann stehen da falsche Werte drin. Und zwar stehen am Ende fuer alle i die gleichen Werte pro index drin. Also z.B. fuer index=1 stehen nur nullen drin, weil das letzte Ergebnis von self.find_breaks2() fuer diesen index 0 war. Fuer index=2 das gleiche analog. Fuer index=3 aber dann nur einsen, weil das letzte Ergebnis von self.find_breaks2() fuer diesen index eben 1 war.
timbo16
User
Beiträge: 6
Registriert: Freitag 6. August 2010, 13:22

Rebecca hat geschrieben:Nur nochmal zur Verdeutlichung, was BlackJack und Cofi meinen:

Code: Alles auswählen

>>> a = [1, 1, 1, 1, 1]
>>> b = a
>>> b[2] = 5
>>> a
[1, 1, 5, 1, 1]

Ah jetzt checke ich. Vielen Dank das ist ein heisser Hinweis, auch wenn mir das bekannt ist. Kann man/ich aber manchmal leicht vergessen. Darauf werde ich ncoh mal alles durchchecken. Aber erhlich gesagt glaube ich liegt es nicht daran. Denn ich habe solche Zuweisungen doch gar nicht. Ausser eben:
temp_breaklist2 = self.find_breaks2(temp_varvaluelist,float(self.var_th2_list[index]))
Denn die Fkt gibt eine Liste zurueck. Aber deswegen habe ich die Liste
del temp_varvaluelist
am Ende geloescht um bei der naechsten Iteration wieder eine neue Liste zu haben...
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Aber gibt self.find_breaks2 eine neue Liste zurueck? Das del hilft dir in diesem Fall ueberhaupt nicht.
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
timbo16
User
Beiträge: 6
Registriert: Freitag 6. August 2010, 13:22

Rebecca hat geschrieben:Aber gibt self.find_breaks2 eine neue Liste zurueck? Das del hilft dir in diesem Fall ueberhaupt nicht.
Ja nach jedem Iterationschritt

Code: Alles auswählen

for index in index_list:
Soll die Funktion eine komplett neue Liste in temp_breaklist2 schreiben. Funktioniert das so nicht? Also bei meinen Tests schien es zu gehen.
BlackJack

@timbo16: ``del`` löscht keine Objekte sondern Namen! Ob das Objekt dann auch verschwindet, hängt davon ab, ob es noch irgendwo referenziert wird, und ob und wann der "garbage collector" dazu kommt sich das Objekt mal anzusehen wenn es bestimmte Bedingungen erfüllt. Wenn Du also nicht vorhattest die *Namen* ungültig zu machen, dann haben die ``del``\s da nichts zu suchen. Und ich sehe keinen vernünftigen Grund die Namen an der Stelle ungültig zu machen, sie werden beim nächsten Schleifendurchlauf ja sowieso wieder an Objekte gebunden.

Du hast ganz eindeutig die selbe Liste in `self.Header_Vars_List`. Du sagst das ist eine verschachtelte Liste mit vielen Nullen!? Wo und wie erzeugst Du diese Datenstruktur denn? Meiner Vermutung ist, dass dort der Fehler liegt und Du eine Liste mit 200 Nullen erzeugst und dann immer wieder *die selbe* Liste in eine andere Liste einfügst, statt immer *neue* Listen mit 200 Nullen zu erzeugen. Mal ein Beispiel was man da so falsch machen kann:

Code: Alles auswählen

In [574]: a = [[0] * 3] * 4

In [575]: a
Out[575]: [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]

In [576]: a[0][1] = 42

In [577]: a
Out[577]: [[0, 42, 0], [0, 42, 0], [0, 42, 0], [0, 42, 0]]

In [578]: a[0] is a[1]
Out[578]: True
timbo16
User
Beiträge: 6
Registriert: Freitag 6. August 2010, 13:22

BlackJack hat geschrieben:Meiner Vermutung ist, dass dort der Fehler liegt und Du eine Liste mit 200 Nullen erzeugst und dann immer wieder *die selbe* Liste in eine andere Liste einfügst, statt immer *neue* Listen mit 200 Nullen zu erzeugen.
:D :D :D :D :D :D
@BlackJack: Vielen vielen Dank. Das ist der Knackpunkt. Ja genau das mache ich. Und hier liegt der Fehler. Jetzt gehen mir auch alle Lichter auf. Jetzt muss ich schleunigst meinen Laptop holen und das am Code noch mal chekcen. Aber ich bin mir 95% sicher, dass es das jetzt war.

Vielen Dank an alle!!!
:D :D :D :D :D :D

Sorry fuer die vielen Smilies, aber... Ich bin ganz aus dem Hauschen.

PS: Und ich werde mir das mal durchlesen und versuchen umzusetzen: PEP 8
Antworten