#! /usr/bin/env python3 # coding=utf8 import os import csv class Temperatur: def __init__(self, day, month, year, hour, min, sec, temp): self.day=day self.month=month self.year = year self.hour=hour self.min=min self.sec = sec self.temp=temp def equalDMY(self,t): return self.day==t.day and self.month==t.month and self.year==t.year # Monatsmittelwerte def equalMY(self,t): return self.month==t.month and self.year==t.year def getCSVList(self): liste = [] liste.append( str(self.day)+'.'+str(self.month)+'.'+str(self.year) ) liste.append( str(self.hour)+':'+str(self.min)+':'+str(self.sec) ) liste.append( str(self.temp).replace('.',',') ) return liste def __str__(self): # toString return str(self.day)+'/'+str(self.month)+'/'+str(self.year)+' '+ \ str(self.hour)+':'+str(self.min)+' '+str(self.temp).replace('.',',') def toInt(sValue): try: value = int(sValue) return value except: return None def toFloat(sValue): try: sValue = sValue.replace(',' , '.') value = float(sValue) return value except: return None def divideDate(datum,dateSplitchar): ok=True errortext='' day=0 month=0 year=0 datelist = datum.split(dateSplitchar) if len(datelist)==3: day=toInt(datelist[0]) # fehlerhaft wenn datum[0] = abc 12.3 12,4 month=toInt(datelist[1]) year=toInt(datelist[2]) if day==None or month==None or year==None: ok=False errortext='Tag, Monat oder Jahr ist nicht numerisch (int): '+datum+' Tag: '+str(day)+' Monat: '+str(month)+' Jahr: '+str(year) else: # alles okay # hier wissen wir, dass alle drei Elemente Zahlen sind ! # Prüfen, ob die drei Werte in den richtigen Bereichen liegen if day<1 or day>31 or month<1 or month>12 or year<1900: ok=False errortext="Tag oder Monat oder jahr ist außerhalb des gültigen Bereiches: "+day+' '+month+' '+year # es fehlt Abfrage korrekte Tag Februar, 31. November etc. /100 teilbar: 1900/2000/2100 year%400=0 else: %4 else: ok=False errortext='Zu wenige Elemente im Datumsformat: '+datum return (ok, errortext, day,month,year) # Tupel oder Array,Feld def divideTime(timeString, splitChar): ok=True errortext='' hour=0 min=0 sec=0 timeList = timeString.split(splitChar) # 23:55:45 if len(timeList)==3: # alles okay, man hat drei Elememte hour=toInt(timeList[0]) min=toInt(timeList[1]) sec=toInt(timeList[2]) if hour==None or min==None or sec==None: errortext="Entweder sind Stunden oder Minute oder Sekunden numerisch fehlerhaft: "+timeString ok=False # eventuell Fehlertext else: # hier wissen wir, dass alle drei Elemente zahlen sind ! # Prüfen, ob die drei Werte in den richtigen Bereichen liegen if hour<0 or hour>24 or min<0 or min>=60 or sec<0 or sec>60: # Schaltsekunde!!! ok=False errortext="Entweder die Stunden oder die Minute oder die Sekunden liegen außerhalb des gültigen Bereiches: "++timeString else: # Fehler, zu wenige Elemente errortext="zu wenige Elemente" ok=False return (ok, errortext, hour, min, sec) # Rückgabe ist eine Tupel=Array # datei prüfen auf Vorhandensein # datei zeilenweise lesen # Zeile trennen nach datum Uhrzeit und Wert # Eintragen in eine Instanz der Klasse Temperatur # Eintragen in eine Liste # Datum Zeit T # 495388 # 16-04-1996 16:10:00 14,8 # 16/04/1996 16:10:00 14,8 def readTemperaturliste(filename, dateSplitchar, timeSplitchar ): print(filename) if not os.path.isfile(filename): print('Die Datei existiert nicht\n'+filename) return handle = open(filename,'r+t') # r=read t=textdatei caption = handle.readline().strip() # strip löscht zeilentrenner print(caption) dummy = handle.readline().strip() # dummy liest aktuelle Zeile als String anzahl = toInt(dummy) if anzahl==None: print('Fehlerhafte Anzahl: '+dummy) handle.close() return None liste = [] # liste der Temperaturen for i in range(anzahl): dummy = handle.readline().strip() # dummy liest aktuelle Zeile als String sections = dummy.split('\t') # trennen nach den tabs zwischen datum Zeit und Tempwert if len(sections)==3: # alles okay pass else: print('Fehlerhafte Anzahl der Zeile: '+dummy) handle.close() return None # nun haben wir 3 section Datum/Zeit/tempValue datum= sections[0] # 16-04-1996 zeit= sections[1] # 16:10:00 tempValue= sections[2] # 14,8 (ok1, errortext, day,month,year) = divideDate(datum,dateSplitchar) if not ok1: print(errortext) (ok2, errortext, hour, min,sec) = divideTime(zeit,timeSplitchar) if not ok2: print(errortext) messwert = toFloat(tempValue) if messwert==None: print('Fehlerhafter Messwert: '+tempValue) if ok1 and ok2 and messwert!=None: # alle drei okay temp = Temperatur(day,month,year, hour,min,sec,messwert) liste.append(temp) else: handle.close() return liste print('ende: Anzahl der Messwerte: ',len(liste)) handle.close() return liste def calcAverageTemp(liste): summe=0.0 for tempValue in liste: # Instanz der Klasse Temperatur summe+=tempValue.temp mittelwert = summe / len(liste) print(mittelwert) def calcAverageTempDay(liste): ergliste=[] anzahlProTag=0 tempActual=None # Vergleich 17/2/2000 mit 18/2/2000 for t in liste: # Instanz der Klasse Temperatur # check, ob neuer Tag if tempActual==None: # erster Datensatz tempActual = Temperatur(t.day,t.month,t.year,0,0,0, 0) tempActual.temp = t.temp anzahlProTag=1 else: if tempActual.equalDMY(t): # gleicher Tag tempActual.temp += t.temp anzahlProTag+=1 else: # wir wissen, t ist ein neuer Tag! summeTemp = tempActual.temp mittelwertTemp = summeTemp/anzahlProTag tempActual.temp = mittelwertTemp ergliste.append(tempActual) # neu starten mit dem aktuellen tag tempActual = Temperatur(t.day,t.month,t.year,0,0,0, 0) tempActual.temp = t.temp anzahlProTag=1 # hier ende der Schleife if anzahlProTag>0: # der letzte Tag muss noch abgearbeitet werden summeTemp = tempActual.temp mittelwertTemp = summeTemp/anzahlProTag tempActual.temp = mittelwertTemp ergliste.append(tempActual) return ergliste def export2CSV(liste,csvFilename): # schreiben in eine CSV-Datei handleCSV = open(csvFilename, 'w+t', newline = '') # öffnen zum Schreiben als textdatei csvwriter = csv.writer(handleCSV, delimiter = ';', quotechar = '|', quoting = csv.QUOTE_MINIMAL) captions = ['Date', 'Time', 'Temperatur'] csvwriter.writerow(captions) for t in liste: csvwriter.writerow(t.getCSVList()) # [1,2,3] handleCSV.close() os.startfile(csvFilename) def menu(path,temperaturListe): while True: print() print('Menueauswahl für die Mittelwert-Berechnung'); print('A: Alle Messwerte'); print('Y: Year'); print('M: Month'); print('D: Day'); print('H: Hour'); print('E: Ende'); wahl = input("Eingabe: ") if wahl!=None: # Abfrage, ob eine gültige Zahl eingegeben wurde wahl = wahl.lower() if wahl=='a': calcAverageTemp(temperaturListe) elif wahl=='d': ergliste = calcAverageTempDay(temperaturListe) for t in ergliste: print(t) export2CSV(ergliste,path+'tempTag.csv') elif wahl=='m': calcAverageTempMonth(temperaturListe) elif wahl=='y': pass elif wahl=='e': return ('',None) break else: print('Bitte nur die Buchstaben A,D,M,Y,E eingeben') # main \n \r\n \t path = 'D:\\progs\\Python\\WiSe-2023\\' filename = 'luft-1996-2000.txt' temperaturliste = readTemperaturliste(path+filename,'-',':') menu(path,temperaturliste) input()