Lister - Programmidee

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.
Gary123456
User
Beiträge: 318
Registriert: Dienstag 26. Februar 2013, 18:39

Du bentutz bei raw-Strings noch immer doppelte Backslashes. Die dürfen dort nicht hin.
Der Code funkt ohne nicht. Das gleiche Problem hatte ich schon in einer anderen Programmiersprache (XPROFAN).

Code: Alles auswählen

import os
import sha

def shasum(filepath, blocksize = 1024 * 1024): 
    h = sha.new()
    with open(filepath, "rb") as f:
        try:
            while True:
                part = f.read(blocksize)
                if not part:
                    break
                h.update(part)
        finally:
            f.close()   
        return h.hexdigest()

Ordner_Liste = [r"C:\\"]
                
Schreibgeschuetzt = [r"C:\\hiberfil.sys", r"C:\\pagefile.sys"]

with open("test.txt", "w") as textdatei:
    try:
        for path in Ordner_Liste:
            for entry in os.listdir(path):
                textdatei.write(os.path.join(path, entry) + "\n")
                textdatei.write(str(os.path.getsize(os.path.join(path, entry))/1024)+ " " + "MB")

                if os.path.isfile(os.path.join(path, entry)) == True:
                    for geschuetzt in Schreibgeschuetzt:
                        if os.path.join(path, entry) != geschuetzt:    
                            textdatei.write(shasum(os.path.join(path, entry)))
                        else:
                           pass
                            
                else:
                    pass
                textdatei.write("")

    except OSError:
        textdatei.write("Datei existiert nicht oder ist unzugänglich!")
1. Wie kann ich eine Datei überspringen? Gibt es ein spezielles Schlüsselwort, dass die for Schleife um 1 erhöht. Den entry oder path um 1 zu erhöhen geht logischerweise nicht.
2. Kann man diesen Code noch vereinfachen?
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Gary123456 hat geschrieben:Der Code funkt ohne nicht. Das gleiche Problem hatte ich schon in einer anderen Programmiersprache (XPROFAN).
Dinge aus einer Programmiersprache unkritisch in eine andere zu übertragen ist keine gute Idee. Was glaubst du denn, was das einleitende r in der Stringdefinition r"C:\\hiberfil.sys" bewirkt?

Zu deinem Problem mit der for-Schleife: http://docs.python.org/2/tutorial/contr ... s-on-loops
Zuletzt geändert von /me am Mittwoch 24. April 2013, 14:16, insgesamt 1-mal geändert.
Gary123456
User
Beiträge: 318
Registriert: Dienstag 26. Februar 2013, 18:39

Fakt ist, dass das ohne einfachen \ nicht funktioniert. Was soll ich machen?
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Gary123456 hat geschrieben:Fakt ist, dass das ohne einfachen \ nicht funktioniert. Was soll ich machen?
Lernen. Lernen wie ein String wirklich aussieht. Lernen, wie man sinnvolle Fehlerbeschreibungen jenseits von "geht nicht" angibt.

Schau dir die Darstellung des Strings an. Das ist in IDLE eine Sache von Sekunden.

Code: Alles auswählen

>>> r"C:\\hiberfil.sys"
'C:\\\\hiberfil.sys'
Du siehst hier ganz eindeutig, dass du zwei Backslashes hast und Windows-Pfade haben halt nur einen als Trenner.
Gary123456
User
Beiträge: 318
Registriert: Dienstag 26. Februar 2013, 18:39

Mit dieser Zeile:

Code: Alles auswählen

Ordner_Liste = [r"C:\"]
will der Code nicht funktionieren. Es scheint so, als ob er die Klammer (hinten) auch als String definiert, da sie als grün gekennzeichnet ist. Was Du sagst, weiss ich. Jedoch listet es mit dem zurzeitigen Code mit \\ korrekt auf.

wenn ich die Zeile so ummändere:

Code: Alles auswählen

Ordner_Liste = [r"C:"]
Listet es alle .py Dateien auf (nicht unter C:\!)

auch wenn ich das mache:

Code: Alles auswählen

Ordner_Liste = ["C:\"]
ist die letzte Klammer grün (-> String) -> Fehlermeldung

Beweis:
Bild
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Gary123456 hat geschrieben:Mit dieser Zeile:

Code: Alles auswählen

Ordner_Liste = [r"C:\"]
will der Code nicht funktionieren.
Ein raw string darf nicht mit einem einzelnen Backslash enden.
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

Ich würde ja sagen, das ist ein Bug in Python, aber ich weiß auch nicht, ob das Problem schon in entsprechenden Kreisen diskutiert wurde und für gut befunden.
Der Parser von Python (also der Teil, der Pythoncode als Text nimmt und ihn in Einheiten wie Zahlen, Klammern, Strings, usw. zerhackt) kennt keine Rawstrings. Daher interpertiert er, egal ob ein r davor steht oder nicht alle \" als Sonderzeichen und erkennt damit das Stringende nicht. Also, falls das letzte Zeichen eines Strings \ ist, darf man keinen Raw-String benutzen. Korrekt wäre also ["C:\\"].
BlackJack

@Sirius3: Wurde schon diskutiert — kann mich daran erinnern, dass das ein paar mal in der Newsgroup aufkam als ich da noch mitgelesen habe — und wurde zwar nicht als Feature verkauft, aber auch nicht als Bug dargestellt. Und dort haben (zumindest damals) einige Python-Devs dort mitgelesen und -diskutiert.
Benutzeravatar
kevind
User
Beiträge: 71
Registriert: Montag 22. Oktober 2012, 20:23
Wohnort: /dev/null

Also ich weiss ja nicht aber mit dem

Code: Alles auswählen

hiberfil.sys
würde ich eher vorsichtig sein.

Sorry ist vl. etwas OT...
Gary123456
User
Beiträge: 318
Registriert: Dienstag 26. Februar 2013, 18:39

@kevind) Ich weiß ganz genau was die macht, warum sie da ist etc. Naja löschen wär ja ned so praktisch.

@Sirius3) Also stimmt meins doch?
1. Wie kann ich eine Datei überspringen? Gibt es ein spezielles Schlüsselwort, dass die for Schleife um 1 erhöht. Den entry oder path um 1 zu erhöhen geht logischerweise nicht.
2. Kann man diesen Code noch vereinfachen?
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Gary123456 hat geschrieben:@Sirius3) Also stimmt meins doch?
Nein, tut es nicht. Wenn ein String mit einem Backslash endet, dann solltest du keine raw strings verwenden. Wenn nicht, dann kannst du raw strings verwenden, solltest dann aber wenn du innerhalb des Strings einen Backslash haben willst auch nur einen angeben und nicht zwei..
webspider
User
Beiträge: 485
Registriert: Sonntag 19. Juni 2011, 13:41

Raw-Strings sollte man sowieso nur in regulären Ausdrücken verwenden. Einen Schleifendurchgang kann man mit continue abbrechen, aus der Schleife selbst springt man mit break raus. Und os.walk() bietet sich ebenfalls an zum Durchwandern von Ordnern.
Gary123456
User
Beiträge: 318
Registriert: Dienstag 26. Februar 2013, 18:39

Nein, tut es nicht. Wenn ein String mit einem Backslash endet, dann solltest du keine raw strings verwenden. Wenn nicht, dann kannst du raw strings verwenden, solltest dann aber wenn du innerhalb des Strings einen Backslash haben willst auch nur einen angeben und nicht zwei..
Ich werd verrückt. Ohne raw_strings das gleiche Problem:

Code: Alles auswählen

