Fehler in Code (Makro für Applikation)

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
rilkar
User
Beiträge: 4
Registriert: Freitag 17. Juni 2011, 09:01

Bin leider ziemlich Python-Neuling. Ich benötige Python um ein paar Makros für eine Applikation zu programmieren, allerdings stürzt bei mir folgende Funktion ständig ab (resp. ich scheine eine Endlos-Schleife programmiert zu haben). Leider habe ich keine Python-Entwicklungs/Debug-Umgebung und muss das ganze nach Trial and Error versuchen.

Die folgende Funktion sollte ein Textfile Zeile für Zeile einlesen, dabei ist nur der erste Buchstabe der Zeile wichtig, der entweder 's' oder 'p' ist. Je nach übergebener 'type'-variable (=s oder p).

Der applikationsspezifische code bewirkt folgendes: die erste Zeile die mit dem Übergabewert (s oder p) übereinstimmt wird als current.layer definiert. Danach werden alle layer die mit dem Übergabewert übereinstimmen aktiviert und alle anderen deaktiviert.

Sieht jemand von euch das Problem?

Code: Alles auswählen

def showLayerType(type) :
	#Shows either all signal or all power planes
	#File "layerInfo.txt" required in \PCB\ folder
	#Type is either 's' or 'p'
	layers=listAllLayers()
	file=open('layerInfo.txt','r')
	i=0
	testline=file.readline()
	setSetting( "display.lock_in_script", 1 )
	while (len(testline)>0):
		if testline[0]=='s' or testline[0]=='p':
			setLayerActive(layers[i],testline[0]==type)
			i=i+1
			testline=file.readline()
			
	file.close()
	#setSetting( "current.layer", layers[nextIndex] )
	setSetting( "display.lock_in_script", 0 )
	return
Gruss & vielen Dank schon im Voraus,
rilkar
Zuletzt geändert von Anonymous am Montag 20. Juni 2011, 15:08, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Code-Tags gesetzt.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Hallo und willkommen im Forum,

Tipp: Was passiert, wenn die Bedingung

Code: Alles auswählen

if testline[0]=='s' or testline[0]=='p':
nicht zutrifft, len(testline) aber größer Null ist?

Im Übrigen ist der Code etwas unorthodox geschrieben. Aber das liegt möglicherweise an dem API Deiner App. Problematisch werden kann allerdings auch, daß Du buildins überschreibst (type und file). Das ist hier wahrscheinlichst kein Problem, aber eine gute Idee kann man das nicht nennen ;-).

HTH
Christian
BlackJack

@rilkar: Bekommst Du die Ausgabe von ``print`` irgendwo in der Anwendung zu sehen? Ein paar Ausgaben an strategischen Stellen kann die Fehlersuche vereinfachen. Du könntest dann zum Beispiel überprüfen ob und wann welcher Code ausgeführt wird. Ich vermute zum Beispiel das die "display.lock_in_script"-Einstellung die Anwendung beziehungsweise die Anzeige "einfriert" bis sie am Ende der Funktion wieder aufgehoben wird. Wenn jetzt also vor der vorletzten Zeile eine Ausnahme die Funktion abbricht, passiert das nie. Könnte es das schon sein? Dann solltest Du mit ``try``/``finally`` dafür sorgen, dass die Anzeige auf jeden Fall entsperrt wird.

Sonstiges: Man braucht am Ende einer Funktion kein ``return`` wenn man nichts zurück gibt.

Dateien sollte man mit der ``with``-Anweisung öffnen, dann werden die auch in jedem Fall wieder geschlossen. Und über Zeilen in Textdateien kann man mit ``for`` iterieren. Damit wird der Code einfacher und kürzer.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Noch eine weitere Anmerkung:

Code: Alles auswählen

setLayerActive(layers[i],testline[0]==type)
Der zweite Parameter ist immer `True`; daher könntest Du das da auch explizit setzen:

Code: Alles auswählen

