Fehlermeldung: Newbie benötigt Hilfe

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
DeBobbes
User
Beiträge: 15
Registriert: Donnerstag 30. August 2007, 06:56

Bin absoluter Beginner mit Null-Ahnung über Python-Skripts. Habe ein Skript vom Kollegen (den ich derzeit nciht erreichen kann) erhalten, den ich nur anzuwenden bräuchte. Erhalte jedoch folgende Fehlermeldung:
Traceback (most recent call last):
File "R:\Projekte\NEWAL-NET\Weberslinden 07_2006\Class-VP\CHROM\GC-Solution\gc_berechnung_Weberslinden.py", line 226, in <module>
files0 = os.listdir(os.path.join(pfad, gas))
WindowsError: [Error 2] Der angegebene Pfadname ist ungültig: '/R:/Projekte/NEWAL-NET/Weberslinden 07_2006/Class-VP/CHROM/GC-Solution\\CH4/*.*'
Wer hat eine Idee, ob es wirklich die falsche Pfadangabe ist (verstehe die Ausgabe "\\CH4/*.*" nicht) oder ob im Code ein fehler steckt.
Bin für jeden Tipp dankbar.
BlackJack

Ich würde mal auf das '*.*' tippen. Wo kommt das her? Übergibst Du dem Programm irgendwelche Argumente an der Kommandozeile oder ist das in einer Konfigurationsdatei eingetragen?
DeBobbes
User
Beiträge: 15
Registriert: Donnerstag 30. August 2007, 06:56

Wie gesagt: ich habe keine Ahnung. Ein *.* kommt im Code nicht vor, das habe ich bereits gecheckt.
Poste hier mal das gesamte Script:

http://paste.pocoo.org/show/3159/

Edit (BlackJack): Skript ausgelagert
BlackJack

Liegt's vielleicht an dem allerersten '/' in dem Dateinamen? Vor dem Laufwerksbuchstaben sollte der doch eigentlich nichts zu suchen haben, oder?
DeBobbes
User
Beiträge: 15
Registriert: Donnerstag 30. August 2007, 06:56

Habe ich auch schon gedacht und ausprobiert. Ändert aber nichts an der Fehlermeldung
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Schlag mich T**, aber sag ma, bekommst du die gleiche Fehlermeldung, wenn du folgenden Pfad angibst:

Code: Alles auswählen

path = r'R:\Projekte\NEWAL-NET\Weberslinden 07_2006\Class-VP\CHROM\GC-Solution'

MfG EnTeQAk
DeBobbes
User
Beiträge: 15
Registriert: Donnerstag 30. August 2007, 06:56

Die Fehlermeldung ändert sich zu:
Traceback (most recent call last):
File "R:\Projekte\NEWAL-NET\Weberslinden 07_2006\Class-VP\CHROM\GC-Solution\gc_berechnung_Weberslinden.py", line 226, in <module>
files0 = os.listdir(os.path.join(pfad, gas))
WindowsError: [Error 2] Das System kann den angegebenen Pfad nicht finden: 'R:/Projekte/NEWAL-NET/Weberslinden 07_2006/Class-VP/CHROM/GC-Solution\\CH4/*.*'
>>>
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Wie rufst du das Programm genau auf? Das *.* muss ja irgentwo herkommen.
DeBobbes
User
Beiträge: 15
Registriert: Donnerstag 30. August 2007, 06:56

Python Datei mit rechter Maustaste und "Edit with Idle". Start des Programms durch drücken der Taste F5
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Das "*.*" fügt os.listdir() hinzu, das passt schon.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
BlackJack

Ich weiss der Quelltext ist nicht von Dir, aber hier sind noch ein paar Anmerkungen zum Programm:

Es gibt Zeilen die länger als 80 Zeichen sind und oft ist kein Leerzeichen nach Kommata.

Die Funktionen aus dem `string`-Modul, die verwendet werden sind alle veraltet. Stattdessen sollte man die entsprechenden Methoden auf den Zeichenketten verwenden.

