''' Esempio di generazione di un file di dati tabellati, separati da tab. Con 3 valori per riga (indice, lettera, float) Lettura del file Con commenti preceduti da # (in prima colonna) Con linee vuote ignorate Calcolo della media e varianza della colonna float Calcolo della frequenza delle lettere nella 2° colonna ''' import random def sensore(): ''' Genero una coppia di valori: - lettera scelta a caso in una stringa - float scelto con distribuzione di Gauss con media 180 e varianza 5 ''' lettere = 'AFRQFWQGQERH' indice = random.randint(0, len(lettere)-1) media = 180 varianza = 5 valore = random.gauss(media, varianza) return lettere[indice], valore def log_dati(dati, filename): ''' Salvo una lista di triple in un file, separate da tab ''' with open(filename, mode='a') as f: linea = '\t'.join([str(v) for v in dati]) f.write(linea + "\n") def log_N_dati(N, filename): ''' Genero N triple e le salvo in un file - indice - lettera e valore dal sensore ''' for i in range(N): L, V = sensore() log_dati((i, L, V), filename) def read_log(filename): ''' Leggo un file di log e: - ignoro linee vuote e commenti con # in prima colonna - segnalo linee con meno o più di 3 valori - segnalo linee in cui il 3° valore non è un float - calcolo la media dei valori della 3° colonna - calcolo la varianza rileggendo di nuovo il file - calcolo la percentuale di lettere apparse in 2° colonna ''' somma = 0 # somma dei valori letti (per la media) numero = 0 # numero di valori letti (per la media) num_linee = 0 # numero di linea (per il messaggio di errore) lettere = {} # conteggio delle lettere lette in 2° colonna with open(filename) as f: for line in f: line = line.strip() # elimino spazi e accapi prima e dopo num_linee += 1 # conto le linee lette if not line: # se la linea è vuota continue # la ignoro e passo alla prossima if line[0] == '#': # se inizia con # è un commento continue # la ignoro e passo alla prossima valori = line.split('\t') # spezzo la linea sugli spazi try: (i, L, v) = valori # mi aspetto 3 valori except: # se non sono 3 catturo l'eccezione e mando un messaggio print('la linea {} non contiene 3 valori: {}'.format(num_linee,valori)) continue # ignoro la linea e vado avanti if v == '--': # se la terza colonna contiene '--' continue # la ignoro if L in lettere: # conto le lettere lettere[L] += 1 else: lettere[L] = 1 try: # provo a convertire la 3° colonna in float somma += float(v) except: # se non è un float do un messaggio di errore print('la linea {} contiene un valore non numerico: {}'.format(num_linee,v)) continue # e la ignoro numero += 1 # se i dati erano OK li conto for k in lettere: # trasformo i numeri in percentuali lettere[k] /= numero lettere[k] *= 100 lettere[k] = round(lettere[k], 2) # con 2 cifre decimali media = somma/numero # calcolo la media sommaQ = 0 # x la varianza serve una seconda somma with open(filename) as f: # rileggo il file for line in f: line = line.strip() if not line: continue if line[0] == '#': continue valori = line.split('\t') try: (i, L, v) = valori except: continue if v == '--': continue try: # sommo lo scarto del valore dalla media, al quadrato sommaQ += (float(v)-media)**2 except: continue varianza = (sommaQ/numero)**0.5 # la varianza è la sqrt della media return media, varianza, numero, lettere if __name__ == '__main__': #log_N_dati(10000, 'dati.log') print(read_log('dati.log'))