Python „Fehler im Code“ Anja Aue | 07.09.16 Softwarefehler Programmierfehler entstehen beim Schreiben des Programmcodes. Der Code entspricht nicht der Syntax der Programmiersprache. Logische Fehler können durch Denkfehler bei der Umsetzung der Aufgabe in ein Programm erzeugt werden. Das Programm wird fehlerfrei ausgeführt, aber das Ergebnis ist nicht korrekt. Laufzeitfehler treten während der Ausführung des Programms auf. Zum Beispiel ist eine Datei nicht an dem angegebenen Speicherort. Java - Einführung | 06.05.15 Seite 2 Syntaxfehler Verstoß gegen die Regeln einer Programmiersprache. Verletzung der Syntax einer Programmiersprache. Ein Ausdruck oder eine Anweisung hat einen falschen Datentyp. Der Interpreter erkennt Syntaxfehler. Sobald ein Syntaxfehler auftritt, wird die Ausführung des Programms abgebrochen. Programmiersprache Python Seite 3 Beispiele Tippfehler bei der Eingabe von Variablennamen oder Schlüsselwörtern. Mischung von numerischen und nicht-numerischen Operatoren. Syntaxfehler in Schleifen oder bedingten Anweisungen. Falsche Übergabe von Parametern. Programmiersprache Python Seite 4 … bei der Eingabe von Code in der Shell Wenn die Eingabe mit der Eingabetaste <Return> abgeschlossen wird, wird der Code auf Syntaxfehler angezeigt. Falls Syntaxfehler vorhanden sind, werden diese direkt in der nächsten Zeile angezeigt. Programmiersprache Python Seite 5 Informationen zu einem Syntaxfehler SyntaxError : EOL while scanning string literal Fehlertyp : Fehlermeldung In dem Beispiel ist ein Syntaxfehler aufgetreten. Die Zeile verstößt gegen die Regeln der Programmiersprache. Nach dem Doppelpunkt folgt eine Beschreibung des Fehlers. In diesem Beispiel ist ein Fehler beim Lesen des Strings aufgetreten. Der String ist nicht korrekt ist nicht korrekt abgeschlossen. Programmiersprache Python Seite 6 … bei der Eingabe von Code in den Editor Programmiersprache Python Seite 7 Erläuterung Das Programm wird mit Run – Run Module (F5) gestartet. Nach dem Start kann das Programm fehlerfrei durchlaufen. Sobald ein Syntaxfehler auftritt, wird die Ausführung abgebrochen. In dem Dialog wird die Fehlermeldung ausgegeben. Die Zeile, die den Fehler verursacht hat, wird farbig markiert. Sobald die Meldung mit OK bestätigt wird, wird die Einfügemarke in die fehlerbehaftete Zeile gesetzt. Programmiersprache Python Seite 8 Fehler: Falsche Einrückung Entsprechend der Einrücktiefe werden Anweisungen dem Kopf einer bedingten Anweisung oder Schleife zugeordnet. Falls die Einrückung nicht korrekt ist, wird der Fehler unexpected indent angezeigt. Programmiersprache Python Seite 9 Fehler: Fehlende Einrückung Jede bedingte Anweisung oder Schleife benötigt mindestens eine Anweisung im Rumpf. Falls diese nicht vorhanden ist, wird der Fehler expected an indented block angezeigt. Programmiersprache Python Seite 10 Logische Fehler Treten bei der Ausführung der Software auf. Falsche Berechnung von Werten. Fehlerhaftes Design der Software. Falsche Nutzung durch den Benutzer. Java - Einführung | 06.05.15 Seite 11 Strategien Testen des Programms mit Hilfe des Debuggers. Der Entwickler kann Zeilen, die in Verdacht stehen einen Fehler zu verursachen, auskommentieren. Falls das Programm anschließend fehlerfrei läuft, ist der Fehler lokalisiert und kann behoben werden. Nach einem erfolgreichen Test wird das Programm gespeichert. Für die Weiterentwicklung wird die Programmdatei kopiert. Falls Fehler nicht gefunden werden, kann auf eine alte fehlerfreie Version zurückgegriffen werden. Java - Einführung | 06.05.15 Seite 12 Debuggen von Code Der Debugger wird in der Shell gestartet (Debug – Debugger). In der Shell wird der Hinweis [Debug ON] angezeigt. Anschließend wird das Programm im Editor gestartet (Run – Run Module). Im Debugger wird die erste Zeile des Codes angezeigt. Java - Einführung | 06.05.15 Seite 13 Debugger Java - Einführung | 06.05.15 Seite 14 Schaltfläche am oberen Rand Go. Ab der auszuführenden Anweisung wird das Programm vollständig oder bis zum nächsten Haltepunkt durchlaufen. Step. Zeilenweise wird das Programm ausgeführt. Over. Das Programm führt die nächste Anweisung aus. Falls eine Funktion aufgerufen wird, wird nicht in diese hineingesprungen. Der Aufruf wird aber ausgeführt. Out. Das Programm durchläuft die aktuelle Funktion vollständig. Quit. Der Debugger wird beendet. Java - Einführung | 06.05.15 Seite 15 Kontrollkästchen zum Anzeigen von Informationen Stack blendet das Textfenster ein und aus. In dem Fenster werden die aktuell auszuführenden Anweisungen angezeigt. Locals zeigt die lokalen Variablen am unteren Rand an. Globals zeigt die globalen Variablen des Programm am unteren Rand an. Source zeigt im Quellcode die aktuell auszuführende Zeile an. Programmiersprache Python Seite 16 Lokale Variablen Variablen, die mit zwei Unterstrichen beginnen, sind von Python vordefinierte Variablen. Die Variable __name__ gibt den Namen des aktuellen Moduls an. Programmiersprache Python Seite 17 Haltepunkte Farbige Markierungen im Code. Die Ausführung eines Programms wird im Debug-Modus an einem Haltepunkt unterbrochen. Programmiersprache Python Seite 18 … setzen Rechter Mausklick auf die gewünschte Anweisung im Editor. Im Kontextmenü wird der Befehl Set Breakpoint ausgewählt. Programmiersprache Python Seite 19 … löschen Rechter Mausklick auf die gewünschte Anweisung im Editor. Im Kontextmenü wird der Befehl Clear Breakpoint ausgewählt. Programmiersprache Python Seite 20 Laufzeitfehler Ausdrücke oder Anweisungen werden vom Programm nicht korrekt ausgewertet. Fehler, die zur Laufzeit des Programms, ein nicht erwünschtes Verhalten des Programms erzeugen. Das Programm kann abstürzen. Java - Einführung | 06.05.15 Seite 21 Beispiele für Laufzeitfehler Division durch Null. Falsche Verwendung von Operanden und / oder Operatoren. Endlosschleife Ein- und Ausgabefehler. Java - Einführung | 06.05.15 Seite 22 Anzeige in der Shell Welcher Laufzeitfehler ist aufgetreten? In diesem Beispiel ist ein TypeError aufgetreten. Programmiersprache Python Seite 23 … in einer Code-Datei verursacht Programmiersprache Python Seite 24 Informationen zum Fehler Dem Wort Traceback folgt die Beschreibung eines Laufzeitfehlers. Dem Wort File folgt die Bezeichnung und Speicherort der Datei, die den Fehler verursacht hat. Dem Wort line folgt die Zeilenangabe, in der der Fehler aufgetreten ist. Durch einen Mausklick mit der rechten Maustaste auf das Wort wird das dazugehörige Kontextmenü geöffnet. Im Kontextmenü wird der Befehl Go to File / Line ausgeführt. Durch den Befehl wird direkt in die fehlerbehaftete Zeile in der dazugehörigen Datei gesprungen. Darunter wird der Fehlertyp und die Fehlermeldung angezeigt. Programmiersprache Python Seite 25 Exception Ausnahme von der Regel. Fehler, die zur Laufzeit des Programms auftreten können. Fehler, die im Code abgefangen und repariert werden können. Java - Einführung | 06.05.15 Seite 26 Informationen im Web https://docs.python.org/3/library/exceptions.html http://www.tutorialspoint.com/python/standard_exceptions.htm http://www.python-kurs.eu/ausnahmebehandlung.php Java - Einführung | 06.05.15 Seite 27 Exception „Division durch Null“ zahlL = 4 zahlR = 0 ergebnis = zahlL / zahlR beispiel\kapitel08_Fehler\zeroDivisionError.py Programmiersprache Python Seite 28 Exception-Handling beispiel\kapitel08_Fehler\zeroDivisionError.py zahlL = 4 zahlR = 0 ergebnis = 0 try: ergebnis = zahlL / zahlR except ZeroDivisionError: print("Eine Division durch Null ist nicht erlaubt.") except: print("Ein unbekannter Fehler ist aufgetreten") else: print("Ergebnis der Division: ", ergebnis) Programmiersprache Python Seite 29 Aufbau try: ergebnis = zahlL / zahlR Versuche except ZeroDivisionError: print("Division durch Null.") Abfangen von speziellen Fehlern except: print("Allgemeiner Laufzeitfehler") Abfangen von allen anderen Fehlern else: print("Kein Fehler") Wenn kein Fehler aufgetreten ist ... finally: print("Egal") Wird immer ausgeführt C++ - Einführung | 06.05.15 Seite 30 Versuche die Anweisungen auszuführen try: ergebnis = zahlL / zahlR Beginn mit dem Schlüsselwort try. Dem Schlüsselwort folgt der Doppelpunkt. In der nächsten Zeile beginnt der, zu dem Befehl gehörende Codeblock. In dem Codeblock können Laufzeitfehler auftreten, müssen aber nicht. Java - Einführung | 06.05.15 Seite 31 Abfangen aller Laufzeitfehler try: ergebnis = zahlL / zahlR except: print("Ein unbekannter Fehler ist aufgetreten") Dem Schlüsselwort except folgt der Doppelpunkt.In der nächsten Zeile beginnt der, zu dem Befehl gehörende Codeblock. Der Codeblock fängt alle Laufzeitfehler ab. Java - Einführung | 06.05.15 Seite 32 Ablauf for zahl in zahlen: try: index = index + 1 ergebnis = zahl / zahlen[index] except: print("Laufzeitfehler") break Java - Einführung | 06.05.15 Versuche die Anweisungen auszuführen Falls ein Fehler auftritt Seite 33 Spezifizierung von Exceptions try: ergebnis = zahlL / zahlR except ZeroDivisionError: print("Eine Division durch Null ist nicht erlaubt.") Dem Schlüsselwort except folgt der Name des abzufangenden Laufzeitfehlers. In diesem Beispiel wird eine Standard-Exception ZeroDivisionError abgefangen. Der Fehler ZeroDivisionError: division by zero wird durch diese Anweisung abgefangen. Java - Einführung | 06.05.15 Seite 34 Erläuterung except ZeroDivisionError except except : : Name : Dem Befehl except kann ein Name eines Laufzeitfehlers folgen, muss aber nicht. Der Name kann sich auf Standard-Exception oder selbstdefinierte Fehler beziehen. Java - Einführung | 06.05.15 Seite 35 Reihenfolge von except-Anweisungen try: ergebnis = zahlL / zahlR Java - Einführung | 06.05.15 Spezialisierung except: print("Ein unbekannter Fehler ist aufgetreten") Generalisierung except ZeroDivisionError: print("Eine Division durch Null ist nicht erlaubt.") Seite 36 Hinweise Jedem Befehl try muss mindesten einmal der Befehl except folgen. Andernfalls wird der Syntaxfehler unexected EOF while parsing angezeigt. Jedem Befehl try wird entsprechend der Einrücktiefe der Befehl except zugeordnet. Der Befehl except ist nur eine Sprungmarke. Jeder dazugehörige Codeblock muss mit einem break abgeschlossen werden. Java - Einführung | 06.05.15 Seite 37 Falls kein Laufzeitfehler auftritt try: ergebnis = zahlL / zahlR else: print("Ergebnis der Division: ", ergebnis) Dem Befehl else folgt der Doppelpunkt. In der nächsten Zeile wird der dazugehörige Codeblock eingerückt angezeigt. Der Codeblock wird nur ausgeführt, wenn keine Laufzeitfehler aufgetreten ist. Der else-Zweig ist optional. Java - Einführung | 06.05.15 Seite 38 Finale ... try: ergebnis = zahlL / zahlR finally: print("… bis zum Index {} durchlaufen.".format(index)) Dem Befehl finally folgt der Doppelpunkt. In der nächsten Zeile wird der dazugehörige Codeblock eingerückt angezeigt. Der Codeblock wird immer ausgeführt, egal ob Fehler aufgetreten sind oder nicht. In diesem Block werden Aufräumarbeiten ausgeführt. Der finally-Zweig ist optional. Java - Einführung | 06.05.15 Seite 39 Hierarchie der Standard-Exceptions BaseException Exception Arithmetic Error ZeroDivision Error TypeError Java - Einführung | 06.05.15 NameError ValueError LookupError IndexError KeyError Seite 40 Exception „ZeroDivisionError“ zahlen = [1, 2, 3, 4, 5, 0, 6, 7, 9, 0] ergebnis = 0 index = 0 for zahl in zahlen: try: index = index + 1 ergebnis = zahl / zahlen[index] except ZeroDivisionError: print("Eine Division durch Null ist nicht erlaubt.") break Java - Einführung | 06.05.15 Seite 41 Exception „ValueError“ Einer Funktion oder Methode werden Argumente übergeben. Das Argument hat den richtigen Datentyp, aber einen fehlerbehaftete Wert. Das Argument kann nicht entsprechend der Konvertierungsfunktion interpretiert werden. Probleme bei der Codierung von Unicode. Java - Einführung | 06.05.15 Seite 42 … bei der Konvertierung von Strings strTemperatur = input("Bitte geben Sie die Temperatur ein: ") try: temperatur = float(strTemperatur) except ValueError: print("Falsche Eingabe. Bitte geben Sie eine Gleitkommazahl ein.") Konvertierung von Strings in Ganz- oder Gleitkommazahlen. Fehlermeldung bei Gleitkommazahlen ValueError: could not convert string to float:. Fehlermeldung bei Ganzzahlen: invalid literal for int() with base 10:. Java - Einführung | 06.05.15 Seite 43 … bei Sequenzen buchstaben = ['a', 'b', 'c', 'd'] try: buchstaben.remove('e') except ValueError: print("Das Element ist in der Liste nicht vorhanden") Elemente, die nicht in der Liste vorhanden sind, sollen gelöscht werden. Fehlermeldung: ValueError: list.remove(x): x not in list Java - Einführung | 06.05.15 Seite 44 Exception „TypeError“ summe = 0 ausgabe = '' try: summe = 5 + 6 ausgabe = 5 + ' + ' + 6 + ' = ' + summe except TypeError: print("Für den Operanden wird der falsche Typ genutzt") Die Variable kann nicht entsprechend der gewünschten Aktion interpretiert werden. In diesem Beispiel wird der Fehler TypeError: unsupported operand type(s) for +: 'int' and 'str' geworfen. Java - Einführung | 06.05.15 Seite 45 Exception „NameError“ Ein Name wird nicht gefunden. Variablen wurden vor der Nutzung nicht deklariert und initialisiert. Methoden werden als Funktionen aufgerufen. Java - Einführung | 06.05.15 Seite 46 … bei Variablen zahlL = 5 try: summe = zahlL + zahlR except NameError: print("Eine der Variablen ist nicht definiert.") In diesem Beispiel wird der Fehler NameError: name 'zahlR' is not defined geworfen. Eine Variable muss vor ihrer Nutzung deklariert und initialisiert werden. Java - Einführung | 06.05.15 Seite 47 … bei nicht definierten Methoden / Funktionen buchstaben = ['a', 'b', 'c', 'd'] try: if count(buchstaben) > 0: del buchstaben[len(buchstaben) - 1] except NameError: print("Die Funktion oder die Variable ist nicht definiert.") In diesem Beispiel wird der Fehler NameError: name 'count' is not defined geworfen. Eine Variable muss vor ihrer Nutzung deklariert und initialisiert werden. Java - Einführung | 06.05.15 Seite 48 Exception „IndexError“ buchstaben = ['a', 'b', 'c', 'd'] lastIndex = len(buchstaben) index = 0 try: while(index <= lastIndex): print(buchstaben[index]) index += 1 except IndexError: print("Die Unter- oder Obergrenze wurde überschritten.") Strings oder Sequenzen können diese Exception werfen. Java - Einführung | 06.05.15 Seite 49 Exception „KeyError“ bei Wörterbüchern farbe = {'rot':255, 'gruen':0, 'blau':0} try: farbton = farbe["gelb"] except KeyError: print("Der Schlüssel ist nicht vorhanden") Java - Einführung | 06.05.15 Seite 50 Exception „IOError“ try: datei = open('adrese.csv', 'r') except IOError: print("Die Datei ... konnte nicht geöffnet werden.") else: strZeile = datei.readline() while strZeile: listeAdresse.append(strZeile.split(';')) strZeile = datei.readline() datei.close() Java - Einführung | 06.05.15 Seite 51 Informationen zu einem Fehler import sys strZahlL = input("Bitte geben Sie eine Ganzzahl ein: ") strZahlR = input("Bitte geben Sie den Vergleichswert ein: ") try: zahlL = int(strZahlL) zahlR = int(strZahlR) except: print("Error-Type: ", sys.exc_info()[0]) print("Error-Wert / Beschreibung: ", sys.exc_info()[1]) print("Traceback: ", sys.exc_info()[2]) Java - Einführung | 06.05.15 Seite 52 Module Zusammenfassung von Codeblöcken zu einem Thema. Zum Beispiel enthält das Modul sys systemspezifische Funktionen. Einige Module wie sys werden automatisch mit der Programmiersprache Python installiert. Andere müssen gesondert installiert werden. Java - Einführung | 06.05.15 Seite 53 … importieren import sys Am Anfang eines Programms können dem Code Module bekannt gemacht werden. Dem Befehl import folgt der Name des Moduls, welches in den Code importiert werden soll. Java - Einführung | 06.05.15 Seite 54 Funktionen etc aus dem Modul nutzen exceptionTupel = sys.exc_info() Der Modulname und die Funktion werden mit Hilfe des Punktoperators verbunden. In dem Modul links vom Punkt ist die Funktion rechts vom Punkt definiert. Jede Funktion oder Methode hat einen eindeutigen Namen. Mit Hilfe des Namens wird die Funktion gestartet. Java - Einführung | 06.05.15 Seite 55 Funktion „exc_info“ exceptionTupel = sys.exc_info() Der Funktion werden keine Argumente übergeben. Die Klammern sind leer. Die Funktion gibt ein Tupel zurück. Das Tupel enthält Informationen zu dem geworfenen Laufzeitfehler. Java - Einführung | 06.05.15 Seite 56 Nutzung eines Index exceptionTupel = sys.exc_info() print("Error-Type: ", exceptionTupel[0]) print("Error-Wert / Beschreibung: ", exceptionTupel[1]) print("Traceback: ", exceptionTupel[2]) Der Index eines Elements in einem Tupel wird durch die eckigen Klammern begrenzt. Das erste Element hat den Index 0. Das letzte Element hat den Index (Länge – 1). Java - Einführung | 06.05.15 Seite 57 Fehlerart exceptionTupel = sys.exc_info() print("Error-Type: ", exceptionTupel[0]) Von welcher Klasse ist der Fehler? Bei einer Fehlermeldung steht die Fehlerart vor dem Doppelpunkt. Jede Standard-Exception ist möglich. Java - Einführung | 06.05.15 Seite 58 Fehlermeldung exceptionTupel = sys.exc_info() print("Error-Type: ", exceptionTupel[1]) Die Fehlermeldung wird nach dem Doppelpunkt. Beschreibung des Fehlers. Java - Einführung | 06.05.15 Seite 59 Traceback import traceback exceptionTupel = sys.exc_info() print("Error-Type: ", exceptionTupel[2]) traceback.print_tb(exceptionTupel[2]) Aus welchen Kontext heraus wurde der Fehler geworfen? Mit Hilfe des Moduls traceback können Informationen in Bezug auf den Kontext ausgegeben werden. In diesem Beispiel wird der Traceback exceptionTupel[2] ausgegeben. Java - Einführung | 06.05.15 Seite 60 Exceptions ignorieren buchstaben = ['a', 'b', 'c', 'd'] try: zeichen = input("Welches Zeichen möchten Sie löschen: ") buchstaben.remove(zeichen) except ValueError: pass except: print("Unbekannter Fehler")) Java - Einführung | 06.05.15 Seite 61 Erläuterung Das Schlüsselwort pass symbolisert eine leere Anweisung. In dem Beispiel wird pass genutzt, um einen Laufzeitfehler abzufangen und nicht zu behandeln. Java - Einführung | 06.05.15 Seite 62