setLayerActive(layers[i], True)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Hyperion hat geschrieben:Noch eine weitere Anmerkung:

Code: Alles auswählen

setLayerActive(layers[i],testline[0]==type)
Der zweite Parameter ist immer `True`;
Wieso das? type kann 's' oder 'p' sein. Genau wie testline[0], oder? Wenn type also z. B. als 's' gewählt wäre (Validität wird auch nicht geprüft), testline[0] an der Stelle aber 'p' ist, evaluiert der Ausdruck zu False - oder stehe ich auf wieder mal auf dem Schlauch?
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

CM hat geschrieben:
Hyperion hat geschrieben:Noch eine weitere Anmerkung:

Code: Alles auswählen

setLayerActive(layers[i],testline[0]==type)
Der zweite Parameter ist immer `True`;
Wieso das? type kann 's' oder 'p' sein. Genau wie testline[0], oder? Wenn type also z. B. als 's' gewählt wäre (Validität wird auch nicht geprüft), testline[0] an der Stelle aber 'p' ist, evaluiert der Ausdruck zu False - oder stehe ich auf wieder mal auf dem Schlauch?
Stimmt. Mein Fehler :oops:

Aber: Ist das auch so gedacht ist die Frage! Also will der OP ggf. die Layer dort aktivieren oder nicht. Zumindest kann er da noch mal drüber nachdenken ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

rilkar hat geschrieben:Sieht jemand von euch das Problem?
Ein Problem ist, dass dein Code wie eine Mischung aus VB und Java aussieht, aber nicht wie Python. Ich empfehle dringend PEP8 zu lesen.
Ein paar problematische Stellen habe ich mal kommentiert:

Code: Alles auswählen

# der Name sollte show_layer_type oder show_layertype sein. "type" ist der Name eine wichtigen eingebauten Funktion, und diesen Namen überschreibst du hier, so dass die Funktion im lokalen Namensraum unzugänglich wird:
def showLayerType(type) :

        # files öffnet man entweder mit dem with-Statement (s.u.) oder eingeklammert in einen try-except-Block:
	file=open('layerInfo.txt','r')

        # Zeilen einer Textdatei sollte man mit "for line in the_file" einlesen:
	testline=file.readline()
	while (len(testline)>0):

                # sowas testet man so: if something in value1, value2, ... (s.u):
		if testline[0]=='s' or testline[0]=='p':
                        # Wenn man die Zeilen so wie oben beschrieben einliest,
                        # braucht man i nicht.
			setLayerActive(layers[i],testline[0]==type)
			i=i+1

        # das return-Statement braucht man nicht, die Funktion wird auch ohne das beendet und gibt automatisch None zurück:
	return
Pythonischer wäre folgendes:

Code: Alles auswählen

def show_layer_type(which_type) :
    allowed_types = 's', 'p'
    if which_type not in allowed_types:
        raise ArgumentError('Argument muss "%s" lauten.' % '" oder "'.join(allowed_types))
    setSetting("display.lock_in_script", 1)
    with open('layerInfo.txt', 'r') as layer_info:
        layer = iter(listAllLayers())
        for testline in layer_info:
            if testline[0] in allowed_types:
                setLayerActive(next(layer), testline[0] == which_type)
    setSetting("display.lock_in_script", 0)
Zuletzt geändert von pillmuncher am Donnerstag 16. Februar 2012, 05:28, insgesamt 2-mal geändert.
In specifications, Murphy's Law supersedes Ohm's.
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

Noch eine Anmerkung.

Code: Alles auswählen

        layer = iter(listAllLayers())
        for testline layer_info:
            if testline[0] in allowed_types:
                setLayerActive(next(layer), testline[0] == which_type)
Hier wird - wie bei dir - für jede passende Zeile aus layerInfo.txt der jeweils nächste layer aus listAllLayers() verwendet. Ist das wirklich das, was du erreichen möchtest?
In specifications, Murphy's Law supersedes Ohm's.
Antworten