Seite 2 von 3
Re: Ordner Pfad mit csv File abgleichen
Verfasst: Freitag 9. August 2019, 14:24
von JohannX
``…/Berichte/2019/Automarke/Bericht_....pdf`` ohne weitere Zwischenverzeichnisse?
Ja genau so sieht es aus. Die Dateistrukturen sind fest vorgegeben.
Da der reports Pfad "C:\daten\Berichte" ist, ist der relative Pfad: PATH_TO_CSV = "..\csv\reports.csv" Ein PDF welches in der selben Ebene liegt wie die Ordner mit der Jahreszahl, sollten nicht mitgenommen werden. Also ist der Code vom Sirius3 nicht optimal, das habe ich Verstanden. Da ich hier an meine Grenzen stoße weiß ich echt nicht wie ich das bewerkstelligen soll? Gibt es eine Möglichkeit in Python mehr auszulesen, also auch in welchen Ordner das File liegt oder wann es dort abgelegt worden sein soll? Warnungen zu Protokollieren ist nie Verkehrt! Da du schreibst dass das einlesen der csv Datei als erstes passieren sollte werde ich deinen Ratschlag folgen.
Code: Alles auswählen
csv_inhalt = pd.read_csv(PATH_TO_CSV, encoding = 'iso8859_15')
print(csv_inhalt)
Jetzt noch Überprüfen ob eine Zeile doppelt vorkommt und Dokumentieren und in eine passende Datenstruktur speichern.
Für einen ”selbsterklärenden” Quelltext würde ich für einen Datensatz in der CSV-Datei ja einen Datentyp mit `collections.namedtuple()` definieren…
Hier habe ich das gefunden, werde aber daraus nicht schlau
http://www.deekras.com/namedtuple.html
Re: Ordner Pfad mit csv File abgleichen
Verfasst: Freitag 9. August 2019, 14:37
von Sirius3
Wenn Du weißt, dass die PDF-Dateien immer in zwei Ebenen tiefe liegen, dann durchsuch doch einfach nur die. Und natürlich ist dann vielleicht der gesamte Pfad interessant, so dass Du nicht nur den Namen der Datei speichern darfst:
Code: Alles auswählen
report_filenames = [path for path in PATH_TO_REPORTS.glob("*/*/*.pdf")]
bzw. wenn Du Dich nur für Jahreszahl, Automarke, Name interessierst:
Code: Alles auswählen
report_filenames = [path.parts[-3:] for path in PATH_TO_REPORTS.glob("*/*/*.pdf")]
Re: Ordner Pfad mit csv File abgleichen
Verfasst: Freitag 9. August 2019, 15:04
von __blackjack__
@JohannX: Es geht um relative Pfade zu einem Bericht, da hat der Pfad der CSV-Datei nichts mit zu tun. Aber wenn die Struktur so wie beschrieben ist, dann ist der relative Pfadteil ja immer nur ein Verzeichnisname der für eine Automarke steht.
Natürlich kann man auch den gesamten Pfad zu einer Datei ermitteln. Das hast Du ja bereits in dem Code mit `os.walk()` gemacht – um dann den Pfadanteil wieder weg zu werfen, und das macht `Path.rglob()` standardmässig – aber auch da wirft der Code von Sirius3 diese Information dann wieder weg, damit der effektiv das gleiche macht was Dein `os.walk()`-Code gemacht hat (+ einschränken auf PDF-Dateien).
Wenn man sich an der Verzeichnisstruktur orientiert, dann wird das aber ein bisschen mehr Code wenn man die Ebenen selbst explizit verarbeitet. Wie immer beim Programmieren zerlegt man das Problem in kleinere Teilprobleme. Also als erstes geht man die Einträge im Basisverzeichnis für Berichte durch und filtert nach Verzeichnissen deren Name vier Zeichen lang ist und nur aus Ziffern besteht. Für jeden dieser Pfade sucht man dann alle Pfade ab dort der Form Verzeichnisname gefolgt von Namen die mit 'Bericht_' anfangen und mit '.pdf' enden. Das kann man mit der `Path.glob()`-Methode machen. Wenn man paranoid ist, filtert man die noch nach Dateien, nicht das jemand ein Verzeichnis mit so einem Namen angelegt hat und damit das Programm in Probleme stürzt.
Die Metadaten einer Datei aus dem Dateisystem wie das Datum kann man natürlich auch abfragen wenn man einen Pfad zu einer Datei hat.
Pandas würde ich hier ja nicht mit hineinnehmen. Ich sehe da keinen Vorteil den das hat, insbesondere wenn das am Ende sowieso nicht die Datenstruktur ist mit der man arbeiten will/wird.
`namedtupel` hatten wir ja schon mal: Das ist in der Python-Dokumentation beschrieben. Genauso wie `pathlib` und `Path`-Objekte dort beschrieben sind.
Re: Ordner Pfad mit csv File abgleichen
Verfasst: Montag 12. August 2019, 09:40
von JohannX
Hi zusammen, ein neuer Tag im Paradies
Punkto namedtuple hab ich folgendes gefunden:
https://riptutorial.com/de/python/examp ... namedtuple
https://docs.python.org/3/library/collections.html
Demnach müsste das namedtuple für die csv Datei wie gefolgt lauten:
Code: Alles auswählen
csv_liste = namedtuple("csv_liste", "Datum, AutoMarke, ID, Irgendwas, NamePDF, True_False")
Aber er mekert leider beim Code:
Code: Alles auswählen
def read_Csv_File():
csv_liste = namedtuple("csv_liste", "Datum, AutoMarke, ID, Irgendwas, NamePDF, True_False")
with open(PATH_TO_CSV, "r", newline = '') as file:
reader = csv.reader(file, delimiter = ',', quotechar = '"')
for line in reader:
csv_liste.append(line)
weil es anscheinend kein append beim csv_liste gibt, laut dem zweiten Link aber sehr wohl?
Re: Ordner Pfad mit csv File abgleichen
Verfasst: Montag 12. August 2019, 09:45
von Sirius3
und wo genau hast Du dieses `append` gefunden? Listen haben eine append-Methode, und Listen solltest Du hier auch benutzen. Die einzelnen Einträge der Liste können dann csv_liste-Instanzen sein (besserer Name: CsvEntry).
Und es gilt immer noch, nur weil man eine Variable `csv_liste` nennt, ist es noch lange keine Liste.
Re: Ordner Pfad mit csv File abgleichen
Verfasst: Montag 12. August 2019, 09:47
von JohannX
Sirius3 hat geschrieben: ↑Montag 12. August 2019, 09:45
und wo genau hast Du dieses `append` gefunden? Listen haben eine append-Methode, und Listen solltest Du hier auch benutzen. Die einzelnen Einträge der Liste können dann namedtuple-Instanzen sein.
Und es gilt immer noch, nur weil man eine Variable `csv_liste` nennt, ist es noch lange keine Liste.
Bitte vergiss meine Frage, es war eine Blöde Frage.
Mit diesem Code läuft es nun durch:
Code: Alles auswählen
def read_Csv_File():
csv_liste = namedtuple("csv_liste", "Datum, AutoMarke, ID, Irgendwas, NamePDF, True_False")
with open(PATH_TO_CSV, "r", newline = '') as file:
reader = csv.reader(file, delimiter = ',', quotechar = '"')
for line in reader:
print(line)
new_data = csv_liste(Datum = line[0], AutoMarke = line[1], ID = line[2], Irgendwas = [3], NamePDF = [4], True_False = [5])
print(new_data)
Aber mir fehlt hier etwas, das ist die Ausgabe:
Code: Alles auswählen
['2019-07-29', 'GM', '0281Y09EEE', 'ISO_EL', 'Testreport_0281Y09EEE.pdf', 'False']
csv_liste(Datum='2019-07-29', AutoMarke='GM', ID='0281Y09EEE', Irgendwas=[3], NamePDF=[4], True_False=[5])
Warum nimmt er 3, 4 und 5 nicht?
Re: Ordner Pfad mit csv File abgleichen
Verfasst: Montag 12. August 2019, 10:02
von sparrow
Nimmt er doch. Wie du in der Zeile geschrieben hast. [3], [4] und [5].
Wolltest du die Elemente aus "line", wi ebei den ersten 3 Einträgen, hättest du das doch geschrieben

