Ordner Pfad mit csv File abgleichen

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.
JohannX
User
Beiträge: 110
Registriert: Mittwoch 27. März 2019, 17:07

Hallöchen 8)

Ich habe nun eine interessante Aufgabe bekommen.
Ziel ist es einen Pfad welcher Ordner (z.B. 2019, 2018, usw) und darin sind PDF´s enthalten. Die PDF´s sollen dann mit einer csv Datei abgeglichen werden, falls in der csv Datei ein Bericht.pdf fehlt soll dieser unten angehängt werden. Das ganze möchte ich mit Threading erledigen, da es noch weiter ausgebaut werden soll, Threading ist aber kein Thema :)

Habe mir mal als erstens vom Pfad die PDF´s ausgeben lassen sowie die csv in einer for Schleife, das funktioniert soweit gut.
Hier mal der Code:

Code: Alles auswählen

import os
import sys
import time
import datetime
import threading
import requests
import PyPDF2


class Data_Matching(threading.Thread):
    def __init__(self, id, name):
        threading.Thread.__init__(self)
        self.id = id
        self.name = name

    def run(self):
        for subdir, dirs, files in os.walk("C:\daten\Bericht"):
            for file in files:
                self.data_dir = os.path.join(subdir, file)
                print(self.data_dir)

        data_csv = open("C:\daten\csv\reports.csv", "r")
        for line in data_csv:
            self.data_csv = line
            print(self.data_csv)
        data_csv.close()

        print(time.strftime("%Y-%m-%d"))


t1 = Data_Matching(1, "t1")
t1.start()
Ist es Ratsam von beiden ein Dict zu erstellen und diese dann Zeile für Zeile abzugleichen?
Oder wie würdet ihr das machen?
__deets__
User
Beiträge: 14543
Registriert: Mittwoch 14. Oktober 2015, 14:29

threading hat mit der Aufgabe nichts zu tun. Und sollte darum auch in der Implementierung nicht vorkommen. Wenn du spaeter diese Funktionalitaet in einem Thread benutzen willst, steht dir das dann trotzdem frei. Ich wuerde dir generell NICHT dazu raten, aber das ist eine andere Diskussion.

Der Name Data_Matching mischt unglueckling zwei Namenskonventionen. Der sollte pythonisch DataMatching lauten. Die fest kodierten Pfade sind natuerlich auch ein no-no. Und eine Klasse ist dafuer im Grunde auch voellig ueberkandidelt, eine Funktion reicht. Statt open/close benutzt man das with-statement.

Und bezueglich des vorgehens: dazu liest du am besten die CSV-Datei ein, und baust ein Set mit relativen Pfadnamen. Und jede Datei die du findest schlaegst du ebenfalls mit ihrem relativen Pfad. Dazu gibt es eine Funktion, zB PurePath.relative_to(*other) aus der pathlib. Generell solltest du erwaegen die pathlib zu benutzen, das ist der bessere, modernere Weg mit Pfaden umzugehen.
JohannX
User
Beiträge: 110
Registriert: Mittwoch 27. März 2019, 17:07

@__deets__

Habe alle deine Ratschläge befolgt, bis auf einen
Die fest kodierten Pfade sind natuerlich auch ein no-no.
Das Python Programm wir auf einem Server einmal täglich ausgeführt, der Pfad bleibt immer gleich auch die nächsten Jahre, man greift hier auf einen Pfad zum Server zu.
Denke dass es hier keinen Sinn macht, den Pfad täglich per Hand immer erneut anzugeben. Außer du hast damit etwas anderes gemeint

Der Code sieht jetzt erstmals so aus:

Code: Alles auswählen

        with open("C:\daten\csv\emclab_reports.csv", "r") as data_csv:
            reader = csv.reader(data_csv, delimiter = ",")
            for line in reader:
                print(line)
Was ich nicht ganz verstehe ist das mit dem set und relativen Pfadnamen
__deets__
User
Beiträge: 14543
Registriert: Mittwoch 14. Oktober 2015, 14:29

Diese Denke, dass die Pfade ja immer gleich blieben, und es darum ok waere sie hart zu kodieren, ist deutlich zu kurz. Das der Server momentan so aufgesetzt ist mag ja sein. Doch wenn du an dem Skript arbeitest, musst du dir lokal erstmal genau so eine Umgebung herstellen, damit du das testen kannst. Die entwickelte Funktionalitaet mag auch fuer andere Aufgaben interessant sein, und ist dann nicht portierbar. Und last but not least ist es schlechter Stil, weil man im Code generell keine magischen Konstanten verwendet. Egal ob Zahlen oder Strings. Mindestens mal gehoert das also an den Anfang der Datei, in eine oder mehrere Konstanten. Aber die Gelegenheit zu verpassen, besser programmieren zu lernen - 🤷‍♂️

