#!/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 #=============== # -------------------- # set1(a,b,c) # -------------------- # date tre stringhe a,b,c restituire la lista ordinata # dei DIVERSI caratteri che compongono le stringhe stesse # suggerimenti: # - usare i set def set1(a,b,c): ##-INIZIO-SOLUZIONE-## s = set(a)|set(b)|set(c) return sorted(s) #return sorted(set(a+b+c)) ##-FINE-SOLUZIONE-## # -------------------- # set2(a,b,c) # -------------------- # date tre stringhe a,b,c restituire la lista ordinata # dei DIVERSI caratteri che sono usati da una sola stringa tra le tre def set2(a,b,c): ##-INIZIO-SOLUZIONE-## sa=set(a) sb=set(b) sc=set(c) return sorted((sa^sc)|(sa^sb)|(sb^sc)) #oppure: #return sorted((sa|sb|sc)-(sa&sb)-(sb&sc)-(sa&sc)) ##-FINE-SOLUZIONE-## # -------------------- # set3(wordlist) # -------------------- # data una lista di parole restituire la lista ordinata # nella quale sono stati rimossi i duplicati def set3(wordlist): ##-INIZIO-SOLUZIONE-## return sorted(set(wordlist)) #oppure: #return sorted({w for w in wordlist})#occhio alle parentesi graffe!!! ##-FINE-SOLUZIONE-## # -------------------- # set4(a,b) # -------------------- # date due stringhe a e b: # se non hanno alcun carattere in comune -> restituire le due stringhe # concatenate, separate da uno spazio # se hanno anche 1 solo carattere in comune -> restituire la stringa composta # dai caratteri in comune, ordinati # suggerimento: # provare a digitare help(set.isdisjoint) nella shell # provare a digitare help(str.join) nella shell def set4(a,b): ##-INIZIO-SOLUZIONE-## sa = set(a) sb = set(b) if set.isdisjoint(sa,sb): return a + ' ' + b else: return ''.join(sorted(sa&sb)) #oppure: #sc = sa& sb #if len(sc)==0: # return a + ' ' + b #else: # return ''.join(sorted(sc)) ##-FINE-SOLUZIONE-## # -------------------- # set5(st,elm): # -------------------- # dato un set st ed un generico elemento elm (di un qualsiasi tipo) # restituire la stringa 'IN' se elm appartiene a st # restituire la stringa 'OUT' se elm NON appartiene a st def set5(st,elm): ##-INIZIO-SOLUZIONE-## return 'IN' if elm in st else 'OUT' #oppure: #if elm in st: # return 'IN' #else: # return 'OUT' ##-FINE-SOLUZIONE-## #--------------------- # dictdalista(listanomicognomi) #--------------------- # data una lista di stringhe ciascuna contenente # un nome ed un cognome, separati da virgole # restituire un dizionario con il cognome come chiave ed il nome come valore # nota: x semplicità, non è necessario implementare controlli sulla validità # degli argomenti def dictdalista(listanomicognomi): ##-INIZIO-SOLUZIONE-## return dict(reversed(s.split(',')) for s in listanomicognomi) #oppure: #return { s.split(',')[1] : s.split(',')[0] for s in listanomicognomi } ##-FINE-SOLUZIONE-## # dictnum(num) # dato un numero num restituire un dizionario che abbia # - come chiavi gli interi da 0 alla parte intera di num # - come valori una toupla che contiene rispettivamente # il quadrato ed il cubo della chiave def dictnum(num): ##-INIZIO-SOLUZIONE-## return { n : (n**2,n**3) for n in range( int(num) )} ##-FINE-SOLUZIONE-## #--------------------- # dictannidato() #--------------------- # Restituire il dizionario con due chiavi "Tom" e "Sally" # con i valori illustrati nel commento sottostante # suggerimento: la chiave è una stringa il valore un dizionario # >>> contactinfo["Tom"] # {'Email':'tom@gmail.com', 'Phone':61234567} # >>> contactinfo["Sally"] # {'Email':'sally@hotmail.com', 'Phone':67654321} def dictannidato(): ##-INIZIO-SOLUZIONE-## contactinfo = { 'Tom' : {'Email':'tom@gmail.com','Phone':61234567}, 'Sally' : {'Email':'sally@hotmail.com','Phone':67654321} } return contactinfo ##-FINE-SOLUZIONE-## #--------------------- # dictquiz1() #--------------------- # Quale delle seguenti inizializzazioni genera un errore? # d1 = {"Name": "Tom" } # d2 = { (1,3,4): 4.5 } # d3 = { ["First", "Last"]: (1,3) } # d4 = { 1: 0.4 } # restituire il numero che indica il dizionario errato (1 per d1, 2 per d2 ...) def dictquiz1(): ##-INIZIO-SOLUZIONE-## return 3 #la chiave deve essere NON-mutable, le liste sono MUTABLE ##-FINE-SOLUZIONE-## #--------------------- # dictquiz2() #--------------------- # dato d = { "a" : 1 , "b" : 2 }. quale delle seguenti espressioni vale [1,2]? # 1 d.keys() # 2 d.values() # 3 d.items() # 4 d.popitem() # 5 Nessuna delle precedenti # restituire il numero che indica la risposta esatta def dictquiz2(): ##-INIZIO-SOLUZIONE-## return 2 ##-FINE-SOLUZIONE-## #--------------------- # dictcase(option) #--------------------- # Considerare il seguente algoritmo: # # se opzione == 'A' restituire 'opzione A' # se opzione == 'B' restituire 'opzione B' # se opzione == 'C' restituire 'opzione C' # in tutti gli altri casi restituire 'opzione non valida' # # in python non esiste il costrutto switch ... case # quindi, per realizzare quanto descritto sopra # - possiamo utilizzare una serie di if ... elif ... else # - possiamo utilizzare un dizionario # # implementare l'algoritmo scritto sopra mediante un dizionario # suggerimento: # help(dict.get) def dictcase(option): ##-INIZIO-SOLUZIONE-## # - inizializzare un dizionario # - usaro il metodo get(key[, default]) dei dizionari per gestire l'opzione non valida casedict={ 'A' : 'opzione A', 'B' : 'opzione B', 'C' : 'opzione C' } return casedict.get(option,'opzione non valida') ##-FINE-SOLUZIONE-## #--------------------- # composizione(sequenza) #--------------------- # Una sequenza di DNA è solitamente costituita da 4 basi nucleotidiche # ed è rappresentato con una stringa costituita dalle lettere: A, T, C, G. # Scrivere una funzione che calcola la composizione base di una sequenza di DNA determinata. # La funzione deve ignorare gli eventuali caratteri non validi # # esempi # >>> composizione("CTATCGGCACCCTTTCAGCA") # {'A': 4, 'C': 8, 'T': 5, 'G': 3 } # >>> composizione("AGT") # {'A': 1, 'C': 0, 'T': 1, 'G': 1 } # >>> composizione("AGXTXX") # {'A': 1, 'C': 0, 'T': 1, 'G': 1 } def composizione(sequenza): ##-INIZIO-SOLUZIONE-## compodict={'A':0,'T':0,'C':0,'G':0} for c in compodict: compodict[c] = sequenza.count(c) #oppure #for b in sequenza: # if b in compodict: # compodict[b] += 1 return compodict #oppure #return {v:sequenza.count(v) for v in 'ATCG'}#bellino!! ##-FINE-SOLUZIONE-## #--------------------- # contaLettere(parola) # -------------------- # Scrivi una funzione che restituisce un dizionario che conta # il numero di volte in cui ogni lettera appare nella parola passata # come argomento. # # Esempi: # >>> contaLettere('google') # {'e': 1, 'g': 2, 'l': 1, 'o': 2} # >>> contaLettere('apple') # {'a': 1, 'e': 1, 'l': 1, 'p': 2} # >>> contaLettere('') # {} # suggerimento: # - help(dict.get) def contaLettere(parola): ##-INIZIO-SOLUZIONE-## return {v : parola.count(v) for v in set(parola)} #oppure: #d={} #for c in parola: # d[c]=d.get(c,0)+1 #return d #oppure: #d={} #s=set(parola) #for c in s: # d[c]=parola.count(c) #return d ##-FINE-SOLUZIONE-## #--------------------- # reverseLookup #--------------------- # Scrivi una funzione che accetta come argomenti un dizionario e un valore # e restituisce un elenco ordinato di tutte le chiavi associate a quel valore. # La funzione restituisce una lista vuota se non viene trovata una corrispondenza. # # Esempi: # >>> reverseLookup({'a':1, 'b':2, 'c':2}, 1) # ['a'] # >>> reverseLookup({'a':1, 'b':2, 'c':2}, 2) # ['b', 'c'] # >>> reverseLookup({'a':1, 'b':2, 'c':2}, 3) # [] def reverseLookup(dictionary, value): ##-INIZIO-SOLUZIONE-## retlist=[] for k,v in dictionary.items(): if v==value: retlist.append(k) return sorted(retlist) #oppure: #return sorted([k for k in dictionary.keys() if dictionary[k] == value]) ##-FINE-SOLUZIONE-## #--------------------- # invertiDizionario(d) #--------------------- # Scrivere una funzione che accetta come argomento un dizionario e # restituisce un dizionario che inverte le chiavi ed i valori del dizionario # originale. # Gestire gli eventuali valori doppi come illustrato negli esempi cioè creare # un dizionario che ha per valori la lista delle chiavi del dizionario originale # suggerimento: # - considerare la funzione membro dict.setdefault(key,default) # Esempi: # >>> invertiDizionario({'a':1, 'b':2, 'c':3, 'd':2}) # {1: ['a'], 2: ['b', 'd'], 3: ['c']} # >>> invertiDizionario({'a':3, 'b':3, 'c':3}) # {3: ['a', 'c', 'b']} # >>> invertiDizionario({'a':2, 'b':1, 'c':2, 'd':1}) # {1: ['b', 'd'], 2: ['a', 'c']} def invertiDizionario(d): ##-INIZIO-SOLUZIONE-## retdict={} for k,v in d.items(): retdict.setdefault(v,[]).append(k) return retdict #oppure: #creare un set dei valori ed iterare su di esso #invece che su tutti gli elementi del dizionario #.... # ##-FINE-SOLUZIONE-## #--------------------- # sparse2dict(numbers) # -------------------- # # Un vettore sparso è un vettore i cui elementi sono quasi tutti zero, come # [1, 0, 0, 0, 0, 0, 0, 2, 0]. # I dizionari sono comunemente utilizzati per tenere traccia dei soli elementi non nulli. # Ad esempio, il vettore illustrato in precedenza può essere rappresentato come # {0:1, 7:2} # poiché il vettore ha il valore 1 all'indice 0 e il valore 2 all'indice 7. # Scrivere una funzione che converte un vettore sparso in un dizionario come descritto sopra. # Esempi: # # >>> sparse2dict([1, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 4]) # {0: 1, 3: 2, 7: 3, 12: 4} # >>> sparse2dict([1, 0, 1 , 0, 2, 0, 1, 0, 0, 1, 0]) # {0: 1, 2: 1, 4: 2, 6: 1, 9: 1} # >>> sparse2dict([0, 0, 0, 0, 0]) # {} def sparse2dict(numbers): ##-INIZIO-SOLUZIONE-## retdict = {} for i,n in enumerate(numbers): if n: retdict[i]=n return retdict ##-FINE-SOLUZIONE-## #------------------------- # dict2sparse(sparsedict) # ----------------------- # # Un vettore sparso è un vettore i cui elementi sono quasi tutti zero, come # [1, 0, 0, 0, 0, 0, 0, 2, 0]. # I dizionari sono comunemente utilizzati per tenere traccia dei soli elementi non nulli. # Ad esempio, il vettore illustrato in precedenza può essere rappresentato come # {0:1, 7:2} # poiché il vettore ha il valore 1 all'indice 0 e il valore 2 all'indice 7. # Scrivere una funzione che converte un dizionario nella sua rappresentazione vettoriale sparsa. # Esempi: # >>> dict2sparse({0: 1, 3: 2, 7: 3, 12: 4}) # [1, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 4] # >>> dict2sparse({0: 1, 2: 1, 4: 2, 6: 1, 9: 1}) # [1, 0, 1, 0, 2, 0, 1, 0, 0, 1] # >>> dict2sparse({}) # [] def dict2sparse(dictionary): ##-INIZIO-SOLUZIONE-## retlist=[] #gestisco il caso di dizionario vuoto if dictionary == {}: return retlist #ricavo il massimo indice del vettore #il vettore avrà (n+1) elementi n=max(dictionary.keys()) #itero su tutti gli indici del vettore (compreso n) for i in range(n+1): if i in dictionary: #se l'indice è nel dizionario come chiave #inserisco il relativo valore nella lista ... retlist.append(dictionary[i]) else: #altrimenti ci metto 0 retlist.append(0) return retlist # oppure: # creare un vettore con tutti zeri # e poi riassegnare il valore agli elementi non nulli # ##-FINE-SOLUZIONE-## #============== # FINE ESERCIZI #============== # NON MODIFICARE DA QUI IN POI!!!!!!!! # 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_float(got,expected,eps=1.e-6): if got == None: print(' KO restituisce: None, risultato atteso: %s' % (repr(expected))) return if abs(got-expected)< eps: prefix = ' OK ' print(' OK') else: #print('KO') prefix = 'KO ' print('%s restituisce: %s, risultato atteso: %s' % (prefix, repr(got), repr(expected))) def test_quiz(got,expected): if got == expected: print(' OK, RISPOSTA ESATTA') else: print(' KO, RISPOSTA SBAGLIATA') # chiama le funzioni-soluzione con argomenti fissati e # confronta i risultati con quelli attesi def main(): print('set1') test(set1('pippo','pappo','puppo'),['a', 'i', 'o', 'p', 'u']) print('set2') test(set2('pippo','pappo','puppo'),['a', 'i', 'u']) print('set3') test(set3('forti precipitazioni e e e temperature in picchiata in tutto il nord nord paura in liguria frane allagamenti e frane '.split()), ['allagamenti', 'e', 'forti', 'frane', 'il', 'in', 'liguria', 'nord', 'paura', 'picchiata', 'precipitazioni', 'temperature', 'tutto']) print('set4') test(set4('buon','caffè'), 'buon caffè') test(set4('buon','giorno'), 'no') print('set5') test(set5(set('abcde'),'a'),'IN') test(set5(set('abcde'),'k'),'OUT') test(set5(set('abcde'),1),'OUT') test(set5(set(range(10)),'a'),'OUT') print('dictdalista') test(dictdalista(['gino,gini','arturo,arturi','raffaello,raffaelli']), {'gini':'gino','arturi':'arturo','raffaelli':'raffaello'}) print('dictnum') test(dictnum(5),{0:(0,0),1:(1,1),2:(4,8),3:(9,27),4:(16,64)}) print('dictannidato') test(dictannidato(),{'Tom':{'Email':'tom@gmail.com','Phone':61234567}, 'Sally':{'Email':'sally@hotmail.com','Phone':67654321}}) print('dictquiz1') test_quiz(dictquiz1(),23+27//9-46//2) print('dictquiz2') test_quiz(dictquiz2(),17+21//7-45//3-3) print('dictcase') test(dictcase('A'),'opzione A') test(dictcase('B'),'opzione B') test(dictcase('C'),'opzione C') test(dictcase('X'),'opzione non valida') test(dictcase(1),'opzione non valida') print('composizione') test(composizione("CTATCGGCACCCTTTCAGCA"), {'A': 4, 'C': 8, 'T': 5, 'G': 3 }) test(composizione("AGT"),{'A': 1, 'C': 0, 'T': 1, 'G': 1 }) test(composizione("AXXGHHT"),{'A': 1, 'C': 0, 'T': 1, 'G': 1 }) print('contaLettere') test(contaLettere('google'),{'e': 1, 'g': 2, 'l': 1, 'o': 2}) test(contaLettere('apple'),{'a': 1, 'e': 1, 'l': 1, 'p': 2}) test(contaLettere(''),{}) print('reverseLookup') test(reverseLookup({'a':1, 'b':2, 'c':2}, 1),['a']) test(reverseLookup({'a':1, 'b':2, 'c':2}, 2),['b', 'c']) test(reverseLookup({'a':1, 'b':2, 'c':2}, 3),[]) print('invertiDizionario') test(invertiDizionario({'a':1, 'b':2, 'c':3, 'd':2}),{1: ['a'], 2: ['b', 'd'], 3: ['c']}) test(invertiDizionario({'a':3, 'b':3, 'c':3}),{3: ['a', 'c', 'b']}) test(invertiDizionario({'a':2, 'b':1, 'c':2, 'd':1}),{1: ['b', 'd'], 2: ['a', 'c']}) print('sparse2dict') test(sparse2dict([1, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 4]),{0: 1, 3: 2, 7: 3, 12: 4}) test(sparse2dict([1, 0, 1 , 0, 2, 0, 1, 0, 0, 1, 0]),{0: 1, 2: 1, 4: 2, 6: 1, 9: 1}) test(sparse2dict([0, 0, 0, 0, 0]), {}) print('dict2sparse') test(dict2sparse({0: 1, 3: 2, 7: 3, 12: 4}), [1, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 4]) test(dict2sparse({0: 1, 2: 1, 4: 2, 6: 1, 9: 1}),[1, 0, 1, 0, 2, 0, 1, 0, 0, 1]) test(dict2sparse({}),[]) # Standard boilerplate to call the main() function. if __name__ == '__main__': main()