staging.inyokaproject.org

[python] try/except Block: Bei except wird der andere Code nicht wie gewünscht ausgeführt

Status: Gelöst | Ubuntu-Version: Ubuntu 20.04 (Focal Fossa)
Antworten |

san04

Anmeldungsdatum:
19. Januar 2010

Beiträge: 1268

Hallo zusammen,

ich versuche mit Python eine Datei einzulesen, die recht lang ist und einen Header hat. Aus dem Header möchte ich gezielt eine größere Anzahl an Werten auslesen und weiter unten dann Messdaten einlesen, die mit matplotlib geplottet werden sollen. Der Code macht auch noch ein paar andere Dinge, aber ich habe versucht ein Minimalbeispiel (bezieht sich hier vorallem auch auf meine Python-Kenntnisse) zu erstellen. In bestimmten Fällen fehlt der Header, demnach sind keine Werte, sondern nur Messdaten einzulesen und zu plotten. Das wollte ich nachträglich mit einem try-Block abfangen. Prinzipiell funktioniert das, aber wenn der except-Block ausgeführt wird, dann werden die Daten nicht geplottet.

Kann mir vielleicht jemand erklären, warum? (Vielleicht zunächst an meinem Code und dann wie man es in einem 3-Zeiler macht 😉 )

Hier der Code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import sys
import matplotlib.pyplot as plt
import csv
# filename = sys.argv[1]
filename = "data1.csv"
x,y = [],[]
CycleLineNumber = 0
Datadict = {
    "test":[0],
    "header":[0]
}
### Daten einlesen ###
with open(filename, newline='') as csvfile:
    reader = csv.reader(csvfile, delimiter=',')
    for i,row in enumerate(reader):
        if(row[0] in Datadict): # Schreibe Daten in Datadict
            Datadict[row[0]] = [row[1]]
            Datadict[row[0]].append(row[2])
        if(CycleLineNumber != 0): # Falls die Zeile mit "Cycle" gefunden wurde: Lies Daten ein
            x.append(int(row[3]))
            y.append(int(row[4]))
        if(row[0] == "Cycle"): # Finde Zeilennummer mit "Cycle" (danach beginnt Messreihe)
            CycleLineNumber = i

###  Plot  ###
fig, ax = plt.subplots()
plt.plot(x,y)
Datalist = []
try:
    for i,Data in enumerate(Datadict): # Schreibe Daten holprig in Datenliste um sie zu plotten
        Datalist.append(Data)
        Datalist[i] += ": "
        for j, SubData in enumerate(Datadict[Data]):
            Datalist[i] += Datadict[Data][j]
    for i,element in enumerate(reversed(Datalist)): # Schreibe Daten in Grafik
        ax.text(0.98, 0.05+i*0.04,"%s" % (element),
                verticalalignment='bottom', horizontalalignment='right',
                transform=ax.transAxes,
                color='slategrey', alpha=.5, fontsize=10)
except:
    print("Daten nicht geschrieben")
plt.show()

Hier die Datei "data.csv" (inkl. Header, hier funktioniert der Plot):

00901,test,0050,DataLength
"header",0000000040,"lines"
"test",1.85,"M"
"Cycle","Value1","Value2","Value3","Value4"
1,00:00:01,0000001201, 0,          1
1,00:00:01,0000001201, 1,          2

Hier die Datei "data1.csv" (ohne Header, hier wird except ausgeführt, aber dann erscheint der Plot nicht korrekt)

"Cycle","Value1","Value2","Value3","Value4"
1,00:00:01,0000001201, 0,          1
1,00:00:01,0000001201, 1,          2

NORACSA

Anmeldungsdatum:
31. Januar 2010

Beiträge: 182

Welcher Befehl sollte denn hier welche Exception werfen?

san04

(Themenstarter)

Anmeldungsdatum:
19. Januar 2010

Beiträge: 1268

Wenn ich den try-Block weglasse und die Datei data1.csv (die keinen Header hat) plotten will kommt der folgende Fehler:

testplot.py|34 error| in <module> Datalist[i] += ": " TypeError: can only concatenate str (not "    int") to str  

Ich habe an der Stelle gar nicht weiter recherchiert woher genau der Fehler kommt. Falls hier ein Fehler kommt soll der ganze Block einfach übersprungen werden und nur die Messdaten geplottet werden. Das funktioniert aber nicht...

NORACSA

Anmeldungsdatum:
31. Januar 2010

Beiträge: 182

san04 schrieb:

Wenn ich den try-Block weglasse und die Datei data1.csv (die keinen Header hat) plotten will kommt der folgende Fehler:

testplot.py|34 error| in <module> Datalist[i] += ": " TypeError: can only concatenate str (not "    int") to str  

Ich habe an der Stelle gar nicht weiter recherchiert woher genau der Fehler kommt. Falls hier ein Fehler kommt soll der ganze Block einfach übersprungen werden und nur die Messdaten geplottet werden. Das funktioniert aber nicht...

OK, das ist leicht zu lösen. Da musst du

1
Datalist[i]=f"{Datalist[i]}: "

schreiben!

Try-Except-Blöcke sind dazu da um erwartete Exceptions abzufangen und nicht um über Programmierfehler drüberhüpfen zu können.

noisefloor Team-Icon

Anmeldungsdatum:
6. Juni 2006

Beiträge: 29567

Hallo,

du benutzt scheinbar - also zumindest lt. Shebang - Python 2. Das ist seit dem 1.1.2020 EOL. Die solltest Python 3 benutzen. if ist in Python ein Statement, keine Funktion → da müssen keine Klammern hinter. Variablen schreibt man in Python klein_mit_unterstrich, nicht mit Großbuchstaben am Anfang.

Nie nackte try..except benutzen, weil du damit alles Fehler weg bügelst, inkl. Programmierfehler. Und genau das hast du ja hier gemacht, wie NORACSA schon erklärt hat.

Gruß, noisefloor

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13242

Mal ganz generell: Exceptions sind für Fehlerbehandlung da. Du hast hier aber wohl eher den Fall, dass Du zwei zulässige Eingaben hast (Dateien mit und ohne Header). Das müsste man dann durch den normalen Programmfluss erkennen und entsprechend behandeln. Algorithmisch würde ich das wohl so machen, dass ich die Eingabe zeilenweise lese und mir alles merke, bis ich auf die Kopfzeile (den Datensatz mit "Cycle" in Deinem Beispiel; das Kriterium kann auch ein anderes sein) treffe. Danach wird dann alles geplottet.

sebix Team-Icon

Ehemalige

Anmeldungsdatum:
14. April 2009

Beiträge: 5584

rklm schrieb:

Mal ganz generell: Exceptions sind für Fehlerbehandlung da.

In Python sind Exceptions sehr billig und sind viel ueblicher als in anderen Sprachen, insbesondere auch fuer den die ueblichen Faelle. Hier ist es guter Programmierstil, anstatt zu pruefen ob die Eingabe syntaktisch ok ist, einfach versuchen zu interpretieren und im Fehlerfall eine Exception zu erwarten.

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11278

Wenn ich das richtig verstehe, reicht doch eigentlich sowas: https://gist.github.com/seahawk1986/34d6231f7ff9fc643d31a9e4e6cefcf2

san04

(Themenstarter)

Anmeldungsdatum:
19. Januar 2010

Beiträge: 1268

Vielen Dank für die vielen hilfreichen Rückmeldungen, ich hab wieder einiges gelernt. 👍

Auch vielen Dank für den vollständigen Code, den werde ich mir nochmal genauer anschauen seahawk1986.

Antworten |