Änderung PDF Namen

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.
Bebbi
User
Beiträge: 144
Registriert: Dienstag 21. April 2020, 19:21

Ich weiss, dass es zum verzweifeln ist, das ist es für mich auch. Mein Korpus hat eine andere Form als heute Morgen...

Sorry aber jetzt habe ich wieder zwei unterschiedliche for Schlaufen. Ich habe versucht beides irgendwie in eine Form zu bringen (natürlich mit raten woher soll ich die Form sonst wissen? :?: ).

Option 1:

Code: Alles auswählen

from pathlib import Path

BESTELL_PATH = Path('P:/KA Hauptordner/Empfang/Ordner Bebbi') # Pfad des Ordners
for filename in BESTELL_PATH.glob("*_color red_*.pdf"): # for Schleife 
    date, name, num, can1, can2, can3 = filename.stem.split('_') # Aufsplittung des Namens in 6 Teile 
    name = name.replace('_color red_', '_Farbe rot_') # Replace von red durch rot
    new_name = 'P:/KA Hauptordner/Empfang/Ordner Bebbi/{}_{}_{}'.format(date, name, num, filename.suffix) # Pfad und Zusammensetzung des neuen Namens 
    for index in range(0, 20):
        if new_name ('{}_{}_{}{}' == '{}_{}_{}{}'):
            new_name = 'P:/KA Hauptordner/Empfang/Ordner Bebbi/{}_{}_{}{}'.format(date, name, num, index, filename.suffix)
        else:
            new_name = '{}_{}_{}'
        break
    new_path = filename.parents[1] / 'Farbe_rot' / new_name
    print(new_name)
   
   
  Hier erscheint folgende Fehlermeldung:
  
  Traceback (most recent call last):
  File "C:\Users\SM\AppData\Local\Programs\Python\Python38-32\Python Test 2.py", line 9, in <module>
    if new_name ('{}_{}_{}{}' == '{}_{}_{}{}'):
TypeError: 'str' object is not callable
>>> 


Option 2:

[code]
from pathlib import Path

BESTELL_PATH = Path('P:/KA/Empfang/Ordner Bebbi') # Pfad des Ordners
for filename in BESTELL_PATH.glob("*_color red_*.pdf"): # for Schleife 
    date, name, num, can1, can2, can3 = filename.stem.split('_') # Aufsplittung des Namens in 6 Teile 
    name = name.replace('_color red_', '_Farbe rot_') # Replace von red durch rot
    new_name = 'P:/KA Hauptordner/Empfang/Ordner Bebbi/{}_{}_{}'.format(date, name, num, filename.suffix) # Pfad und Zusammensetzung des neuen Namens 
    for index in range(0, 20):
       new_name = 'P:/KA/Empfang/Ordner Bebbi/{}_{}_{}{}'.format(date, name, num, index, filename.suffix)
    else:
            new_name = 'P:/KA Hauptordner/Empfang/Ordner Bebbi/{}_{}_{}'
    break
    new_path = filename.parents[1] / 'Farbe_rot' / new_name
    print(new_name)
    
    Hier passiert überhaupt nichts  :cry: 
    
    Ich weiss, dass ihr das nicht nachvollziehen könnt!
Jankie
User
Beiträge: 592
Registriert: Mittwoch 26. September 2018, 14:06

Bebbi hat geschrieben: Donnerstag 28. Mai 2020, 12:51 [...] woher soll ich die Form sonst wissen? :?: ).
Durch ausprobieren, beobachten und lernen. Ein Grundlagentutorial kann da auch hilfreich sein.
Bebbi
User
Beiträge: 144
Registriert: Dienstag 21. April 2020, 19:21

Ich probiere seit mehreren Tagen aus und versuche das Ganze zu verstehen...
Bebbi
User
Beiträge: 144
Registriert: Dienstag 21. April 2020, 19:21

Weshalb kann mir z.B. nicht jemand sagen der Befehl in Zeile X ist falsch und sollte so aussehen. Dann kann ich das einfügen, schauen ob es funktioniert und entsprechend versuchen nachzuvollziehen. Wenn wüsste ich auch ob das Windrad beim Fisch hinten oder vorne stehen muss. So wie jetzt verzettle ich mich total und habe keine Ahnung mehr was überhaupt wie aussehen soll. Ich habe schon gefühlte 100 Varianten versucht und keine scheint Sinn zu machen. Dann kommen immer die Aussagen du hast ja alles und weisst wie es aussehen sollte. Wer sagt denn das ich das weiss. Vielleicht steht das ja irgendwo aber ich sehe es nicht.....

Mein letzter Versuch war das hier - klappt natürlich nicht. Ich weiss, dass jeder von Euch den Fehler sofort sieht, ich kanns leider nicht sehen.

Code: Alles auswählen

from pathlib import Path

BESTELL_PATH = Path('P:/KA Hauptordner/Empfang/Ordner Bebbi')
for filename in BESTELL_PATH.glob("*_color red_*.pdf"):
    date, name, num, can1, can2, can3 = filename.stem.split('_')
    name = name.replace('_color red_', '_Farbe rot_')
    for index in range(1, 20):
        new_name = 'P:/KA Hauptordner/Empfang/Ordner Bebbi/{}_{}_{}{}'.format(date, name, num, filename.suffix)
    else:
        new_name = 'P:/KA Hauptordner/Empfang/Ordner Bebbi/{}_{}_{}{}{}'.format(date, name, num, index, filename.suffix)
    break
    new_path = filename.parents[1] / "Farbe_rot" / new_name
    print(new_name)
__deets__
User
Beiträge: 14538
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das else nach dem for ist NIEMALS richtig in deinem Code. Wenn du etwas mehrfach machen willst, nimmst du eine Schleife. Wenn du etwas bedingt tun willst, nimmst du eine if-Anweisung. Wenn du etwas bedingt mehrfach tun willst, packst du die Anweisung *in* die Schleife. Wenn du etwas pruefen willst, und DANN gegebenenfalls etwas mehrfach tun, dann kommt die for-Schleife IN die if-Anweisung.

Das break ist auch falsch, oder sollen die Zeilen danach wirklich niemals ausgefuehrt werden? Dann koennen sie auch weg.

Ich rate mal, was du willst;

Code: Alles auswählen


        new_name = 'P:/KA Hauptordner/Empfang/Ordner Bebbi/{}_{}_{}{}'.format(date, name, num, filename.suffix)
        if os.path.exists(new_name):
              for i in itertools.count():     
                       new_name = 'P:/KA Hauptordner/Empfang/Ordner Bebbi/{}_{}_{}{}{}'.format(date, name, num, index, filename.suffix)
                       if not os.path.exists(new_name):
                              break
         # ab hier ist new_name dann eindeutig
Benutzeravatar
__blackjack__
User
Beiträge: 13100
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Bebbi: Wenn ich mir das ansehe dann ist ganz klar das Du ``for``-Schleifen nicht verstanden hast. Das ist aber eine Grundlage die *ich* keinem erklären möchte, weil die an anderen Stellen zu genüge erklärt wird. Ich wüsste auch nicht wie ich das noch mal anders als in all den verschiedenen Tutorials und Büchern erklären sollte. Das heisst ich würde entweder selbst das gleiche schreiben was schon zigfach woanders steht, oder es tatsächlich mehr oder weniger abschreiben. Das bringt niemandem etwas.

Und hier wurde vieles davon ja auch schon gesagt. Zum Beispiel recht zeitnah, dass ein ``else`` zu einem ``for`` eher exotisch ist und Dich hier nicht weiter bringt. Und was machst Du? Ein ``else`` zu einem ``for``…