Die relativen Pfade sind nicht zwingend, wuerden die Portabilitaet erhoehen, weil eben Pfader relativ zu einem Basis-Pfad (eben dem Argument an die Funktion) ermittelt und gespeichert werden. Und set ist unabhaengig davon die richtige Datenstruktur, mit der man prueft, ob ein Element schon in einer Menge (set) von Dingen ist.
JohannX
User
Beiträge: 110
Registriert: Mittwoch 27. März 2019, 17:07

__deets__ hat geschrieben: Donnerstag 8. August 2019, 14:51 Diese Denke, dass die Pfade ja immer gleich blieben, und es darum ok waere sie hart zu kodieren, ist deutlich zu kurz. Das der Server momentan so aufgesetzt ist mag ja sein. Doch wenn du an dem Skript arbeitest, musst du dir lokal erstmal genau so eine Umgebung herstellen, damit du das testen kannst. Die entwickelte Funktionalitaet mag auch fuer andere Aufgaben interessant sein, und ist dann nicht portierbar. Und last but not least ist es schlechter Stil, weil man im Code generell keine magischen Konstanten verwendet. Egal ob Zahlen oder Strings. Mindestens mal gehoert das also an den Anfang der Datei, in eine oder mehrere Konstanten. Aber die Gelegenheit zu verpassen, besser programmieren zu lernen - 🤷‍♂️

Die relativen Pfade sind nicht zwingend, wuerden die Portabilitaet erhoehen, weil eben Pfader relativ zu einem Basis-Pfad (eben dem Argument an die Funktion) ermittelt und gespeichert werden. Und set ist unabhaengig davon die richtige Datenstruktur, mit der man prueft, ob ein Element schon in einer Menge (set) von Dingen ist.
Also deinen ersten Absatz habe ich jetzt so verstanden, dass am Anfang des Python Files der Pfad zu den Dateien angeben sein soll, verstehe ich das so Richtig?
Sprich der Code wäre dann so:

Code: Alles auswählen

path_to_csv = "C:\daten\csv\reports.csv"
path_to_files = "C:\daten\Bericht"
with open(path_to_csv, "w") as data_csv:
            for subdir, dirs, files in os.walk(path_to_files):
                for file in files:
                    data_csv.write(os.path.join(subdir, file) + "\n")
So wird die csv Datei jedes mal neu überschieben, ist aber nicht das Richtige, das weiß ich schon!

Beim zweiten Absatz versteh ich nur Bahnhof :?:
__deets__
User
Beiträge: 14543
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das ist etwas besser. Aber da geht noch mehr. Konstanten werden in Python GROSS geschrieben. Und natürlich gehört der Code danach in eine Funktion. Du wolltest den doch irgendwann mal aus einem Thread aus aufrufen..

Bezüglich des 2ten Absatzes: weißt du was ein relativer Pfad ist? Wenn nicht, hast du das mal versucht zu googeln? Weißt du was eine Menge ist? Wenn nicht, hast du das mal gegoogelt? Und was wolltest du in deinem Dictionary speichern? Was ist die Eigenschaft eines Dictionary die dich für diese Aufgabe interessiert?
Benutzeravatar
__blackjack__
User
Beiträge: 13113
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Irgendwie glaube ich den Pfad "C:\daten\csv\reports.csv" in *der* Schreibweise ja nicht so ganz. 😉
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
JohannX
User
Beiträge: 110
Registriert: Mittwoch 27. März 2019, 17:07

Also ich habe die Konstanten Variablen nun groß geschrieben

Code: Alles auswählen

PATH_TO_CSV = "C:\daten\csv\reports.csv"
PATH_TO_FILES = "C:\daten\Berichte"
Wenn nicht, hast du das mal versucht zu googeln?
Da sagst du "eval is evil" und schlägst Google vor, Google is evil :twisted:
Kleine Scherz am Rande...

Hab mich da ein wenig durchgelesen mit den Absoluten und Relativen Pfaden, sowie Menge
http://desktop.arcgis.com/de/arcmap/10. ... 6E99FADEFF
https://www.python-kurs.eu/python3_sets_mengen.php

