Ich bin zu doof für Listen

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
Robbse1990
User
Beiträge: 16
Registriert: Montag 16. Oktober 2017, 10:29

Hallo Zusammen,
klar, es gibt unzählige Beiträge im Internet mit exportieren und importieren von Listen aller Art. Jedoch werde ich nicht wirklich schlau daraus.
Folgendes Szenario: Ich betreibe eine Raspberrry Pi mit BME280 Sensor. Temperatur und Feuchtigkeit auslesen funktioniert super, auch die Daten mit matplotlib zu visualisieren geht. Nur was mir Kopfschmerzen bereitet ist folgendes:
Ich habe eine Funktion die mir 3 Werte ausgibt (return a, b, c). Wie kann ich diese jetzt am sinnvollsten in eine txt datei schreiben (alle neuen Daten einfach an die Liste anhängen), und dann die letzten 7 Zeilen wieder einlesen, wenn nötig (da hier einige Daten zusammenkommen, würde ich es gerne vermeiden, wenn möglich, alles einzulesen und nur die letzten 7 Zeilen zu verwenden)? Die Liste schreiben bekomme ich noch hin, sieht dann so aus:
('10.10.2017', 20.5, 64.3)
('11.10.2017', 20.4, 65.9)
usw.
Aber wenn ich einlesen will, bekomme ich das nicht hin mit der Zeilen-Verarbeitung. Am liebsten hätte ich dann 3 Python-Listen, eine mit Datum, Temperaturt und Feuchtigkeit, welche ich mit matplotlib verarbeiten kann. Wenn ich mit readline arbeite, liest es mir jedes einzenle Zeichen als Zeile ein.
Kann mir bitte jemand ein Stichwort geben oder eine Funktion die mir weiterhilft? Ich will keine fertige Lösung, nur ein Tipp in welche Richtung ich denken sollte.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Was heisst denn "einiges"?

Eine Funktion um direkt auf bestimmte Zeilen zu springen gibt es naemlich nicht. Das geht schon vom Betriebssystem her nicht, Dateien sind Datenstroeme von Bytes, das Konzept einer Zeile, an die man springt, kennt es nicht.

Wenn "einiges" sich in der Groessenordung von ein paar MB abspielt, ist das wahrscheinlich ziemlich egal, dann benutz das CSV-Modul sowohl zum schreiben wie auch zum lesen.

Wenn es mehr werden, dann benutz sqlite zum speichern und auslesen, weil du da Abfragen machen kannst ala "alles seit Zeitpunkt X" etc.
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Du könntest deque() aus dem collections-Modul verwenden. Mittels maxlen kann dort die Maximalzahl von Elementen bestimmt werden. Überschüssige Elemente werden dabei automatisch entfernt und es bleiben nur die neuesten erhalten. Wenn du also die letzten 7 Zeilen behalten möchtest, dann wäre es deque(deine_datei, 7). Dabei werden aber trotdem die vorherigen Zeilen angefasst. Müsstest du halt mal schauen, was das performancemäßig ausmacht. Weil technisch gesehen kriegt man diese Info vom Betriebssystem schlicht nicht. Da muss man im Endeffekt immer selbst nachzählen und dafür braucht man nunmal alle Zeilen.
Robbse1990
User
Beiträge: 16
Registriert: Montag 16. Oktober 2017, 10:29

Cool! Danke für die schnellen Antworten. Werde mir mal das csv Modul anschauen. Hab mir fast schon gedacht das ich ums Zeilen zählen nicht rum komme. Wenn es geht/oder nicht, poste ich den Code mal, vllt erkennt jemand ein Verbesserungspotential.
Robbse1990
User
Beiträge: 16
Registriert: Montag 16. Oktober 2017, 10:29

Der vollständigkeit halber:

ich habe das Problem so gelöst. Dabei schreibe ich 2 Messdaten und das Datum in eine Zeile, die Daten sind durch tap getrennt. Anschließend lese ich die Daten wieder ein und schreibe alles in eine seperate Liste


zeit = time.strftime("%a:%d.%m.%Y %H:%M:%S")

#Sensor auslesen
var_temp = round(sensor.read_temperature(),1)
var_hum = round(sensor.read_humidity(),1)

#Daten in Datei schreiben
with open ("Messdaten.txt", "a") as fh:
fh.write(str(zeit)+'\t'+str(var_temp)+'\t'+str(var_hum)+'\n')



#Daten lesen
with open(datei_pfad, 'rb') as fh:
for line in fh:
date_list.append(line[0:20])
temp_list.append(float(line[24:28]))
hum_list.append(float(line[29:34]))
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@Robbse1990: auch wenn Du das csv-Modul nicht verwenden willst, das Arbeiten mit festen Indizes ist eine unkontrollierbare Fehlerquelle.

Code: Alles auswählen

zeit = time.strftime("%a:%d.%m.%Y %H:%M:%S")	

#Sensor auslesen
temperature = sensor.read_temperature()
humidity = sensor.read_humidity()

#Daten in Datei schreiben
with open ("Messdaten.txt", "a") as output:
    output.write('{}\t{:.1f}\t{:.1f}\n'.format(zeit, temperature, humidity)

Code: Alles auswählen

#Daten lesen
dates = []
temperatures = []
humidities = []
with open(datei_pfad, 'r') as lines: 
    for line in lines:
        date, temperature, humidity = line.split('\t')
        dates.append(date)
        temperatures.append(float(temperature))
        humidities.append(float(humidity))
Robbse1990
User
Beiträge: 16
Registriert: Montag 16. Oktober 2017, 10:29

Meinst du mit Fehlerquelle das wenn ein Fehler in der Zeile auftraucht, alles nicht mehr passt? Oder gibts da noch mehr "Gefahren"? Ich habe wenig Ahnung davon, was Python wirklich macht, bzw wie es arbeitet.
Antworten