@Schlangenbeschwörung: Anmerkungen zum Quelltext: Kommentare sollen dem Leser einen Mehrwert über den Code geben. Faustregel: Kommentare beschreiben nicht *was* der Code macht, denn das steht da bereits als Code, sondern warum er das macht. Sofern das nicht offensichtlich ist. Offensichtlich ist in aller Regel auch was in der Dokumentation von Python und den verwendeten Bibliotheken steht.
Kommentare werden mit *einem* "#"-Zeichen eingeleitet.
Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.
Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (PascalCase).
`home` ist so sinnfrei weil man das aktuelle Arbeitsverzeichnis nicht vor einen relativen Pfad setzen muss. Das kann man einfach weglassen. Und `home` ist auch ein bisschen irreführend, denn die meisten würde darunter das Heimatverzeichnis des Benutzers verstehen. Das kann mit dem aktuellen Arbeitsverzeichnis übereinstimmen, muss es aber nicht.
Das "data"-Verzeichnis dagegen sollte man als Konstante definieren, denn das kommt sonst zweimal literal im Quelltext vor.
Pfade sind keine einfachen Zeichenketten, weil für Pfade regeln gelten damit sie gültig sind/bleiben, und diese Regeln hängen teilweise auch von der Plattform ab. Deshalb setzt man Pfade nicht einfach mit Zeichenkettenoperationen zusammen. Früher hat man dafür die Funktionen im `os.path`-Modul verwendet. In neuem Code sollte man besser `pathlib.Path` verwenden.
Du hast in `files` die Dateinamen, nutzt die aber überhaupt nicht, sondern baust die dann noch mal per Code aus einer laufenden Nummer zusammen.
`n` und `dat` werden viel zu weit von der Stelle entfernt definiert wo sie dann letztendlich tatsächlich verwendet werden. Das macht den Code schwerer zu lesen und zu refaktorisieren und man vergisst bei solchen Abständen bei Programmänderungen gerne mal Definitionen die nicht mehr gebraucht werden.
Die beiden Variablen enthalten auch in jedem Schleifendurchlauf den gleichen Wert, warum sind das also überhaupt zwei Variablen?
Wenn man am Anfang oder am Ende von allen ``if``/``elif``/``else``-Zweigen das gleiche macht, dann schreibt man das einmal vor bzw. nach dem Konstrukt und nicht nicht in jeden Zweig. Das gilt auch wenn die Sachen nicht am Anfang oder Ende stehen, aber dort stehen könnten, ohne die Semantik zu verändern. Das würde man auch leichter sehen wenn man in den Zweigen die Schritte immer in der gleichen Reihenfolge machen würde.
Wenn man eine Zählvariable hat deren Anfang und Ende man kennt, dann ist das eine ``for``-Schleife statt einer ``while``-Schleife.
Die Schleife schrumpft damit am Ende auf das hier zusammen:
Code: Alles auswählen
for i in range(1, len(files) + 1):
if i == 1:
out = lesen(i)
else:
out += lesen(i)
Was da noch unschön ist, ist der Test der für jeden Durchlauf gemacht wird, obwohl man genau weiss, dass der nur für den ersten Durchlauf gebraucht wird. So etwas behandelt man deshalb normalerweise *vor* der Schleife:
Code: Alles auswählen
out = lesen(1)
for i in range(2, len(files) + 1):
out += lesen(i)
Oder man regelt das mit `map()` und `sum()`:
Code: Alles auswählen
data_frames = map(lesen, range(1, len(files) + 1))
out = sum(data_frames, next(data_frames))
Zwischenstand (ungetestet):
Code: Alles auswählen
#!/usr/bin/env python3
from pathlib import Path
import pandas as pd
DATA_PATH = Path("data")
COLUMN_NAMES = ["Name", "orga", "met", "konz", "selbst", "eng", "tem", "konf"]
def lesen(file_path):
return pd.read_csv(file_path, header=0, index_col=0, names=COLUMN_NAMES)
def main():
cvs_paths = list(DATA_PATH.glob("*.csv"))
data_frames = map(lesen, cvs_paths)
sums = sum(data_frames, next(data_frames))
(sums / len(cvs_paths)).to_csv("Ergebnismittelwerte.csv")
if __name__ == "__main__":
main()
Deine Frage kann man nicht so wirklich beantworten, denn Du müsstest schon selber wissen wie ein nicht vorhandener Wert in die Rechnung eingehen soll und das entsprechend programmieren. Also beispielsweise nicht vorhandene Werte durch 0en ersetzen falls die als 0 in das Ergebnis eingehen sollen. Oder nicht pauschal durch die Anzahl der Dateien teilen sondern pro Person ermitteln wie viele Werte tatsächlich vorhanden waren, und durch diese Anzahlen teilen. Je nach dem welches Vorgehen in dem vorliegenden Fall Sinn macht. Vielleicht hängt das sogar von den Bedeutungen der Spalten ab, bei welchem Wert welches vorgehen Sinn macht.