``map(None, X, Y)`` ist ein sehr ungewöhnlicher Ausdruck, wenn man ``zip(X, Y)`` meint. Die beiden Ausdrücke verhalten sich unterschiedlich wenn `X` und `Y` verschieden lang sind, aber das wird in `lineareRegression()` ja gleich am Anfang ausgeschlossen. Das `map()` sollte man durch `zip()` oder `itertools.izip()` ersetzen. Die Funktion könnte man auch in zwei aufteilen. Die Namen `Var_a` und `Var_b` werden berechnet aber nicht verwendet.

`findePeakID()` ist zu "quelltextlastig", es ist zu viel "copy'n'paste" Quelltext, den man in eine Datenstruktur stecken kann. Hier mal exemplarisch und ungetestet für 'CH4':

Code: Alles auswählen

PEAK_IDS = {'CH4': ((16.05, 'EG1','-9999'),
                    (19.05, 'EG2','-9999'),
                    (34.05, 'EG3','-9999'),
                    (37.05, 'EG4','-9999'),
                    (52.05, 'EG5','-9999'),
                    (55.05, 'EG6','-9999'),
                    (70.05, 'EG7','-9999'),
                    (73.05, 'EG8','-9999'),
                    (88.05, 'EG9','-9999'),
                    (91.05, 'EG10','-9999'),
                    (106.05, 'EG11','-9999'),
                    (109.05, 'EG12','-9999'),
                    (124.05, 'EG13','-9999'),
                    (127.05, 'EG14','-9999'),
                    (142.05, 'EG15','-9999'),
                    (145.05, 'EG16','-9999'),
                    (160.05, 'EG17','-9999'),
                    (163.05, 'EG18','-9999'),
                    (4.05, '1.1', 'EG1'),
                    (7.05, '2.1', 'EG2'),
                    (10.05, '3.1', 'EG1'),
                    (13.05, '4.1', 'EG2'),
                    (22.05, '1.2', 'EG3'),
                    (25.05, '2.2', 'EG4'),
                    (28.05, '3.2', 'EG3'),
                    (31.05, '4.2', 'EG4'),
                    (40.05, '1.3', 'EG5'),
                    (43.05, '2.3', 'EG6'),
                    (46.05, '3.3', 'EG5'),
                    (49.05, '4.3', 'EG6'),
                    (58.05, '1.4', 'EG7'),
                    (61.05, '2.4', 'EG8'),
                    (64.05, '3.4', 'EG7'),
                    (67.05, '4.4', 'EG8'),
                    (76.05, '1.5', 'EG9'),
                    (79.05, '2.5', 'EG10'),
                    (82.05, '3.5', 'EG9'),
                    (85.05, '4.5', 'EG10'),
                    (94.05, '5.1', 'EG11'),
                    (97.05, '6.1', 'EG12'),
                    (100.05, '7.1', 'EG11'),
                    (103.05, '8.1', 'EG12'),
                    (112.05, '5.2', 'EG13'),
                    (115.05, '6.2', 'EG14'),
                    (118.05, '7.2', 'EG13'),
                    (121.05, '8.2', 'EG14'),
                    (130.05, '5.3', 'EG15'),
                    (133.05, '6.3', 'EG16'),
                    (136.05, '7.3', 'EG15'),
                    (139.05, '8.3', 'EG16'),
                    (148.05, '5.4', 'EG17'),
                    (151.05, '6.4', 'EG18'),
                    (154.05, '7.4', 'EG17'),
                    (157.05, '8.4', 'EG18'),
                    (166.05, '5.5', 'EG17'),
                    (169.05, '6.5', 'EG18'),
                    (172.05, '7.5', 'EG17'),
                    (175.05, '8.5', 'EG18'))}


def find_peak_id(gas, r):
    for lower_limit, time, id_ in PEAK_IDS[gas]:
        if r > lower_limit and r < lower_limit + 0.4:
            return (time, id_)
    return ('-1111', '-1111')
Für weitere Gase braucht man jetzt nur noch die "Tabelle" in `PEAK_IDS` erweitern. Man könnte die Daten auch in Textdateien auslagern oder aus einer Datenbank holen. Das ist viel flexibler als alles hart in ``if``-Abfragen zu kodieren. Ausserdem könnte man eine Funktion schreiben, die die Daten überprüft, zum Beispiel ob sich Bereiche überlappen. Beim eintippen von solchen Zahlenkolonnen passiert schonmal hin und wieder ein Fehler, den man so entdecken könnte.