Re: Ordner Pfad mit csv File abgleichen
Verfasst: Montag 12. August 2019, 10:04
von JohannX
Bei dem print(line) gibt wird alles ausgegeben, das funktioniert auch, aber bei print(new_data) fehlen jedoch die 3 Einträge.
Oder nicht?
Re: Ordner Pfad mit csv File abgleichen
Verfasst: Montag 12. August 2019, 10:12
von Sirius3
Da fehlt nichts, das wird so ausgegeben, wie DU das beim Erzeugen des NamedTuple geschrieben hast.
Um solche Fehler zu vermeiden, wäre die einfachere Schreibweise fehlerunanfälliger:
Aaarg, dieser Klassenname ist einfach schrecklich falsch.
Re: Ordner Pfad mit csv File abgleichen
Verfasst: Montag 12. August 2019, 10:39
von JohannX
Aaarg, dieser Klassenname ist einfach schrecklich falsch.
Jetzt muss ich noch kontrollieren ob es gleiche Zeilen gibt, was eigentlich nicht passieren sollte.
Dann die PDF´s samt Pfad in ein Namedzuple speichern und anschließend diese beiden kontrollieren ob in der csv Datei ein Eintrag fehlt laut den PDF´s und speichern
Sollte so Richtig sein oder?
Re: Ordner Pfad mit csv File abgleichen
Verfasst: Montag 12. August 2019, 12:17
von JohannX
Jetzt habe ich 2 Namedtuples
Code: Alles auswählen
csv_nt = namedtuple("csv_nt", "Datum, AutoMarke, ID, Irgendwas, NamePDF, True_False")
reports_nt = namedtuple("reports_nt", "Jahr, Automarke, NamePDF")
Ich möchte kontrollieren ob die NamePDF´s welche in reports_nt sind auch in csv_nt vorhanden sind.
Code: Alles auswählen
fehlt = set(reports_nt[2]) - set(csv_nt[4])
print(fehlt)
Das will er aber nicht so haben, dachte mit set kann man dies kontrollieren?
Code: Alles auswählen
Traceback (most recent call last):
File "reporter.py", line 42, in <module>
matching()
File "reporter.py", line 36, in matching
fehlt = set(reports_nt[2]) - set(csv_nt[4])
TypeError: 'type' object is not subscriptable
Re: Ordner Pfad mit csv File abgleichen
Verfasst: Montag 12. August 2019, 12:30
von Sirius3
Jetzt verwechselst Du wieder die Klassendefinitionen csv_nt/reports_nt (die man deshalb besser wie Klassennamen schreibt: CsvEntry, ReportsEntry) mit Instanzen davon.
Außerdem macht es wenig Sinn, aus einem Eintrag ein Set zu erstellen. Wie schon öfters hier geschrieben, mußt Du Listen benutzen.
Re: Ordner Pfad mit csv File abgleichen
Verfasst: Montag 12. August 2019, 13:38
von JohannX
So funktioniert das:
Code: Alles auswählen
CsvEntry = []
ReportsEntry = []
def read_csv_File():
with open(PATH_TO_CSV, "r", newline = '') as file:
reader = csv.reader(file, delimiter = ',')
for line in reader:
CsvEntry.append(line)
def read_path_File():
report_filenames = [path.parts[-3:] for path in PATH_TO_REPORTS.glob("*/*/*.pdf")]
for line in report_filenames:
ReportsEntry.append(line)
def matching():
fehlt = set(ReportsEntry[2]) - set(CsvEntry[4])
print(fehlt)

Re: Ordner Pfad mit csv File abgleichen
Verfasst: Montag 12. August 2019, 14:51
von snafu
Mit globalen veränderbaren Objekten muss man extrem aufpassen. Und du hast gleich zwei davon. Ganz ungünstig ist es, wenn Funktionen, die auf solchen Objekten arbeiten, einen bestimmten Zustand erwarten. Bei dir muss man vorher zwei Funktionen aufrufen, damit eine Dritte überhaupt funktioniert. Mag in deinem Fall ausreichen, ist aber kein guter Programmierstil. Und wenn du in 3 Monaten vergessen hast, welche Voraussetzungen erfüllt sein müssen (Aufruf besagter Funktionen), dann wirst du auch erstmal dumm gucken...
Re: Ordner Pfad mit csv File abgleichen
Verfasst: Montag 12. August 2019, 14:59
von sparrow
Vor allem, weil es total unnötig ist. Da wird rigoros alles ignoriert, was Funktionen aus macht.
Das Schlimme: Nicht er er wird sich in 3 Monaten am Kopf kratzen, weil er er ja Praktikant ist.
Re: Ordner Pfad mit csv File abgleichen
Verfasst: Montag 12. August 2019, 15:13
von snafu
Das Zauberwort heißt return und ist essentiell beim Programmieren. Davon gehen die Voraussetzungen zwar nicht weg, aber man sieht viel deutlicher, was zu tun ist und kann das Verhalten besser nachvollziehen, wenn man als "Fremder" den Code ausführt.
Re: Ordner Pfad mit csv File abgleichen
Verfasst: Montag 12. August 2019, 15:24
von Sirius3
Jetzt hast Du nicht die NamedTuple-Klasse CsvEntry genannt, sondern eine globale Liste. Da wäre der alte Name csv_liste doch besser, oder?
Man macht aber keine globalen Variablen, hier kannst Du doch ganz einfach eine Lokale Liste erzeugen, die Du per `return` zurückgibst und an matching als Parameter übergibst.
Du mußt übrigens in jedem Element der Liste den zwieten Eintrag in ein Set stecken. So macht matching im Moment nicht das, was Du möchtest.
Re: Ordner Pfad mit csv File abgleichen
Verfasst: Montag 12. August 2019, 15:24
von kbr
@JohannX: was befindet sich denn in ReportsEntry[2] und in CsvEntry[4]? Und was sagt die anschließend erstellte Differenzmenge aus?
Re: Ordner Pfad mit csv File abgleichen
Verfasst: Montag 12. August 2019, 22:20
von __blackjack__
Besonders erheiternd ist ja bei den globalen Listen, dass das im ersten Beitrag mal mit Threads angefangen hat.

Re: Ordner Pfad mit csv File abgleichen
Verfasst: Donnerstag 22. August 2019, 12:28
von JohannX
__blackjack__ hat geschrieben: ↑Montag 12. August 2019, 22:20
Besonders erheiternd ist ja bei den globalen Listen, dass das im ersten Beitrag mal mit Threads angefangen hat.
@JohannX: was befindet sich denn in ReportsEntry[2] und in CsvEntry[4]? Und was sagt die anschließend erstellte Differenzmenge aus?
CsvEntry[4] -> ['Datum', 'Automarke', 'InterneID', 'Emission', 'Prüfbericht_InterneID.pdf', 'False']
ReportsEntry[2] -> ('Datum', 'Automarke', 'Prüfbericht_InterneID.pdf')
Code: Alles auswählen
def matching():
fehlt = set(ReportsEntry[2]) - set(CsvEntry[4])
print(fehlt)
Damit gebe ich aus, welche Einträge in der CSV fehlen, jedoch nur das erste Element. Müsste ich dann quasi in einer for-schleife machen oder? damit er zeile für zeile durchgeht?