@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.
Änderung PDF Namen
- __blackjack__
- User
- Beiträge: 14031
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
Am 11. Mai hatte ich Dir folgenden Code geschrieben:
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
`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 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)
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))
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
@ __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.
@ __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.
- __blackjack__
- User
- Beiträge: 14031
- 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.
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.
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
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.

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))
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.
Bevor Du nicht ein Grundlagentutorial durchgearbeitet hast und verstanden hast, was Funktionen sind, brauchst Du hieran nicht weiter arbeiten.