Die Dateinamenverarbeitung ab Zeile 226 sieht sehr abenteuerlich aus. Das "rumgeslice" mit "magischen" Positionen, und Zählen von Substrings sieht recht kompliziert aus, wenn man sich dann anschaut wie die Dateien später geöffnet werden, sieht es aber so aus, als wenn die einfach die Form 'WEBE???.txt' haben, wobei das die '???' für eine beliebige Zeichenkette stehen, die eine "Flussnummer" darstellen!? So eine Liste mit Dateinamen inklusive Pfad dorthin sollte sich mit einer Zeile erstellen lassen:

Code: Alles auswählen

    files1 = glob.glob(os.path.join(pfad, gas, 'WEBE???.txt'))
Logische Zeilenfortsetzungen mit dem '\' am Zeilenende sind übrigens nicht nötig solange noch schliessende Klammern ausstehen.

Wenn man keine Liste mit Zahlen benötigt, sollte man `xrange()` anstelle von `range()` verwenden.

Das einlesen der Datei hätte ich wohl einem Iterator über die Datei (``fin_iter = iter(fin)``) und `islice()` aus dem `itertools`-Modul gemacht. Dann hätte man zum Schluss einfach eine ``for``-Schleife über die restlichen Zeilen machen können.

Die ``elif``-Abfrage in Zeile 322 sollte besser nie zutreffen, weil das Programm sonst in der nächsten Zeile mit einem `NameError` abbricht. Was soll das einsame `as` dort denn bezwecken!?

Eine ``if``/``elif`` bei der Zweige nur aus einem ``pass`` bestehen, kann man immer so umschreiben, dass man diesen Zweige eliminiert.

Den Quelltext von Zeile 354-374 kann man etwas logischer strukturieren und verkürzen. `check` kann man loswerden indem man eine ``for``-Schleife schreibt und diese verlässt, wenn der Test entsprechend ausfällt. Um zu testen ob eine 0 in einer Liste enthalten ist, braucht's auch keine explizite Schleife, das geht mit dem Ausdruck ``0 in liste``. Beide Zweige in der Abfrage in der inneren Schleife testen ob der Wert am aktuellen Index 0 ist, diese Entscheidung kann man also vorziehen. Und die zweite Bedingung beim ``elif`` ist genau das Gegenteil von der Bedingung im ``if``, braucht also nicht explizit überprüft werden. Beide Zweige enden auch mit der gleichen Zeile, die kann man auch herausziehen.

Code: Alles auswählen

    for counter in xrange(100):
        if 0 not in h:
            break
        print counter
        for i in xrange(len(h)):
            if h[i] == 0:
                if i <= 1:
                    neuer_peak = i + 2
                else:
                    neuer_peak = i - 2
                h[i] = h[neuer_peak]

Ab Python 2.5 kann man das Ganze noch etwas verkürzen:

Code: Alles auswählen

    for counter in xrange(100):
        if 0 not in h:
            break
        print counter
        for i in xrange(len(h)):
            if h[i] == 0:
                h[i] = h[i + (2 if i <= 1 else -2)]
Vom Algorithmus her wäre es vielleicht schlauer als Abbruchbedingung zu testen ob sich `h` im letzten Schleifendurchlauf verändert hat. Wenn das nicht der Fall war, dann wird es das auch in den folgenden nicht mehr tun und man kann aufhören.

Code: Alles auswählen

    old_zeroes = h.count(0)
    while True:
        new_zeroes = h.count(0)
        if old_zeroes == new_zeroes:
            break
        old_zeroes = new_zeroes
        for i in xrange(len(h)):
            if h[i] == 0:
                h[i] = h[i + (2 if i <= 1 else -2)]
`eichgasFlaechen` nach `h` zu kopieren und das Ergebnis wieder zurück zu kopieren scheint übrigens überflüssig. Man hätte `h` auch einfach an das gleiche Objekt binden können.

Ab Zeile 380 hätte man auch direkt über die Elemente von `eichgasFlaechen` iterieren können statt den Umweg über einen Index zu nehmen. Und man sollte nie ein reines ``except:`` verwenden, ohne eine konkrete Ausnahme anzugeben. Sonst werden dort einfach *alle* Ausnahmen behandelt, was die Fehlersuche enorm erschweren kann. Der Kommentar ist ja schon fast richtig: `ZeroDivisionError` heisst das Ding was da hingehört.

