#!/usr/bin/python -tt #======= #Crediti #======= # esercizi corso di python @ifac-cnr # Copyright 2012 Nicola ZOppetti # Licensed under the Apache License, Version 2.0 # http://www.apache.org/licenses/LICENSE-2.0 #==================== #Indicazioni generali #==================== # RIEMPIRE LE FUNZIONI # DOVE COMPARE IL COMMENTO # +++METTI QUI IL TUO CODICE+++ # Seguire le istruzioni riportate nel commento # precedente ciascuna funzione da riempire # Una volta studiata una soluzione ad un esercizio, per verificare se è corretta eseguire QUESTO SCRIPT # per un generico 'esercizio 1', se la soluzione è errata o non data # sullo standard output viene stampato il prefisso KO, il valore restituito e quello atteso # >>> esercizio 1 # >>> KO restituisce: None, risultato atteso: [98, 55, 10, 8, 2] # # Se la soluzione è corretta: # sullo standard output viene stampato OK # >>> esercizio 1 # >>> OK #=============== #INIZIO ESERCIZI #=============== # scrivifile(nome,cognome,gg,mm,aaaa,interessi,pathfile) # ---------------------------------------------------- # scrivere una funzione che # si aspetta i seguenti argomenti: # - nome,cognome, interessi sono delle stringhe # - gg,mm,aaaa sono degli interi che rappresentano la data di nascita # - pathfile è una stringa che identifica il nome di un file # la funzione deve creare il file testuale (pathfile) # contenente i seguenti dati, uno per riga: # 'nome: ' # 'cognome: ' # 'datadinascita: 'una stringe in formato gg-mm-aa** che rappresenta la data # le ultime due cifre dell'anno devono essere mascherate con due caratteri che non siano numeri ;-) # 'interessi: ' # il file deve avere quindi 4 righe, # la prima deve iniziare con 'nome:' # la seconda con 'cognome:' # la terza con 'datadinascita:' seguito da uno spazio e dalla data di nascita in formato gg-mm-aaXX # la quarta con 'interessi:' # # suggerimenti: # - riguardare la lezione sulle stringhe ed in particolare la funzione format # - usare la divisione intera per determinare le prime due cifre dell'anno def scrivifile(nome,cognome,gg,mm,aaaa,interessi,pathfile): ##-METTI-QUI-IL-TUO-CODICE-## return # leggifile(pathfile): # --------- # leggere il file creato nell'esercizio precedente e restituire un dizionario # del tipo # { # 'nome' : la stringa letta dopo i ':' della prima riga, eliminando gli eventuali spazi iniziali , # 'cognome' : la stringa letta dopo i ':' della seconda riga, eliminando gli eventuali spazi iniziali , # 'datadinascita' : la stringa letta dopo i ':' della terza riga, eliminando gli eventuali spazi iniziali # 'interessi': la stringa letta dopo i ':' della letta dalla quarta riga, eliminando gli eventuali spazi iniziali # } # # la funzione dovrebbe permettere di leggere anche eventuali campi aggiuntivi # presenti dalla quinta riga in poi con formato # nomecampo: valore # ed aggiungerli al dizionario come stringhe # ad es. # "segni particolari : nessuno" # dovrebbe avere nel dizionario un'occorrenza # { # .... # 'segni particolari' : 'nessuno' # } # # inoltre la funzione dovrebbe permettere di gestire anche righe che contengono più volte il carattere ':', ad esempio la riga # "note: a noi il carattere : non ci spaventa" # dovrebbe avere nel dizionario un'occorrenza # { # .... # 'note' : 'il carattere : non ci spaventa' def leggifile(pathfile): ##-METTI-QUI-IL-TUO-CODICE-## return # leggifile2(pathfile): # --------- # come la precedente ma con gestione speciale della terza riga per # la quale si scorporano il mese il giorno come interi e la stringa che indica l'anno. # il dizionario restituito avrà la forma: # { # .... # 'gg' : intero che indica il giorno, letto dalla terza riga # 'mm' : intero che indica il mese, letto dalla terza riga # 'aa' : stringa dell'anno '19**', , letta dalla terza riga # ..... # } # # suggerimento: # valutare se conviene usare la funzione leggifile # sfruttare la conoscenza del formato della data insieme # agli slice per isolare le porzioni di riga di interesse def leggifile2(pathfile): ##-METTI-QUI-IL-TUO-CODICE-## return # scrivifilebin(pathfile) # ----------------------- # creare un file binario con path 'pathfile' che contiene 10 bytes con valori 5,10, ...., 50 def scrivifilebin(pathfile): ##-METTI-QUI-IL-TUO-CODICE-## return # appendiafilebin(pathfile) # ----------------------- # 'appendere' a un generico file binario con path 'pathfile' # la stringa 'perché' codificata in utf-8 # l'aggiunta deve avvenire solo se il file esiste # se il file non esiste stampare su stdout il messaggio 'IL FILE pathfile NON ESISTE' # dove pathfile è il path del file # suggerimento: # testare l'esistenxa del file con la funzione os.path.exists import os.path def appendiafilebin(pathfile): ##-METTI-QUI-IL-TUO-CODICE-## return # leggifilebin(pathfile): # ----------------------- # leggere un file binario che contiene: # - i primi 6 bytes rappresentano 3 interi i1,..,i3 ciascuno rappresentato con 2 bytes # - i successivi 6 bytes rappresentano una stringa s di 6 caratteri (ascii) # - i successifi bytes rappresentano 3 numeri floating point f1,..,f3 in doppia prescisione # la funzione restituisce la toupla (i1,i2,i3,s,f1,f2,f3) # suggerimenti: # - usare il modulo struct # - nella stringa di formato specificare allineamento native e standard size ('=') # - usare il formato 'short' (h) per gli interi di 2 bytes import struct def leggifilebin(pathfile): ##-METTI-QUI-IL-TUO-CODICE-## return #============== # FINE ESERCIZI #============== # NON MODIFICARE DA QUI IN POI!!!!!!!! import re # FUNZIONE test() usata in main() per stampare # cosa restituisce ciascuna funzione vs. cosa dovrebbe restituire quella corretta def test(got, expected): if got == expected: prefix = ' OK ' print(' OK') else: prefix = ' KO ' print('%s restituisce: %s, risultato atteso: %s' % (prefix, repr(got), repr(expected))) def test_scrivifile(pathfile='mydati.txt',nome='nicola',cognome='zoppetti',gg=13,mm=9,aaaa=1984,interessi='mentire sulla data di nascita'): scrivifile(nome,cognome,gg,mm,aaaa,interessi,pathfile) if not os.path.exists(pathfile): print('KO, il file non è stato creato') return with open(pathfile,'rt') as fl: rows=fl.readlines() if len(rows) != 4: print('KO: il file non ha 4 righe') return if rows[0].split(':')[0] != 'nome': print('KO: la prima riga non comincia con nome:') return if rows[1].split(':')[0] != 'cognome': print('KO: la seconda riga non comincia con cognome:') return if rows[2].split(':')[0] != 'datadinascita': print('KO: la terza riga non comincia con datadinascita:') return if rows[3].split(':')[0] != 'interessi': print('KO: la quarta riga non comincia con interessi:') return m=re.search(r'(\d\d)[-/](\d\d)[/-](\d\d)\D\D',rows[2].split(':')[1]) if not m: print('KO: ci sei quasi ma il formato della data non è valido!!') return if int(m.group(1)) != gg: print('KO: non torna il giorno: ho letto {0}, mi aspettavo {1}'.format(m.group(1),gg)) return if int(m.group(2)) != mm: print('KO: non torna il mese: ho letto {0}, mi aspettavo {1}'.format(m.group(2),mm)) return if int(m.group(3)) != aaaa//100: print("KO: non torna l'anno: ho letto {0}**, mi aspettavo {1}**".format(m.group(2),mm)) return print('OK!!') return def test_leggifile(pathfile='mydati.txt',nome='nicola',cognome='zoppetti',gg=13,mm=9,aaaa=1984,interessi='mentire sulla data di nascita'): scrivifile(nome,cognome,gg,mm,aaaa,interessi,pathfile) with open(pathfile,'at') as fl: fl.write('\n') fl.write('segni particolari: nessuno\n') fl.write('note: il carattere : non ci spaventa') d = leggifile(pathfile) expecteddict= { 'nome': nome, 'cognome': cognome, 'datadinascita': '{0:02d}-{1:02d}-{2:02d}**'.format(gg,mm,aaaa//100), 'interessi': interessi, 'segni particolari': 'nessuno', 'note': 'il carattere : non ci spaventa' } test(d,expecteddict) def test_leggifile2(pathfile='mydati.txt',nome='nicola',cognome='zoppetti',gg=13,mm=9,aaaa=1984,interessi='mentire sulla data di nascita'): scrivifile(nome,cognome,gg,mm,aaaa,interessi,pathfile) with open(pathfile,'at') as fl: fl.write('\n') fl.write('segni particolari: nessuno\n') fl.write('note: il carattere : non ci spaventa') d = leggifile2(pathfile) expecteddict= { 'nome': nome, 'cognome': cognome, 'gg': gg, 'mm': mm, 'aaaa': '{0:02d}**'.format(aaaa//100), 'interessi': interessi, 'segni particolari': 'nessuno', 'note': 'il carattere : non ci spaventa' } test(d,expecteddict) def test_scrivifilebin(pathfile='mybinfl.bin'): scrivifilebin(pathfile) if not os.path.exists(pathfile): print('KO, il file non è stato creato') return with open(pathfile,'rb') as fl: data = fl.read() return test(data, b'\x05\n\x0f\x14\x19\x1e#(-2') from io import StringIO import sys def test_appendiafilebin(pathfile='mybinfl.bin'): scrivifilebin(pathfile) appendiafilebin(pathfile) if not os.path.exists(pathfile): print('KO, il file non è stato creato') return with open(pathfile,'rb') as fl: data = fl.read() test(data, b'\x05\n\x0f\x14\x19\x1e#(-2perch\xc3\xa9') #provo con un file che non esiste ed intercetto cosa viene scritto su stdout #maschero stdout con il mio stdout (uno stream testuale in memoria) old_stdout = sys.stdout sys.stdout = mystdout = StringIO() #uso la funzione appendiafilebin('pathfilechenonesiste') #recupero cosa scritto nello stdout mystdout.seek(0) myretstr = mystdout.read() #ripristino lo stdout sys.stdout = old_stdout #testo cosa scritto sullo stdout test(myretstr, 'IL FILE pathfilechenonesiste NON ESISTE\n') return def test_leggifilebin(pathfile='mybinfl.bin'): i1 = 10 i2 = 3899 i3 = 2222 s = 'nicola' f1 = 1.e5 f2 = 0.234 f3 = -1.456e9 with open(pathfile,'wb') as myflbin: dataw = struct.pack('=hhh6sddd',i1,i2,i3,s.encode('ascii'),f1,f2,f3) myflbin.write(dataw) retval=leggifilebin(pathfile) if retval: i1r,i2r,i3r,sr,f1r,f2r,f3r = retval else: i1r,i2r,i3r,sr,f1r,f2r,f3r = None,None,None,None,None,None,None test((i1r,i2r,i3r,sr,f1r,f2r,f3r),(i1,i2,i3,s,f1,f2,f3)) # chiama le funzioni-soluzione con argomenti fissati e # confronta i risultati con quelli attesi def main(): print('scrivifile') test_scrivifile() test_scrivifile(nome='pinco',cognome='panco',gg=31,mm=12,aaaa=1902,interessi='tanti') print() print('leggifile') test_leggifile() test_leggifile(nome='pinco',cognome='panco',gg=31,mm=12,aaaa=1902,interessi='tanti') print() print('leggifile2') test_leggifile2() test_leggifile2(nome='pinco',cognome='panco',gg=31,mm=12,aaaa=1902,interessi='tanti') print() print('scrivifilebin') test_scrivifilebin() print() print('appendiafilebin') test_appendiafilebin() print() print('leggifilebin') test_leggifilebin() # Standard boilerplate to call the main() function. if __name__ == '__main__': main()