Sobald das Programm am Server lauffähig ist, werde ich die Pfade noch genau angeben, das wird für´s erste mal nebensächlich sein.
Als Praktikant habe ich nicht überall zugriff und musste mir ein paar Files und Daten besorgen um es am lokalen PC zu probieren :?

Das ist mal der aktuelle Code:

Code: Alles auswählen

# Konstanten werden in Python immer GROSS geschrieben und am Anfang der Datei
PATH_TO_CSV = "C:\daten\csv\reports.csv"
PATH_TO_FILES = "C:\daten\Berichte"
PATH_TO_LOGFILES = "C:\daten\csv\logfile.txt"
DATE_TIME = time.strftime("%Y-%m-%d")

# Dictionaries
dic_report_data = []
dic_csv_data = []

def DataMatching():
    for subdir, dirs, files in os.walk(PATH_TO_FILES):
        for file in files:
            report_title = os.path.basename(os.path.join(subdir, file))
            dic_report_data.append(report_title)
    print(dic_report_data)

    with open(PATH_TO_CSV, "r") as csv_data:
        data_csv = csv.reader(csv_data)
        for line in data_csv:
            dic_csv_data.append(line)
    print(dic_csv_data)

    print(len(dic_report_data))
    print(len(dic_csv_data))

if __name__ == "__main__":
    DataMatching()
Soweit so gut, hoffe ich zumindest.
Jetzt könnte ich mit einer if abfrage kontrollieren ob beide Dict´s die gleiche länge haben. Ist die Antwort ja, soll nicht passieren
Wenn mehr Einträge in der Ordner Struktur sind sollen die Fehlenden PDF´s in die csv eingetragen werden.
Falls jedoch mehr Einträge in der csv als in der Ordner Struktur sind, soll eine Warnung ausgegeben werden.

Ist hier mein Gedankengang so der Richtige? Oder gibt es Konstruktive Kritik mit eventuell Code Beispielen?
Benutzeravatar
__blackjack__
User
Beiträge: 13113
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@JohannX: Grunddatentypen haben an sich ja schon nichts in Namen verloren. Abgekürzt schon gar nicht. Und so überhaupt gar nicht wenn es nicht einmal stimmt. Listen sind keine Wörterbücher. Der Kommentar ``# Dictionaries`` ist auch falsch. Wäre er richtig, wäre er überflüssig.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
JohannX
User
Beiträge: 110
Registriert: Mittwoch 27. März 2019, 17:07

Na da habe ich wieder was gelernt

Code: Alles auswählen

report_data = []
csv_data = []

def DataMatching():
    for subdir, dirs, files in os.walk(PATH_TO_FILES):
        for file in files:
            report_title = os.path.basename(os.path.join(subdir, file))
            report_data.append(report_title)
    print(report_data)

    with open(PATH_TO_CSV, "r") as values_from_csv:
        inhalt = csv.reader(values_from_csv)
        for line in inhalt:
            csv_data.append(line)
    print(csv_data)

    print(len(report_data))
    print(len(csv_data))

if __name__ == "__main__":
    DataMatching()
__deets__
User
Beiträge: 14543
Registriert: Mittwoch 14. Oktober 2015, 14:29

Der Name der Funktion ist nicht der Konvention entsprechend. Das sollte data_matching sein. Globale Variablen anzulegen ist ein Fehler. Vor allem wenn die wie hier eh nur innerhalb der Funktion verwandt werden. Wenn dich eh nur der eigentliche Dateiname und nicht der gesamte Pfad interessiert, warum fügst du den aus dem walk erzeugten Namen erst mühselig zu einem absoluten Pfad zusammen, um daraus direkt den basename zu nehmen? Dann nimm doch gleich “file”. Ein schlecht gewählter Name, weil er den eingebauten Namen “file” überschreibt. Und bist du sicher, dass die Namen der Dateien selbst ausreichen? Und es da keine kollisionen geben kann? Und die Variable “line” aus der CSV Verarbeitung ist auch irreführend. Das ist eine Reihe von werten. Man nennt das darum row. Und wenn du die als Ganzes ablegst, dann ist das doch wertlos. Denn dann vergleichst du “Datei.pdf” mit [“Datei.pdf”]. Eine Liste kann niemals gleich einem String sein. Was steht denn in der CSV sonst, neben dem Dateinamen? Nix? Dann kann das auch nur eine normale Datei mit Zeilen sein.


