Datein lesen Python

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.
Antworten
JuliCat
User
Beiträge: 1
Registriert: Dienstag 18. Januar 2022, 12:10

[*]Hallo zusammen! also meine Frage ist eine etwas spezielle Frage, ich erwarte nicht dass jeder versteht was ich mache aber ich würde mich über ein paar Tipps freuen. Es ist ein langer Text aber ich würde mich freuen wenn ihr es lesen würdet ♥

Also es geht darum dass ich ein Dokument habe, ein Excell Tabelle mit verschiedenen Werten, nun sollte ich diese Werte in eine Liste speichern, das sind 8037 Werte, und zum beispiel für Wert 101, die 100 vorherigen Werte, den Wert für 101 und die folgenden 100 werte aufsummieren und davon den Mittelwert berechnen.

Hier die Aufgabe:

b.) Die Anzahl der gezählten täglichen Sonnenflecken unterliegt großen Schwankungen.
Berechnen Sie daher zu jedem dezimalen Datum den Mittelwert über die 100 vorangehenden, 100 folgenden und die aktuelle Anzahl der Sonnenflecken. Es reicht
die Mittelung nur für Daten zu machen, welche 100 vorangehende und folgende
Werte haben

Mein Versuch:
da python ja ab 0 anfängt zu Zählen und meine Liste ab Zeile 2 einen Wert hat, ist sozusagen die ersten 100 Zahlen Zeile 02-102, 103 dann die 101 sozusagen und ab 104 dann die nächsten Hundert Zahlen

Code: Alles auswählen

Liste2 = []
f1= open("sunspot_2000.csv", "r+")
with open("sunspot_2000.csv", "r") as f: 
      for line in f:
            str = f1.readline()
            Liste = str[21:24]
            str = Liste
            Liste2.append(str) 
Liste2.pop(0)
koListe = list(map(int, Liste2))
#hier habe ich die Liste von tupeln in Zahlen umgewandelt


listSum = 0
listSum1= 0
n = 103
i = 100
while  n >= 103 and n<= 7935 :
    p = n-i #meine Idee war, dass 103-100 dann 3 ergibt und das -1 ergibt dann den ersten Wert wo es gerechnet werden soll also 2 (was ja dann laut Python dann die 0 ist) und dann noch die 103 -1 um dann bis wert 102 zu rechnen.
    for x in range(p-1,n-1):
        listSum += koListe[x]
    print(listSum)   

    aktZahl = koListe[n]
    print (aktZahl)
    k = n + i
    for x in range(n+1,k+1):
        listSum1 += koListe[x]
    print(listSum1)
    n += 1
    print('Der Mittelwert der Sonnenflecke ist', (listSum+aktZahl+listSum1)/201)
mein Problem: es führt das aufsummieren nicht richtig aus, jeder aufsummierte Wert sollte dann ungefähr um die 17.000 liegen, aber die Werte werden dann immer höher und der letzte Wert ist dann 47.580.958(bei den '100' vorherigen Zahlen) und bei den 100 nächsten 46.059.820, also ich glaube es summiert nicht nur die 100 Zahlen sondern viel mehr und ich weiß nicht genau was ich machen soll... Ideen?
Benutzeravatar
__blackjack__
User
Beiträge: 13111
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@JuliCat: Fangen wir mal am Anfang an, dem Einlesen. Du öffnest die selbe Datei zweimal und hast dann eine Schleife über die Zeilen des einen Dateiobjekts um mit der aktuellen Zeile *nichts* zu machen, und die aber in der Schleife per `readline()` vom anderen Dateiobjekt zu lesen. Wie kommt man denn auf so eine Idee?

Zumal die Datei die an `f1` gebunden wird, nicht geschlossen wird. Und "r+" ist bei Textdateien eigentlich nie ein sinnvoller Modus, weil man da nur in ganz wenigen Ausnahmefällen sinnvoll etwas mit anfangen kann. Die öffnet man mit "r", "w", oder "a" und zieht dann die eine Richtung die da jeweils drin steckt, also lesen *oder* schreiben, durch.

Bei Textdateien sollte man immer explizit beim öffnen die Kodierung angeben.

`f` ist wie die meisten einbuchstabigen Namen kein guter Name. Zu `file` sollte es da schon noch reichen. `f1` kombiniert das dann auch noch mit einer nichtssagenden Nummer. Wenn Du für `f` und `f1` aussagekräftige Namen gesucht hättest, wäre Dir vielleicht an der Stelle schon aufgefallen das da was am Code nicht stimmt, denn mir fällt jetzt nicht ein wie man die sinnvoll benennen sollte. Was ja daran liegt, dass es im Grunde der gleiche Wert ist, mit dem im Code dann das effektiv das gleiche gemacht wird, nur parallel, auf etwas unterschiedlichem Weg, und das Ergebnis von einem der beiden Wege wird dann einfach konsequent ignoriert.