Wobei für diese Lösung mit `range()` wird man das Sprachkonstrukt ``else`` zu ``for`` sogar brauchen, denn man muss ja auch irgendwie den Fall berücksichtigen, dass es alle Dateinamen bis einschliesslich ``…19…`` bereits gibt, und dann sollte ja nicht lautlos doch wieder eine vorhandene Datei überschrieben werden oder eine Ausnahme auslöst werden, je nach Betriebssystem. Das hatte ich ja auch schon mal geschrieben: man wird explizit auf die Exsistenz prüfen müssen wenn das plattformübergreifend funktionieren soll. So eine Überprüfung sehe ich in dem Code nicht. Also weder explizit mit der entsprechenden Methode, noch über das behandeln einer Ausnahme.

Und da sind wir dann wieder an dem Punkt das ich ja auch schon mal vorgeschlagen habe das in eine allgemeine Umbenennungsfunktion heraus zu ziehen die von dem ganzen Splitten an "_", und ersetzen von Namensteilen, und wieder zusammensetzen, unabhängig ist, und die man mit einfacheren Mitteln auch mal testen kann. Oder zumindest eine Funktion die einen `Path` bekommt und ggf. einen entsprechenden `Path` mit einer eingefügten Nummer liefert, so dass es dafür noch keinen Eintrag im Dateisystem gibt.

Auch wenn der Code bisher nicht so viele Zeilen hat, ist das Problem halt doch relativ gross das da gelöst werden soll, insbesondere für Anfänger, und insbesondere für Dich. Also sollte man das auf kleinere Teilprobleme reduzieren, die einfacher zu lösen sind, und die vor allem auch einfach zu testen sind.

Zu dem Code von __deets__: Der hat jetzt `os.path` verwendet, was man nicht ohne Not mit Code vermischen sollte der eigentlich `pathlib.Path` verwendet. Das er das eigentlich tut kann man halt leicht übersehen weil Du da Pfade als Zeichenketten verwendest wo man eigentlich ``filename.with_name(…)`` verwenden sollte.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Sirius3
User
Beiträge: 17748
Registriert: Sonntag 21. Oktober 2012, 17:20

Am 11. Mai hatte ich Dir folgenden Code geschrieben:

Code: Alles auswählen

from pathlib import Path

BESTELL_PATH = Path('P:/KA Hauptordner/Empfang/Ordner Bebbi/Bestellungen')
for filename in BESTELL_PATH.glob("*_Color_red_*.pdf"):
    date, name, num, can1, can2 = filename.stem.split('_')
    name = name.replace('red', 'rot')
    new_name = '{}_{}_{}{}'.format(date, name, num, filename.suffix)
    new_path = filename.parents[1] / "Farbe_rot" / new_name
    filename.rename(new_path)
wo dann Dein Einwand war, dass new_path nicht eindeutig ist, und Du ihn durch eine Ziffer eindeutig machen willst.
Also modifiziert man den Code zu

Code: Alles auswählen

from pathlib import Path

BESTELL_PATH = Path('P:/KA Hauptordner/Empfang/Ordner Bebbi/Bestellungen')
for filename in BESTELL_PATH.glob("*_Color_red_*.pdf"):
    date, name, num, can1, can2 = filename.stem.split('_')
    name = name.replace('red', 'rot')
    new_name = '{}_{}_{}{}'.format(date, name, num, filename.suffix)
    new_path = filename.parents[1] / "Farbe_rot" / new_name
    filename.rename(generate_unique_path(new_path))
`generate_unique_path` soll also den gegebenen Pfad nehmen, prüfen ob er existiert und falls ja entsprechend Nummern einfügen.

Code: Alles auswählen

from itertools import count
def generate_unique_path(path):
    if not path.exists():
        return path
    for index in count(1):
        new_path = path.with_name(f"{path.stem}_{index}{path.suffix}")
        if not new_path.exists():
            return new_path
Bebbi
User
Beiträge: 144
Registriert: Dienstag 21. April 2020, 19:21

@ __deets__ Danke! Ich muss mir die Lösung jetzt zuerst anschauen und nachvollziehen was gemacht wird. if ist mir (ziemlich sicher wegen der Excel Erfahrung) einiges einleuchtender als die else Geschichten. Was ist auf den ersten Blick nicht begreife ist, for i in intertools.count(): wo wird dieses i später wieder verwendet? Oder besser gesagt von wo weiss das System dass sich der Index auf das i beziehen sollte?

@ __blackjack__ Danke auch Dir für Deine Erklärungen. Ich habe for Schleifen wirklich noch nicht begriffen. Ich weiss dass Ihr mich mehrmals auf die 'else' und 'for' hingewiesen habt. Wenn ich dann aber auf https://www.python-kurs.eu/for-schleife.php nachschaue kommt halt genau dieses 'else' und 'for' in der Erklärung vor. Dann heisst es suche die Sachen raus und das was man scheinbar findet ist nicht richtig.... Die Texte sind für einen Layen oft nicht verständlich. Auch bei Dir kommen Wörter wie Code, Path oder Path mit eingefügten Nummern. Zudem sind diese (scheinbar) unzähligen Bibliotheken verwirrend. Einer arbeitet mit os. andere mit Path, was scheinbar auch nicht miteinander benutzt werden kann oder sollte. Wie gesagt, der Code funktioniert auch jetzt noch nicht ganz, aber ich habe wenigstens wieder etwas was ich mir genau anschauen und hoffentlich nachvollziehen kann.
__deets__
User
Beiträge: 14538
Registriert: Mittwoch 14. Oktober 2015, 14:29

@Bebbi: das i in meinem Code ist der Index. Es ist eine Skizze.
Benutzeravatar
__blackjack__
User
Beiträge: 13100
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Bebbi: Der Code von __deets__ war halt nicht getestet. Also entweder beides `i` nennen oder beides `index` nennen. Auf magische Weise weiss Python natürlich nicht was gemeint war. Rechner machen immer nur genau das was man ihnen sagt, nie was man eigentlich gemeint hat.

In dem verlinkten Tutorial wird als erstes die allgemeine Syntax von ``for`` mit dem ``else`` gezeigt. Man muss noch weiter lesen zu der Beschreibung und den Beispielen wo dann auch gar kein ``else`` mehr zum ``for`` vorkommt. Das ``else`` wird auf der gesamten Seite nicht erklärt. Wenn Du Dich auf diese Seite stützt, verwendest Du also etwas von dem Du überhaupt nicht weisst was das macht. Warum verwendest Du das dann? Was hattest Du denn erwartet was das macht und auf welcher Grundlage hast Du das erwartet?

Ich denke nicht das es laientaugliche Begriffe für das Programmieren gibt, so wenig wie es das für jede andere Tätigkeit gibt, die nicht für alle alltäglich und trivial ist. Man muss halt Begriffe lernen. Und Code oder Quelltext gehört dazu. Wobei das ja sogar noch von der Programmiersprache unabhängig ist, denn die allermeisten setzen auf diese Form Programme in dieser Form vom Programmierer zu erwarten. Und man muss auch die Begrifflichkeiten lernen die direkt mit dem Problem zu tun haben, das man lösen will. Du arbeitest mit Pfaden. Also `Path`-Objekten. Und wenn Du Dir jetzt tatsächlich nichts passendes unter einem „Pfad mit Nummern“ vorstellen kannst, wo *Du* doch selber die Anforderung gestellt hast, das keine Dateien ersetzt werden sollen, sondern in dem Fall eine fortlaufende Nummer in den Pfad eingebaut werden soll, dann weiss ich echt nicht mehr weiter.

Falls das Problem war, dass Du nicht weisst das `Path` das englische Wort für „Pfad“ ist: Man kann ohne Englisch nicht wirklich programmieren. So ziemlich alle Programmiersprachen verwenden englischsprachige Schlüsselwörter und Bezeichner für die direkt verfügbaren Namen und auch für die Standardbibliothek. Die originale Sprachdokumentation ist in der Regel in Englisch. Genau so wie die Dokumentation der Standardbibliothek. Das zieht sich dann weiter in Bibliotheken von Drittanbietern und deren Dokumentation.

Das schöne an der heutigen Zeit ist, dass man keine teuren Fachbücher mehr kaufen muss und das wissen nur einem kleinen Fachkreis zur Verfügung steht. Es gibt Wikipedia und Wörterbücher im Netz die man kostenlos nutzen kann. In Wikipedia werden auch die allgemeineren Begriffe wie Code/Quelltext erklärt, die selbst in Anfängertutorials zu konkreten Programmiersprachen oft einfach so als gegeben vom Himmel fallen. Oder auch Begriffe wie „path“/„Pfad“ im Kontext von Computern. Nützlich ist auch das die Wikipediaartikel auch immer Links zu dem jeweiligen Artikel in anderen (natürlichen) Sprachen enthalten, so dass man auch immer die Möglichkeit hat die Erklärungen auf Englisch und Deutsch nachzulesen.

Python ist schon etwas länger dabei, darum gibt es manchmal Module oder einzelne Funktionen die man nicht mehr verwenden sollte, weil im Laufe der Zeit bessere Alternativen dazu gekommen sind. Da gehört `os.path` dazu, weil `pathlib.Path` eine objektorientierte Schnittstelle für Pfad- und Dateioperationen zur Verfügung stellt, mit der man vieles kompakter und verständlicher ausdrücken kann. Für das ``path.with_name(f"{path.stem}_{index}{path.suffix}")`` bräuchte man beispielsweise drei Zeilen Code und drei verschiedene Funktionen aus dem `os.path`-Modul.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Bebbi
User
Beiträge: 144
Registriert: Dienstag 21. April 2020, 19:21

Täglich grüsst das Murmelter, ich weiss Ihr hasst mich dafür aber damit muss ich wohl leben :-)

Noch einmal besten Dank für die zahlreichen Angaben und Infos von gestern. Bin noch ganz erschlagen und versuche mich durchzukämpfen. Ich verfolge momentan die von Sirius3 vorgeschlagene Variante weiter. Da ich glaube (wie Ihr ja auch schon geschrieben habt), dass eine Vermischung von os. und Path wohl nicht so sinnvoll ist. Die beiden von Sirius3 erwähnten Code-Blocks (oder wie man das nennt) habe ich nun versucht zusammen zu fassen. Auf Zeile 12 meint das System nun, dass sich return ausserhalb der Funktion befindet ('return' outside function). Da der Befehl ja eingezogen ist kann ich mir nicht vorstellen, dass dies der Fall sein kann. Ich habe auch sichergestellt, dass der Einzug mit Tab und nicht mit Leerzeichen gesetzt wurde, was so habe ich gelesen of zu der Meldung führt.

Code: Alles auswählen

from pathlib import Path
from itertools import count


BESTELL_PATH = Path('P:/Key Advisors Hauptordner/Empfang/Ordner Bebbi')
for filename in BESTELL_PATH.glob("*_ClientStatement_*.pdf"):
    date, name, num, can1, can2 = filename.stem.split('_')
    name = name.replace('ClientStatement', 'Vermögensausweis')
    new_name = '{}_{}_{}{}'.format(date, name, num, filename.suffix)
    new_path = filename.parents[1] + "Vermögensausweis" + new_name
    if not path.exists():
        return path
    for index in count(1):
        new_path = path.with_name(f"{path.stem}_{index}{path.suffix}")
        if not new_path.exists():
            return new_path
    print(generate_unique_path(new_path))
Sirius3
User
Beiträge: 17748
Registriert: Sonntag 21. Oktober 2012, 17:20

Dir präsentiert man die Lösung auf dem Silbertablett und Du siehst sie nicht. Warum hast Du jetzt wieder angefangen, Codes zu mischen, statt vorher zu versuchen, sie zu verstehen?
Bevor Du nicht ein Grundlagentutorial durchgearbeitet hast und verstanden hast, was Funktionen sind, brauchst Du hieran nicht weiter arbeiten.
Antworten