Bei der Regressionsberechnung ab Zeile 403 hätte man auch gleich über `ApeakRet` und `ApeakPPM` iterieren können. Das `range()` hier ist noch "schlimmer" als `range(len(irgendwas))` weil hier eine 8 hart kodiert ist von der man a) nicht weiss woher diese Zahl kommt, und die b) falsch ist sobald sich die Grösse von den Datenstrukturen mal ändern sollte. Dann darf man das ganze Programm nach 8en durchsuchen, wo man bei jeder dann entscheiden muss ob es eine 8 ist, die geändert werden muss oder nicht.

Die importierten Module `sys` und `math` werden nicht benutzt.

Man sollte so wenig wie möglich auf Modulebene machen. Den Hauptteil kann man in eine Funktion, zum Beispiel `main()`, stecken und mit folgendem Idion starten, wenn der Quelltext als Programm gestartet wurde:

Code: Alles auswählen

if __name__ == '__main__':
    main()
Das hat den Vorteil, dass man den Quelltext auch als Modul importieren kann ohne dass das Programm ausgeführt wird und man so Funktionen einzeln austesten oder von anderen Programmen aus benutzen kann. Ausserdem fällt so auf, wenn man globale Namen statt Argumentübergabe verwendet. So etwas kann auch aus versehen ganz schnell passieren, wenn man in einer Funktion Namen verwendet, die auch auf Modulebene existieren. Wenn man nicht aufpasst hat man ganz schnell mal ein Objekt ausserhalb der Funktion verändert, was man gar nicht wollte.

Den Hauptteil sollte man auch auf mehrere Funktionen aufteilen. Der ist so etwas lang.
DeBobbes
User
Beiträge: 15
Registriert: Donnerstag 30. August 2007, 06:56

Woran kann es denn liegen, dass das Verzeichnis nicht gefunden wird, obschon es existiert? Oder wird vielmehr eine Datei in dem angegebenen Verzeichnis nicht geunden, die möglichweise nciht dem geforderten Format entspricht?
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

EnTeQuAk hat geschrieben:Schlag mich T**, aber sag ma, bekommst du die gleiche Fehlermeldung, wenn du folgenden Pfad angibst:
Huch? Ist "tot" jetzt schon auf dem Schäuble-Index?
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

birkenfeld hat geschrieben:
EnTeQuAk hat geschrieben:Schlag mich T**, aber sag ma, bekommst du die gleiche Fehlermeldung, wenn du folgenden Pfad angibst:
Huch? Ist "tot" jetzt schon auf dem Schäuble-Index?
Man weiß ja nie :=)

Habs aber nur aus langer Weile gemacht :D


Aber nun wieder zurück zum Thema:
BlackJack

Gibt's das Verzeichnis denn *wirklich*? Was passiert wenn Du den Pfad per Copy'n'Paste in den Explorer übernimmst?
DeBobbes
User
Beiträge: 15
Registriert: Donnerstag 30. August 2007, 06:56

kopiere ich den String in den Explorer, wird das Verzeichnis auch angezeigt
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Was mich dann weiterhin verwirrt, ist warum die Pfadangabe mit Slash-/Backslash gemixt angezeigt wird.

Kannst du uns vielleicht nochmal deinen bereits veränderten Quellcode in einen Paste (http://paste.pocoo.org) posten, damit wir eventuell nochmal drüber schauen können?


Weiterhin die Frage, welchen der genannten Pfade hast du im Explorer ausprobiert?

Code: Alles auswählen

R:\Projekte\NEWAL-NET\Weberslinden 07_2006\Class-VP\CHROM\GC-Solution
oder

Code: Alles auswählen

R:/Projekte/NEWAL-NET/Weberslinden 07_2006/Class-VP/CHROM/GC-Solution\\CH4/
(was eigentlich *nicht* funktionieren sollte)


MfG EnTeQuAk
BlackJack

Bei Deiner zweiten Pfadangabe ist ein Backslash zu viel, das ist im Original auch nur einer, wird aber mit `repr()` dargestellt.
Antworten