`str` ist zum einen eine kryptische Abkürzung → Nicht machen. Und zum anderen der Name des eingebauten Zeichenkettentyps. Den sollte man nicht an etwas anderes binden.

`Liste` wird an eine Zeichenkette gebunden. Das ist verwirrend. Und `Liste` ist auch viel zu generisch. Und dann wird in der nächsten Zeile `str` an den gleichen Wert gebunden, das hätte man sich also sparen können und gleich an `str` binden können beziehungsweise einen besseren Namen.

`Liste2` ist ein schlechter Name weil der so gar nichts über die Bedeutung des Inhalts aussagt und auch noch eine sinnlose Nummer enthält.

Aus einer Liste am Ende das erste Element mit `pop()` entfernen ist etwas was man beim erstellen der Liste schon hätte richtig machen können, in dem man das ungewollte Element da gar nicht erst rein steckt.

Und das umwandeln in ganze Zahlen hätte man auch gleich beim Einlesen machen können. Eine Liste weniger, ein Name weniger über den man sich Gedanken machen muss.

Kommentare stehen üblicherweise *über* der Zeile oder dem Block den man da kommentiert. Und sie sollten nicht beschreiben was der Code macht, solange das offensichtlich. Das steht da bereits als Code. Offensichtlich ist in der Regel was in der Dokumentation der Programmiersprache und den verwendeten Bibliotheken steht.

`koListe` ist wieder schlecht als Name weil `ko` eine kryptische Abkürzung ist. Wie wär's mit `sonnenfleckenanzahlen`. Das sagt ziemlich deutlich was die Werte da bedeuten. Und deutsch ist keine so praktische Sprache für aussagekräftige Namen. Das wird schnell sperrig. :-)

Übrigens klein geschrieben weil: Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (PascalCase).

Randbemerkung: Ob das mit dem Ausschneiden von einer festen Position einer Zeile aus einer CSV-Datei so eine gute Idee ist, wage ich zu bezweifeln. Das sieht so allgemein nicht robust gegen Änderungen aus.

`listSum` und `listSum1` — da wäre wieder das Thema schlechte Namen und auch noch Nummern.

Das ganze scheint mir auch zu kompliziert, zu nah am Aufagbentext zu sein. Statt die 100 vorhergenden, die 100 nachfolgenden, und den aktuellen Wert zu addieren, kann man doch einfach die ja aufeinanderfolgenden 201 Werte in einem Durchgang addieren.

Das Deine Zahlen immer grösser und grösser werden ist ja auch irgendwie offensichtlich weil in der Schleife die einzige Operation die auf `listSum` und `listSum1` passiert immer nur aufaddieren ist. Das ist nicht wirklich sinnvoll.

Die magischen Zahlen 103 und 7935 sollten nicht fest im Quelltext stehen. Die lassen sich aus den anderen vorhanden Daten berechnen, beziehungsweise sollte die 103 gar nicht nötig sein, denn der Index fängt immer bei 0 an. An Index 0 steht die erste Anzahl an Sonnenflecken. Wenn da etwas anderes steht, hat das nix in der Liste zu suchen.

Letztlich ist das ja ein gleitendes Mittel über ein Fenster. Das programmiert man eher nicht zu Fuss selbst, da gibt es Bibliotheken für. Numpy, Pandas, oder wenn man sich diese Abhängigkeiten nicht einfangen will das (externe) `more_itertools`-Modul für das Fenster, und das `statistics`-Modul aus der Standardbibliothek. Wenn man sich selbst `more_itertools` nicht rein holen will, würde ich das trotzdem anschauen wie die das mit dem Fenster gelöst haben und das so oder so ähnlich nachprogrammieren. Ich vermute mal da würde dann was mit einer `collections.deque` heraus kommen.

An Code vielleich für den Einstieg mal das einlesen in eine Liste mit Zahlen in drei Zeilen und sinnvollen Namen:

Code: Alles auswählen

    with open("sunspot_2000.csv", "r", encoding="utf-8") as file:
        next(file)  # Erste Zeile übespringen.
        sonnenfleckenanzahlen = [int(line[21:24]) for line in file]
Alles danach würde ich komplett anders/einfacher schreiben. Halt je nach dem welche Bibliotheken man dafür verwenden möchte.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten