Zeichnungsdateien verschieben und Umbenennen.

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
Antworten
surfhai
User
Beiträge: 10
Registriert: Montag 21. Dezember 2009, 22:45

Hi Leute,

Mein Skript hat folgende Aufgaben:
- Zeichnungsdateien von Pro/E in ein Unterverzeichnis "Zeichnungen" verschieben
- Dateinamensformat: '{0}.{1}.{2}'.format(ascii_zeichen, 'drw', int)
Beispiel: Grundplatte.drw.30
- Nur die Datei mit dem höchsten Index verschieben
- Nur drw Dateien verschieben
- Dateiindex nach dem Verschieben auf 1 setzen

Falls jemand ein Fehler findet oder etwas eleganter gelöst werden kann, sagt nur bescheid :)

Code: Alles auswählen

import os
import shutil

#os.path.join(os.getcwd(), 'Zeichnungen')
copytodir = os.getcwdu() + os.sep + u'Zeichnungen'
copyfromdir = os.getcwdu()

def user_abfrage(text, default = 'j'):
    abfrage = raw_input(text)
    if str.isalpha(abfrage):
        return str.strip(abfrage).lower()[0]
    else:
        return default
        
frage = u'Sollen alle letzten Zeichnungsdateien in das Verzeichnis "Zeichnungen" verschoben werden? [J/n] '

if user_abfrage(frage, default = u'j') == 'j':
    # Versuche Unterverzeichnis 'Zeichnungen' zu erstellen
    try:
        os.mkdir(copytodir)
    except:
        print u"Verzeichnis '{0}' konnte nicht erstellt werden".format(copytodir)
    else:
        # Verzeichnis in liste einlesen
        verzeichnis_inhalt = os.listdir(copyfromdir)
        
        # Für jedes eingelesene Element prüfen ob es sich
        # um eine Datei handelt.
        dateien = []
        for element in verzeichnis_inhalt:
            element_path = os.path.join(ziel, element)
            if os.path.isfile(element_path):
                dateien.append(element)
        
        
        dateien.sort()
        vergleich_alt = ''
        for datei in dateien:
            datei_splitted = datei.split('.')
            if len(dateI_splitted) >= 3 and datei_splitted[-1].isdigit()\
               and datei_splitted[-2].lower() == 'drw':
                vergleich_alt = datei_splitted
                if datei_splitted[-1] > vergleich_alt[-1]:
                    dateien.remove('.'.join(vergleich_alt))
                datei_neu = '.'.join(datei_splitted[:-1])
            else:
                dateien.remove(datei)
            
        
        for datei in dateien:
            # Prüfen ob es sich um eine Pro/E Zeichnungsdatei handelt
            # Format: '{0}.{1}.{2}'.format(ascii_zeichen, 'drw', int)
            datei_splitted = datei.split('.')
            try:
                shutil.move(os.path.join(copyfromdir, datei), \
                            os.path.join(copytodir, datei))
            except:
                print u'FEHLER: {0} konnte nicht verschoben werden.'.format(\
                                                                     os.path.join(copyfromdir,\
                                                                                  datei))
            else:
                print u'{0} verschoben nach {1}'.format(datei,\
                                                        os.path.join(copytodir, datei))
        
        
        frage = u'Verschobene Zeichnungen auf Dateiindex 1 setzen? [j/N] '
        if user_abfrage(frage, default = u'n') == 'j':
            verzeichnis_inhalt = os.listdir(copytodir)
            dateien = []
            for element in verzeichnis_inhalt:
                try:
                    datei = element.split('.')
                    name_neu = '.'.join(['.'.join(datei[:-1]), '1'])
                    os.rename(os.path.join(copytodir, element) \
                              os.path.join(copytodir, name_neu))
                except:
                    print u'FEHLER: {0} konnte nicht umbenannt werden.'.format(\
                                                                        os.path.join(copytodir,\
                                                                                     element)
lunar

Nicht gut, und das ist noch nett gesagt :)

- os.path.join, nicht a + os.sep + b verwenden
- "except" niemals ohne konkrete Ausnahme (hier wohl EnvironmentError) verwenden
- Der Name "user_abfrage" ist unsinnig und irreführend (da wird kein "user" abgefragt). "yesno_question" oder "ask_yesno" wäre besser. Der Rückgabewert ist auch dumm. Die Antwort kannst Du auch direkt in der Funktion interpretieren und dann einen richtigen Wahrheitswert zurückgeben.
- Es werden Namen gebunden und nie verwendet … und Namen verwendet, die nie gebunden werden (Tippfehler)
- Apropos Namen: Entscheide Dich für eine Sprache, Deutsch oder (vorzugsweise) Englisch, aber nicht beides gleichzeitig.

Das sind nur stilistische Anmerkungen, die Logik habe ich mir gar nicht mehr angesehen …
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo.

Was mir beim durchlesen aufgefallen ist:

- "user_abfrage" ist ein schlechter Name für eine Funktion. Benenne sie danach, WAS abgefragt wird. Außerdem solltest du keine englischen und deutschen Bezeichner vermischen. Entscheide dich für eine Sprache.
- Zeile 11: Benutze besser "abfrage.isalpha()". Analog auch für die folgende Zeile.
- Zeile 16: Frage ist eine Konstante und sollte daher am Anfang des Programms stehen. Außerdem werden Konstanten in GROSSBUCHSTABEN geschrieben. Siehe dazu PEP 8.
- Programmcode sollte nie direkt im Modul stehen, dann kannst du es nämlich nicht mehr vernünftig importieren und wiederverwenden. Benutze besser folgendes:

Code: Alles auswählen

if __name__ == "__main__":
    main()
Der Code sollte dann in einer main-Funktion stehen.
- Benutze keine excepts ohne Anzugeben, welche Exceptions abgefangen werden sollen. Sonst werden alle Fehler verschluckt, was das finden von Fehlern nahezu unmöglilch macht.
- Zeilen 30 bis 34 könnte man durch eine List Comprehension ersetzen.
- Zeilen 40 bis 46 sehen sehr chaotisch aus, da solltest du etwas Ordnung reinbringen. Auch solltest du die ganzen magischen Zahlen durch sinnvolle Konstanten ersetzen.
- In 59, 60, 63, 75, 78 und 79 sind die "\" am Ende überflüssig. Innerhalb von geklammerten Ausdrücken brauchst du sie nicht zu verwenden.
- Ich hab es nicht nachgeschaut, aber sind deine Zeilen kürzer als 80 Zeichen?
- "format" kannst du auch so verwenden, dass du statt {0} einen Namen schreibst. Das sieht manchmal etwas übersichtlicher aus. Ist aber oft nur eine Geschmacksfrage.

Sebastian
Das Leben ist wie ein Tennisball.
surfhai
User
Beiträge: 10
Registriert: Montag 21. Dezember 2009, 22:45

Danke für die Hinweise, ich bemüh mich das umzusetzen...

Hier ist was ich bisher gemacht habe.

Code: Alles auswählen

#/bin/usr/env python
# coding=cp1252

import os
import shutil

def frage_ja_nein(text, default = True):
    abfrage = raw_input(text)
    if not abfrage.isalpha():
        return default
    if str.strip(abfrage).lower()[0] == 'j':
        return True
    else:
        return False
        
def verzeichnis_erstellen(pfad):
    '''Erstellt das Verzeichnis pfad.'''
    try:
        os.mkdir(pfad)
        return True
    except EnvironmentError:
        print u"Verzeichnis '{0}' konnte nicht erstellt werden".format(pfad)
        return False
        
def zeichnungsdateinamen(pfad):
    '''Gibt eine Liste mit den Zeichnungsnamen im Verzeichnis pfad zurück.'''
    
    verzeichnis_inhalt = os.listdir(pfad)
    rueckgabe = []
    for i, element in enumerate(verzeichnis_inhalt):
        element_abs = os.path.join(pfad, element)
        if os.path.isfile(element_abs):
            element_split = element.split('.')
            
            if len(element_split) >= 3 \
            and element_split[-1].isdigit() \
            and element_split[-2].lower() == 'drw' \
            and len(verzeichnis_inhalt) - 1 > i \
            and element_split[:-1] != verzeichnis_inhalt[i + 1].split('.')[:-1]:
                rueckgabe.append(element)
    return rueckgabe
    
def verschiebe_datei(quelle, ziel):
    '''verschiebt die Quelldatei quelle nach Ziel'''
    
    try:
        shutil.move(quelle, ziel)
    except EnvironmentError:
        text = u'FEHLER: {0} konnte nicht verschoben werden.'
        print text.format(quelle)
    else:
        text = u'{0} verschoben nach {1}'
        print text.format(quelle, ziel)
    
def setze_index_zurueck(verzeichnis):
    '''setzt den Dateiindex der Dateien in verzeichnis auf 1'''
    
    verzeichnis_inhalt = os.listdir(verzeichnis)
    for element in verzeichnis_inhalt:
        element_abs = os.path.join(verzeichnis, element)
        datei = element.split('.')
        if os.path.isfile(element_abs) and datei[-1].isdigit():
            try:
                name_neu = '.'.join(['.'.join(datei[:-1]), '1'])
                os.rename(element_abs, os.path.join(verzeichnis, name_neu))
            except EnvironmentError:
                text = u'FEHLER: {0} konnte nicht umbenannt werden.'
                print text.format(os.path.join(verzeichnis, datei))
                
def main():
    ziel = os.path.join(os.getcwd(), 'Zeichnungen')
    quelle = os.getcwdu()
    
    if not os.path.exists(ziel):
        frage = u'Sollen alle letzten Zeichnungsdateien in das Verzeichnis "Zeichnungen" verschoben werden? [J/n] '
        if frage_ja_nein(frage):
            if not verzeichnis_erstellen(ziel):
                return False
    
    dateien = zeichnungsdateinamen(quelle)
    
    for datei in dateien:
        datei_neu_abs = os.path.join(ziel, datei)
        datei_alt_abs = os.path.join(quelle, datei)
        verschiebe_datei(datei_alt_abs, datei_neu_abs)
    
    frage = u'Verschobene Zeichnungen auf Dateiindex 1 setzen? [j/N] '
    if frage_ja_nein(frage, default = False):
        setze_index_zurueck(ziel)
        
        
if __name__ == '__main__':
    main()
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo.

Nur recht kurz rübergeschaut:

Code: Alles auswählen

def frage_ja_nein(text, default = True):
    abfrage = raw_input(text)
    if not abfrage.isalpha():
        return default
    return strip(abfrage)strip().lower()[0] == 'j'

Code: Alles auswählen

def verschiebe_datei(quelle, ziel):
    try:
        shutil.move(quelle, ziel)
    except EnvironmentError:
        text = u'FEHLER: {quelle} konnte nicht verschoben werden.'
    else:
        text = u'{quelle} verschoben nach {ziel}'

    print text.format(quelle=quelle, ziel=ziel)
Die Ausgabe sollte allerdings nicht mit in der Funktion stehen. Funktionalität und Ausgabe trennt man am besten. Überlege dir was passiert, wenn du statt der Konsole nun eine GUI benutzen willst und was du dann alles anpassen müsstest.
Das Leben ist wie ein Tennisball.
surfhai
User
Beiträge: 10
Registriert: Montag 21. Dezember 2009, 22:45

Hab schon über eine grafische Oberfläche nachgedacht. Aber ich glaube, so wie ich es jetzt hab, ist es ganz gut. Kritik ist aber auch jetzt noch gern gesehn.

Es wird auch nur auf Windows ausgeführt, deswegen hab ich os.system('pause') verwendet.

Code: Alles auswählen

#/bin/usr/env python
# coding=cp1252

import os
import shutil
import Tkinter
import tkFileDialog
        

class proe(object):
    def __init__(self):
        self.quelle = ''
        self.ziel = ''
        
    def frage_ja_nein(self, text, default = True):
        abfrage = raw_input(text)
        if not abfrage.isalpha():
            return default
        return abfrage.strip().lower()[0] == 'j'
            
    def verzeichnis_erstellen(self, pfad):
        '''Erstellt das Verzeichnis pfad.'''
        try:
            os.mkdir(pfad)
            return True
        except EnvironmentError:
            print u"Verzeichnis '{0}' konnte nicht erstellt werden".format(pfad)
            return False
            
    def zeichnungsdateinamen(self, pfad):
        '''Gibt eine Liste mit den Zeichnungsnamen im Verzeichnis pfad zurück.'''
        
        verzeichnis_inhalt = os.listdir(pfad)
        rueckgabe = []
        for i, element in enumerate(verzeichnis_inhalt):
            element_abs = os.path.join(pfad, element)
            if os.path.isfile(element_abs):
                element_split = element.split('.')
                
                if len(element_split) >= 3 \
                and element_split[-1].isdigit() \
                and element_split[-2].lower() == 'drw' \
                and len(verzeichnis_inhalt) - 1 > i \
                and element_split[:-1] != verzeichnis_inhalt[i + 1].split('.')[:-1]:
                    rueckgabe.append(element)
        return rueckgabe
        
    def verschiebe_datei(self, quelle, ziel):
        '''verschiebt die Quelldatei quelle nach ziel'''
        
        try:
            shutil.move(quelle, ziel)
        except EnvironmentError:
            text = u'FEHLER: {quelle} konnte nicht verschoben werden.'
        else:
            text = u'{quelle} verschoben nach {ziel}'
            
        print text.format(quelle = quelle, ziel = ziel)
            
    def kopiere_datei(self, quelle, ziel):
        '''kopiert die Quelldatei quelle nach ziel'''
        
        try:
            shutil.copyfile(quelle, ziel)
        except EnvironmentError:
            text = u'FEHLER: {quelle} konnte nicht kopiert werden.'
        else:
            text = u'{quelle} kopiert nach {ziel}'
            
        print text.format(quelle = quelle, ziel = ziel)
        
    def setze_index_zurueck(self, verzeichnis):
        '''setzt den Dateiindex der Dateien in verzeichnis auf 1'''
        
        verzeichnis_inhalt = os.listdir(verzeichnis)
        for element in verzeichnis_inhalt:
            element_abs = os.path.join(verzeichnis, element)
            datei = element.split('.')
            if os.path.isfile(element_abs) and datei[-1].isdigit():
                try:
                    name_neu = '.'.join(['.'.join(datei[:-1]), '1'])
                    os.rename(element_abs, os.path.join(verzeichnis, name_neu))
                except EnvironmentError:
                    text = u'FEHLER: {0} konnte nicht umbenannt werden.'
                    print 'verzeichnis = {0}'.format(verzeichnis)
                    print text.format(os.path.join(verzeichnis, datei))
                    
    def main(self):
        
        ##########################################################
        #while True:
        #
        #    verzeichnis = raw_input('\nVerzeichnis: ')
        #    if os.path.isdir(verzeichnis):
        #        quelle = verzeichnis
        #        ziel = os.path.join(quelle, 'Zeichnungen')
        #        break
        #    else:
        #        print u'\nKein gültiges Verzeichnis angegeben.'
        ##########################################################
        
        root = Tkinter.Tk()
        self.quelle = tkFileDialog.askdirectory()
        if not self.quelle:
            return False
        root.destroy()
        self.ziel = os.path.join(self.quelle, 'Zeichnungen')
        
        print u'Arbeitsverzeichnis:'
        print self.quelle
        
        frage = u'\nSoll das Verzeichnis "Zeichnungen" angelegt werden? [J/n] '
        if self.frage_ja_nein(frage):
            if not os.path.exists(self.ziel):
                if not self.verzeichnis_erstellen(self.ziel):
                    return False
            else:
                print u'Verzeichnis existiert bereits.'
        else:
            if not os.path.exists(self.ziel):
                print u'\nEXIT'
                return False
        
        dateien = self.zeichnungsdateinamen(self.quelle)
        
        frage = u'\nSollen alle letzten Zeichnungsdateien in das Verzeichnis "Zeichnungen" verschoben werden? [J/n] '
        if self.frage_ja_nein(frage):
            for datei in dateien:
                datei_neu_abs = os.path.join(self.ziel, datei)
                datei_alt_abs = os.path.join(self.quelle, datei)
                self.verschiebe_datei(datei_alt_abs, datei_neu_abs)
        else:
            frage = u'\nSollen alle letzten Zeichnungsdateien in das Verzeichnis "Zeichnungen" kopiert werden? [J/n] '
            if self.frage_ja_nein(frage):
                for datei in dateien:
                    datei_neu_abs = os.path.join(self.ziel, datei)
                    datei_alt_abs = os.path.join(self.quelle, datei)
                    self.kopiere_datei(datei_alt_abs, datei_neu_abs)
        
        frage = u'\nVerschobene Zeichnungen auf Dateiindex 1 setzen? [j/N] '
        if self.frage_ja_nein(frage, default = False):
            self.setze_index_zurueck(self.ziel)
        
        
if __name__ == '__main__':
    p = proe()
    try:
        p.main()
    except KeyboardInterrupt:
        print '\n\nEXIT'
    
    os.system('pause')
Antworten