Und last but not least der dickste Fehler ist der “Algorithmus”. Wenn auf dem Server die Dateien A, B, C liegen, und in der Datei die Dateien E, F, G stehen - dann sagt dein Längenvergleich “alles knorke”. Obwohl es offensichtlich Unterschiede gibt. Und generell hilft eine Liste nicht, wenn der Inhalt zwar gleich sein mag, aber die Reihenfolge ist anders. A, B, C != B, C, A.

Der set datentyp erlaubt genau da, sich um die Reihenfolge keinen Kopf machen zu müssen.

{ A, B, C } == { B, C, A }

Und jetzt die Frage an dich: wer garantiert Dir, dass die Daten in der exakt gleichen Reihenfolge geliefert werden?

Und noch besser: Sets erlauben Dir ganz einfach rauszufinden, was genau die Unterschiede sind.

https://docs.python.org/3/tutorial/data ... .html#sets

Schau dir mal genau an, was die verschiedenen Methoden liefern. Und wie sich das auf deinen Fall bezieht.
JohannX
User
Beiträge: 110
Registriert: Mittwoch 27. März 2019, 17:07

Gestern:
Der Name Data_Matching mischt unglueckling zwei Namenskonventionen. Der sollte pythonisch DataMatching lauten.
Heute:
Der Name der Funktion ist nicht der Konvention entsprechend. Das sollte data_matching sein.
Was ist da jetzt das Richte?
"data_matching" wird es jetzt werden!
Wenn dich eh nur der eigentliche Dateiname und nicht der gesamte Pfad interessiert, warum fügst du den aus dem walk erzeugten Namen erst mühselig zu einem absoluten Pfad zusammen, um daraus direkt den basename zu nehmen?
Es gibt sicherlich mehrere Wege nach Rom, außerdem sind bei diesem Pfad welchen ich auslesen möchte mehrere Ordner vorhanden, in all diesen Ordnern sind PDF´s enthalten.
Es gibt sicherlich 100 andere Wege dies zu Bewerkstelligen.

Das ist eine Zeile von der "besagten" csv Datei:

Code: Alles auswählen

2018-04-31,Automarke,eine Nummer(Zahlen und GROSSbuchstaben),Immunität,Bericht_eine Nummer(wie zuvor) - 44.43_A_99.pdf,False
Die Ordner Struktur ist:

Code: Alles auswählen

Berichte\2019 (und 2018, 2017, usw...)
Und in all diesen Ordnern sind PDF´s enthalten

Der Name der PDS´s ist der gleiche wie in der csv Datei (Bericht_eine Nummer(wie zuvor) - 44.43_A_99.pdf)


Das mit den set schau ich mir jetzt mal an!
Benutzeravatar
sparrow
User
Beiträge: 4195
Registriert: Freitag 17. April 2009, 10:28

Das hier sollte man gelesen haben: PEP8
JohannX hat geschrieben: Freitag 9. August 2019, 10:25Es gibt sicherlich mehrere Wege nach Rom, außerdem sind bei diesem Pfad welchen ich auslesen möchte mehrere Ordner vorhanden, in all diesen Ordnern sind PDF´s enthalten.
Es gibt sicherlich 100 andere Wege dies zu Bewerkstelligen.
Es gibt bestimmt mehrere Wege nach Rom. Aber von München nach Rom über London zu fahren ist nicht sehr sinnvoll.
Und einen Pfad aus Verzeichnis und Dateinamen zusammenzubauen, nur um dann hinterher den Dateinamen herauszulesen ist kein Weg nach Rom sondern wenig sinnvoll.
__deets__
User
Beiträge: 14543
Registriert: Mittwoch 14. Oktober 2015, 14:29

Gestern war es eine Klasse. Und heute ne Funktion. Ich habe also beide Male das richtige gesagt 🤷🏼‍♂️

Sicher gibt es viele Wege nach Rom. Aber du BIST in Rom. Und willst mir jetzt ernsthaft verkaufen, es ist sinnvoll nach Auckland und wieder zurück zu fliegen, um dann wieder in Rom zu sein?

Aber ich merke schon: du weißt es besser. Dann viel Erfolg!
Benutzeravatar
__blackjack__
User
Beiträge: 13113
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@JohannX: `data_matching` wäre von der Schreibweise her richtig, aber vom Inhalt eher nicht für eine Funktion, weil es keine Tätigkeit beschreibt. Solange wir von der Hauptfunktion reden, braucht man sich aber eigentlich keine Gedanken über einen Namen zu machen, weil die konventionellerweise einfach `main()` heissen würde. Wobei ich hier neben der Hauptfunktion bereits zwei weitere Funktionen sehe. Das ermitteln der Dateinamen aus dem Verzeichnisbaum und aus der CSV-Datei sind ja zwei unterschiedliche Aufgaben bei denen es Sinn macht die getrennt entwickeln und testen zu können.

Dein Code sammelt alle Dateinamen, nicht nur die, bei denen man am Dateinamen erkennen kann, das es PDF-Dateien sind.

In der CSV-Datei stehen dann also nur die Dateinamen selbst, ohne (Teil)Pfad? Wie sollte dann damit umgegangen werden wenn in der CSV-Datei ein Dateiname mehr als einmal vorkommt? Wie wenn er im Verzeichnisbaum mehr als einmal vorkommt? Die würden sich dann ja nicht mehr eindeutig zuordnen lassen. Was ist wenn die Anzahl von einen Dateinamen aus den Verzeichnissen von der Anzahl in der CSV-Datei abweicht?

Wenn ein Bericht im Verzeichnisbaum gefunden wurde der in der CSV-Datei noch nicht enthalten ist, wo sollen dann die anderen Werte her kommen die neben dem Dateinamen in der CSV-Datei stehen?

Ist rekursives Durchlaufen des Verzeichnisbaums wirklich die sinnvollste Lösung? Hat der tatsächlich keine feste Struktur an der man sich orientieren kann, und eventuell sogar sinnvoll einschränken kann in welche Verzeichnisse man geht und in welche nicht?
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

@JohannX: also wenn ich Dich jetzt richtig verstanden habe, dann ist der Ordner gar nicht wichtig, oder kann es in unterschiedlichen Jahren Dateien mit dem selben Namen geben, und man muß diese aus dem Datum in der CSV-Datei extrahieren?

`report_data` und `csv_data` sind zwei schlechte Variablennamen. `data` ist ja so gut wie alles. In `report_data` sind doch in Wirklichkeit `report_pdf_filenames`, was in csv_data steht, weiß ich nicht, aus Deinem csv-Beispiel werde ich nicht schlau.

Mit pathlib kann man `report_pdf_filenames` auch ganz einfach füllen:

Code: Alles auswählen

PATH_TO_REPORTS = pathlib.Path("C:\\daten\\Berichte")
report_filenames = [path.name for path in PATH_TO_REPORTS.rglob("*.pdf")]
JohannX
User
Beiträge: 110
Registriert: Mittwoch 27. März 2019, 17:07

@__blackjack__
Dein Code sammelt alle Dateinamen, nicht nur die, bei denen man am Dateinamen erkennen kann, das es PDF-Dateien sind.
Es sollten nur PDF´s in den Ordnern enthalten sein, natürlich kann es passieren dass mal was daneben geht. Da hast du Recht, das müsste man berücksichtigen.
Doch wie gehe ich hierbei vor? *PDF
In der CSV-Datei stehen dann also nur die Dateinamen selbst, ohne (Teil)Pfad? Wie sollte dann damit umgegangen werden wenn in der CSV-Datei ein Dateiname mehr als einmal vorkommt? Wie wenn er im Verzeichnisbaum mehr als einmal vorkommt? Die würden sich dann ja nicht mehr eindeutig zuordnen lassen. Was ist wenn die Anzahl von einen Dateinamen aus den Verzeichnissen von der Anzahl in der CSV-Datei abweicht?
In der CSV-Datei steht dann anfangs das Datum wann die PDF abgespeichert worden ist/bzw. wann die Datei in den Ordner gekommen ist. -> Datum
Dann steht in welchem Ordner die PDF gefunden wurde (also \Berichte\2019\AutomarkeXY) -> AutomarkeXY
Dann steht eine Interne Bearbeitungsnummer welche als Name im PDFnamen enthalten ist (Bericht_028154A09P_Im_BCI_GPA3.1-A2_PCBA.pdf), diese ist immer 10-stellig -> 028154A09P
Zum Schluss kommt noch ein False oder True hinzu, hierbei wird die PDF durchgelesen ob sich 2 Schlüsselwörter in der PDF befinden (Replace oder Ersetzt) -> True oder False

Sollte dann so aussehen:

Code: Alles auswählen