Ordner_Liste = ["C:\"]

Code: Alles auswählen

import os
import sha

def shasum(filepath, blocksize = 1024 * 1024): 
    h = sha.new()
    with open(filepath, "rb") as f:
        try:
            while True:
                part = f.read(blocksize)
                if not part:
                    break
                h.update(part)
        finally:
            f.close()   
        return h.hexdigest()

Ordner_Liste = ["C:\\"]
                
Schreibgeschuetzt = [r"C:\\hiberfil.sys", r"C:\\pagefile.sys"]

with open("test.txt", "w") as textdatei:
    try:
        for path in Ordner_Liste:
            for entry in os.listdir(path):
                textdatei.write(os.path.join(path, entry) + "\n")
                textdatei.write(str(os.path.getsize(os.path.join(path, entry))/1024)+ " " + "MB")

                if os.path.isfile(os.path.join(path, entry)) == True:
                    for geschuetzt in Schreibgeschuetzt:
                        if os.path.join(path, entry) != geschuetzt:    
                            textdatei.write(shasum(os.path.join(path, entry)))
                        else:
                            continue                                                      
                else:
                    pass
                textdatei.write("")

    except OSError:
        textdatei.write("Datei existiert nicht oder ist unzugänglich!")
    except IOError:
        textdatei.write("Keine Berechtigungen!") 
Warum springt es micht zum nächsten entry? Oder ist das except Schuld?
webspider
User
Beiträge: 485
Registriert: Sonntag 19. Juni 2011, 13:41

continue hat nur eine Wirkung auf die nächstgelegene Schleife, die äußere bleibt also ungerührt davon. Daher solltest du Refactoring betreiben und sowas auf Funktionen aufteilen bis dir die Logik klar und offensichtlich wird.
xeike
User
Beiträge: 83
Registriert: Donnerstag 28. Februar 2013, 09:58

Gary123456 hat geschrieben:Ich werd verrückt. Ohne raw_strings das gleiche Problem:
Ja, die Backslashes leiten besondere Zeichen ein. \" heißt so viel wie: Füge das Zeichen '"' mit in die Zeichenkette ein.

Wenn du Linux, BSD oder MacOS X hättest, dann würde dein Verzeichnis vielleicht "/home/gary" (oder so ähnlich) lauten und du hättest das Problem mit dem Backslash nicht. :wink:

Edit: Geht eigentlich

Code: Alles auswählen

pfad = os.path.join("C:", "")
unter windows?

Warum springt es micht zum nächsten entry? Oder ist das except Schuld?
Wie soll es denn aussehen?

Vielleicht hilft eine Variable "brich_schleife_ab" oder die "break"-Anweisung?

Xe
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

@Gary123456: also an Deinem Code ist noch so einiges nicht in Ordnung. Teile Deinen Code in Funktionen auf, die eine genau bestimmte Aufgabe haben, zum Beispiel eine Funktion, die testet ob die als Parameter übergebene Datei in einer Liste von anderen Dateien vorkommt, dazu gibt es im Übrigen eine passende Funktion: »os.path.samefile«, da wegen Deiner Doppelbackslashes in Rawstrings ein direkter Vergleich immer Fehlschlägt. Dann willst Du wahrscheinlich, dass falls eine nichtlesbare Datei in einem Ordner ist, nicht gleich die ganze Schleife abbricht, würde Dir einfacher fallen, wenn Du eine Funktion hättest, die den gesamten Infotext erzeugt. Dann benutzt Du 5! mal den gleichen »os.path.join«!
Gary123456
User
Beiträge: 318
Registriert: Dienstag 26. Februar 2013, 18:39

im Übrigen eine passende Funktion: »os.path.samefile«
Läuft leider nur unter Unix.

Ich habe das gefunden: os.path.normcase(path) auf diesen Rat hin: http://stackoverflow.com/questions/8892 ... python-2-7 Was haltet Ihr davon? Welche Möglichkeiten gibt es noch?

Folgender Code, der aber wegen dem os.path.samefile nicht so ganz funkt:

Code: Alles auswählen

import os
import sha


def shasum(filepath, blocksize = 1024 * 1024): 
    h = sha.new()
    with open(filepath, "rb") as f:
        try:
            while True:
                part = f.read(blocksize)
                if not part:
                    break
                h.update(part)
        finally:
            f.close()   
        return h.hexdigest()

#Alternative für die 5 os.path.join's
def path_join(path, entry):
    return os.path.join(path, entry)

#Groesse berechnen
def groesse(path):
    return os.path.getsize(path)

#Geschütze ignorieren
def sha_wert(path, pfad, Geschuetzt):
    for geschuetzt in Geschuetzt:
        if os.path.samefile(path, os.path.join(pfad, Geschuetzt)) == True:
            return shasum(os.path.join(path, entry))
        else:
            continue
        



Verzeichnisse = ["C:\\"]
Geschuetzt = ["C:\\hiberfil.sys"]

for path in Verzeichnisse:
    for entry in os.listdir(path):
        Pfad = path_join(path, entry)
        Groesse = int(groesse(Pfad)) / 1024
        Sha = sha_wert(Pfad, path, Geschuetzt)
        
        
        print Pfad
        print Groesse
        
Besser?
Zuletzt geändert von Gary123456 am Mittwoch 24. April 2013, 20:08, insgesamt 1-mal geändert.
Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

Ganz ehrlich,
wäre ich dein Chef und du würdest mir das als Ergebnis präsentieren, würde ich dich zur Strafe an den Nichtfeier- & Sonntagen zwischen Weihnachten und Neujahr arbeiten lassen. Ist ja eine Beleidigung für jeden Programmierer.
Pep8, with block und close, sinnlose int Umwandlung, explizites True, sinnloses continue usw.-
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
Gary123456
User
Beiträge: 318
Registriert: Dienstag 26. Februar 2013, 18:39

Ich habe mein Bestes gegeben. Was der "Chef" dazu sagen würde, wäre mir egal, da ich in Python noch übe. Ich finde diese Aussage nicht fair. Dennoch versuche ich den Code zu verbessern.

EDIT: Ja und ich habe einige Fehler gesehen und bisher ausgebessert. Mal sehen, ob ich noch welche finde :)
Gary123456
User
Beiträge: 318
Registriert: Dienstag 26. Februar 2013, 18:39

Code: Alles auswählen

import os
import sha


def shasum(filepath, blocksize = 1024 * 1024): 
    h = sha.new()
    with open(filepath, "rb") as f:
        try:
            while True:
                part = f.read(blocksize)
                if not part:
                    break
                h.update(part)
        finally:
            f.close()   
        return h.hexdigest()

def sha_wert(path, verzeichnis, geschuetzt):
    for geschuetzt in geschuetzt:
        if os.path.samefile(path, os.path.join(verzeichnis, geschuetzt)):
            return shasum(os.path.join(path, entry))

verzeichnisse = ["C:\\"]
geschuetzt = ["C:\\hiberfil.sys"]

for path in verzeichnisse:
    for entry in os.listdir(path):
        Pfad = os.path.join(path, entry)
        Groesse = os.path.getsize(Pfad)
        Sha = sha_wert(Pfad, path, geschuetzt)
Pep8 kann ich nicht so ganz nachvollziehen.

Code: Alles auswählen

explizites True
Wenn man == True hinschreibt, fällt es einem Einsteiger wie mir viel leichter. Glaub mir.

Zwei Funktionen waren unnötig.

Aber für heute ist Schluss
Antworten