2018-04-31,AutomarkeXY,028154A09P,Immunität,Bericht_eine Nummer(wie zuvor) - 44.43_A_99.pdf,False
Nur von wo ich Immunität her bekomme weiß ich noch nicht, muss ich dann nächste Woche erfragen wenn wieder wer da ist.

Sollte ein Dateinamen mehr als einmal vorkommen sollte es in ein Log-File geschrieben werden und per Mail (aber per Mail kommt dann später)

Prinzipiell soll jeder Name nur einmal in der Ordnerstruktur und einmal in der csv Datei vorliegen. Also es wird überprüft welche PDF´s sind in der Ordnerstruktur und sind diese dann gleich mit der csv?
Wenn ja -> mache nichts
Wenn nein -> Füge in der csv den Fehlenden Eintrag hinzu
Ist es andersrum also wenn mehr Einträge in der csv Datei sind als PDF´s in der Ordnerstruktur vorhanden -> schreibe dies in die log Datei
Egal welches eingetretten ist, sende eine Mail (kommt dann später hinzu)


Später soll das noch in eine Datenbank geschrieben werden, sowas hab ich schon öfters gemacht, sollte somit kein Problem sein!
JohannX
User
Beiträge: 110
Registriert: Mittwoch 27. März 2019, 17:07

Dieses Vorhaben übersteigt alles was ich jemals in Python gemacht habe und ich lerne Python erst seit Ostern :shock:
JohannX
User
Beiträge: 110
Registriert: Mittwoch 27. März 2019, 17:07

@Sirius3
Danke dein Code ist Perfekt!
Somit nimmt er nur alle PDF´s

Jetzt habe ich 2 listen,
bei report_pdf_filenames ist die liste ["PDF", "PDF","PDF", ...]
bei csv_data ist die liste [[Datum, AutomarkeXY,Bericht,...], [Datum, AutomarkeXY,Bericht, ....] usw]

So rein Überlegt brauche ich ja nur den Bericht heraussuchen und in die Liste speichern, der Rest ist ja für die Überprüfung mittels set ja überflüssig
Benutzeravatar
__blackjack__
User
Beiträge: 13113
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@JohannX: Also so in sich ist der Code von Sirius3 perfekt, aber für Deine Problemlösung natürlich nicht, denn die erste Liste enthält nur die Dateinamen. Wenn Du da einen findest der nicht in der CSV-Datei steht, dann musst Du Daten hinzufügen die sich aus dem Dateinamen alleine nicht ermitteln lassen. Für die erste Spalte brauchst Du das Datum der Datei – dazu braucht man einen Pfad zu der Datei und nicht nur den Namen. Das AutomarkeXY ist auch ein Teil aus dem Pfad der nicht nicht im Dateinamen allein enthalten ist. Und Du brauchst hier etwas was am Anfang schon angesprochen wurde – einen relativen Pfad der relativ zu einem anderen Pfad ist. Nämlich dem Verzeichnis mit der Jahreszahl.

Wie gesagt würde ich mich da deutlich stärker an der Verzeichnisstruktur orientieren falls die fest und vorgegeben ist und nicht einfach rekursiv *irgendwo* PDFs suchen. Denn was passiert denn zum Beispiel wenn direkt im Basisverzeichnis der Berichte, also auf der gleichen Ebene wie die Verzeichnisse mit den Jahren als Namen ein PDF liegt? Oder direkt unter so einem Verzeichnis, der AutomarkeXY-Teil also leer ist? Kann der AutomarkeXY-Teil aus mehr als einem Verzeichnis bestehen oder liegt die PDF-Datei immer direkt unter so einem Verzeichnis? Anders gefragt: Haben die Berichtsdateinamen immer die Form ``…/Berichte/2019/Automarke/Bericht_....pdf`` ohne weitere Zwischenverzeichnisse?

Falls die Dateinamen der Berichts-PDFs tatsächlich alle mit dem gleichen Präfix anfangen, dann würde ich auch das testen, und nur solche verarbeiten. Und bei anderen eventuell eine Warnung protokollieren.

Das einlesen der CSV-Daten würde ich als erstes machen. In eine passende Datenstruktur. Und da würde ich dann auch auf doppelte Dateinamen testen. Das wäre dann auch mindestens eine Warnung, wenn nicht gar ein Fehler (der nicht unbedingt fatal sein muss) der als solcher protokolliert werden sollte.

Für einen ”selbsterklärenden” Quelltext würde ich für einen Datensatz in der CSV-Datei ja einen Datentyp mit `collections.namedtuple()` definieren…
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten