Python: Statement Complessi (Soluzioni)¶
Codice condizionale: if
¶
Soluzione:
numero = int(raw_input("scrivi un numero: ")) if numero % 2 == 0: print "pari" else: print "dispari"
Uso
else
perche’ pari e dispari sono le uniche due possibilita’.Volendo, posso esplicitare la terza possibilita’, cioe’ il caso in cui
numero
non e’ ne’ pari ne’ dispari, cosi’:if numero % 2 == 0: print "pari" elif numero % 2 == 1: print "dispari" else: print "impossibile!"
ma il codice nell’
else
non verra’ eseguito per nessun valore dinumero
!Visto che le due possibilita’ (
numero
e’ pari,numero
e’ dispari) sono mutualmente esclusive, posso anche permettermi di scrivere:if numero % 2 == 0: print "pari" if numero % 2 == 1: print "dispari"
perche’ anche in assenza dell’
else
, uno e solo uno dei dueif
puo’ essere eseguito.Soluzione:
numero = float(raw_input("scrivi un razionale: ")) if numero >= -1 and numero <= 1: print "okay"
Non servono ne’
elif
(c’e’ una sola condizione) ne’else
(se la condizione e’ falsa, non devo fare niente).Soluzione:
risposta = raw_input("scrivi due numeri separati da spazio: ") parole = risposta.split() numero1 = int(parole[0]) numero2 = int(parole[1]) if numero1 > numero2: print "primo" elif numero2 > numero1: print "secondo" else: print "nessuno dei due"
In alternativa:
risposta = raw_input("scrivi due numeri separati da spazio: ") numeri = [int(parola) for parola in risposta.split()] if numeri[0] > numeri[1]: print "primo" elif numeri[0] < numeri[1]: print "secondo" else: print "nessuno dei due"
Soluzione:
oroscopo_di = { "gennaio": "fortuna estrema", "febbraio": "fortuna galattica", "marzo": "fortuna incredibile", "aprile": "ultra-fortuna", } mese = raw_input("dimmi il tuo mese di nascita: ") if oroscopo_di.has_key(mese): print oroscopo_di[mese] else: print "non disponibile"
Soluzione:
percorso = raw_input("scrivi il percorso: ") righe = open(percorso, "r").readlines() if len(righe) == 0: print "vuoto" elif len(righe) < 100: print "piccolo", len(righe) elif len(righe) < 1000: print "medio", len(righe) else: print "grande", len(righe)
Si noti che non e’ necessario specificare per intero le condizioni: nel codice abbrevio
100 < len(righe) < 1000
conlen(righe) < 1000
. Me lo posso permettere perche’ quandolen(righe)
e’ minore di100
eseguo il primoelif
: il secondoelif
non viene neanche considerato.Soluzione:
punto1 = [float(parola) for parola in raw_input("scrivi tre coordinate: ").split()] punto2 = [float(parola) for parola in raw_input("scrivi tre coordinate: ").split()] if punto1[0] >= 0 and punto1[1] >= 0 and punto1[2] >= 0 and \ punto2[0] >= 0 and punto2[1] >= 0 and punto2[2] >= 0: diff_x = punto1[0] - punto2[0] diff_y = punto1[1] - punto2[1] diff_z = punto1[2] - punto2[2] print "la distanza e'", (diff_x**2 + diff_y**2 + diff_z**2)**0.5
Si noti che il
print
e’ dentro l’if
.Soluzione: sappiamo che
numero
e’ un intero arbitrario (puo’ essere qualunque intero deciso dall’utente). Il codice che ci interessa e’ questo:if numero % 3 == 0: print "divide 3!" elif numero % 3 != 0: print "non divide 3!" else: print "boh"
L’
if
, l’elif
e l’else
formano una catena: solo uno tra loro viene eseguito.- L’
if
viene eseguito se e solo senumero
e’ divisibile per tre. - L’
elif
viene eseguito se e solo se l’if
precedente non viene eseguito e senumero
non e’ divisibile per tre. - L’
else
viene eseguito quando ne’ l’if
ne’ l’elif
vengono eseguito.
Visto che non ci sono numeri che non siano ne’ divisibili ne’ non-divisibili per
3
, non resta alcuna altra possibilita’. O viene eseguito l’if
, o viene eseguito l’elif
: l’else
non viene mai eseguito.Quindi la risposta e’ no.
- L’
Soluzione: come sopra,
numero
e’ un intero arbitrario. Il codice e’:numero = int(raw_input("scrivi un numero: ")) if numero % 2 == 0: print "divide 2!" if numero % 3 == 0: print "divide 3!" if numero % 2 != 0 and numero % 3 != 0: print "boh"
Qui non ci sono “catene” di
if
,elif
edelse
: ci sono treif
indipendenti.- Il primo
if
viene eseguito se e solo senumero
e’ divisibile per due. - Il secondo
if
viene eseguito se e solo senumero
e’ divisibile per tre. - Il terzo
if
viene eseguito se e solo senumero
non e’ divisibile ne’ per due, ne’ per tre.
Se
numero
e’ es. 6, che e’ divisibile sia per due che per tre, allora i primi dueif
vengono entrambi eseguiti, mentre il terzo non viene eseguito.Se
numero
e’ es. 5, che non e’ divisibile ne’ per due ne’ per tre, allora i primi dueif
non vengono eseguiti; in compenso viene eseguito il terzo.Quindi la risposta e’ si’.
(Altri esempi: per
numero = 2
viene eseguito solo il primoif
, pernumero = 3
solo il secondo. Si noti pero’ che non c’e’ verso di non eseguire nessuno uno dei treif
.)- Il primo
Soluzione:
risposta = raw_input("somma o prodotto?: ") if risposta == "somma": numero1 = int(raw_input("numero 1: ")) numero2 = int(raw_input("numero 2: ")) print "la somma e'", numero1 + numero2 elif risposta == "prodotto": numero1 = int(raw_input("numero 1: ")) numero2 = int(raw_input("numero 2: ")) print "il prodotto e'", numero1 * numero2
Usare un
if
o unelif
non altera l’esecuzione del programma.Posso semplificare cosi’:
risposta = raw_input("somma o prodotto?: ") numero1 = int(raw_input("numero 1: ")) numero2 = int(raw_input("numero 2: ")) if risposta == "somma": print "la somma e'", numero1 + numero2 elif risposta == "prodotto": print "il prodotto e'", numero1 * numero2
Codice iterativo¶
Soluzioni:
Soluzione:
for numero in range(10): print numero
Soluzione:
for numero in range(10): print numero**2
Soluzione:
somma_quadrati = 0 for numero in range(10): somma_quadrati = somma_quadrati + numero**2 print somma_quadrati
Soluzione:
prodotto = 1 # occhio che qui parto da 1! for numero in range(1,10): prodotto = prodotto * numero print prodotto
Soluzione:
volume_di = { "A": 67.0, "C": 86.0, "D": 91.0, "E": 109.0, "F": 135.0, "G": 48.0, "H": 118.0, "I": 124.0, "K": 135.0, "L": 124.0, "M": 124.0, "N": 96.0, "P": 90.0, "Q": 114.0, "R": 148.0, "S": 73.0, "T": 93.0, "V": 105.0, "W": 163.0, "Y": 141.0, } somma_volumi = 0 for volume in volume_di.values(): somma_volumi = somma_volumi + volume print somma_volumi
Soluzione:
volume_di = { "A": 67.0, "C": 86.0, "D": 91.0, "E": 109.0, "F": 135.0, "G": 48.0, "H": 118.0, "I": 124.0, "K": 135.0, "L": 124.0, "M": 124.0, "N": 96.0, "P": 90.0, "Q": 114.0, "R": 148.0, "S": 73.0, "T": 93.0, "V": 105.0, "W": 163.0, "Y": 141.0, } fasta = """>1BA4:A|PDBID|CHAIN|SEQUENCE DAEFRHDSGYEVHHQKLVFFAEDVGSNKGAIIGLMVGGVV""" # estraggo la sequenza sequenza = fasta.split("\n")[1] somma_volumi = 0 # per ciascun carattere nella sequenza... for aa in sequenza: volume_di_aa = volume_di[aa] somma_volumi = somma_volumi + volume_di_aa print somma_volumi
Soluzione: adatto il codice dell’esempio sopra:
lista = [1, 25, 6, 27, 57, 12] minimo_fino_ad_ora = lista[0] for numero in lista[1:]: if numero < minimo_fino_ad_ora: minimo_fino_ad_ora = numero print "il minimo e':", minimo_fino_ad_ora
Soluzione: combino l’esempio e l’esercizio sopra:
lista = [1, 25, 6, 27, 57, 12] massimo = lista[0] minimo = lista[0] for numero in lista[1:]: if numero > massimo: massimo = numero if numero < minimo: minimo = numero print "minimo =", minimo, "massimo =", massimo
Soluzione:
range(0, len(sequenza), 3)
restituisce[0, 3, 6, 9, ...]
, che sono le posizioni di inizio delle varie triplette.E’ sufficiente scrivere:
sequenza = "ATGGCGCCCGAACAGGGA" # parto da una lista vuota triplette = [] for pos_inizio in range(0, len(sequenza), 3): tripletta = sequenza[pos_inizio:pos_inizio+3] triplette.append(tripletta) print triplette
Soluzione:
testo = """>2HMI:A|PDBID|CHAIN|SEQUENCE PISPIETVPVKLKPGMDGPKVKQWPLTEEKIKALVEICTEMEKEGKISKI >2HMI:B|PDBID|CHAIN|SEQUENCE PISPIETVPVKLKPGMDGPKVKQWPLTEEKIKALVEICTEMEKEGKISKI >2HMI:C|PDBID|CHAIN|SEQUENCE DIQMTQTTSSLSASLGDRVTISCSASQDISSYLNWYQQKPEGTVKLLIYY >2HMI:D|PDBID|CHAIN|SEQUENCE QITLKESGPGIVQPSQPFRLTCTFSGFSLSTSGIGVTWIRQPSGKGLEWL >2HMI:E|PDBID|CHAIN|SEQUENCE ATGGCGCCCGAACAGGGAC >2HMI:F|PDBID|CHAIN|SEQUENCE GTCCCTGTTCGGGCGCCA""" # prima di tutto rompo il testo in righe righe = testo.split("\n") # creo il dizionario dove metto il risultato voluto sequenza_di = {} # ora posso iterare sulle varie righe for riga in righe: if riga[0] == ">": # se la riga e' un'intestazione, estraggo il nome # della sequenza nome = riga.split("|")[0] else: # altrimenti, e' la sequenza vera a propria. il # nome l'ho ricavato nell'iterazione precedente # (che corrisponde alla riga sopra nel file FASTA) # quindi lo posso usare per aggiornare il dizionario sequenza_di[nome] = riga print sequenza_di
Soluzioni:
Soluzione:
while raw_input("scrivi 'STOP': ") != "STOP": print "devi scrivere 'STOP'..."
Soluzione:
while raw_input("scrivi stop: ").lower() != "stop": print "devi scrivere stop..."
Soluzioni:
- Soluzione: tutti i numeri in
range(10)
. - Soluzione: il numero
0
. Ilbreak
interrompe immediatamente ilfor
. - Soluzione: tutti i numeri in
range(10)
. Ilcontinue
salta all’iterazione successiva, cosa che Python fa automaticamente quando finisce il corpo del ciclofor
. Visto checontinue
in questo caso si trova proprio alla fine del corpo del ciclofor
, e come se non ci fosse. - Soluzione: il numero
0
. Nella primissima iterazione, quandonumero
vale0
, prima Python esegueprint numero
, che stampa appunto0
; poi l’if
viene eseguito, e cosi’ ilbreak
che contiene, che fa interrompere immediatamente ilfor
. - Soluzione: niente. Nella primissima iterazione, quando
numero
vale0
, l’if
viene eseguito e cosi’ ilbreak
che contiene, che fa interrompere immediatamente ilfor
. Ilprint
non viene mai eseguito. - Soluzione: niente. Il corpo del
while
non viene mai eseguito, la condizione e’False
! - Soluzione: niente. Visto che il corpo del
while
non viene mai eseguito (la condizione e’False
!), la rigacondizione = True
non viene mai eseguita. - Soluzione:
"la condizione e' vera"
un numero indefinito di volte. Visto che la condizione e’ sempreTrue
, ilwhile
non finisce mai di iterare! - Soluzione: dieci stringhe della forma
"all'indice 0 c'e' l'elemento 0"
,"all'indice 1 c'e' l'elemento 1"
, etc. - Soluzione: tutti gli elementi di
righe
(processati dastrip()
) che vengono prima della prima riga vuota, vale a dire"riga 1"
,"riga 2"
e"riga 3"
. Appenariga
vale""
(il quarto elemento dirighe
) l’if
viene eseguito, e con esso ilbreak
, che interrompe il ciclo. Si noti che la quarta riga non viene stampata.
- Soluzione: tutti i numeri in
Soluzione:
numeri = (0, 1, 1, 0, 0, 0, 1, 1, 2, 1, 2) for i in range(len(numeri)): numero_in_pos_i = numeri[i] if numero_in_pos_i == 2: print "la posizione e'", i break
Soluzione:
stringhe = ("000", "51", "51", "32", "57", "26") for i in range(len(stringhe)): stringa_in_pos_i = stringhe[i] if "2" in stringa_in_pos_i: print "posizione =", i, "valore =", stringa_in_pos_i break
Codice annidato¶
Soluzione:
n = 5 matrice = [range(n) for i in range(n)] for riga in matrice: for elemento in riga: print elemento
Soluzione:
- Tutti gli elementi della matrice.
- La somma di tutti gli elementi della matrice.
- Di nuovo tutti gli elementi della matrice.
- Di nuovo tutti gli elementi della matrice.
- La lista degli elementi sulla diagonale.
Uso due cicli
for
per iterare sulle coppie di elementi:numeri = [8, 3, 2, 9, 7, 1, 8] for numero_1 in numeri: for numero_2 in numeri: print numero_1, numero_2
E’ molto simile all’esempio dell’orologio!
Scrivo:
numeri = [8, 3, 2, 9, 7, 1, 8] coppie_gia_stampate = [] for i in range(len(numeri)): for j in range(len(numeri)): coppia = (numeri[i], numeri[j]) # controllo se ho gia' stampato la coppia simmetrica if (coppia[1], coppia[0]) in coppie_gia_stampate: continue # se arrivo qui vuol dire che non ho gia' stampato la coppia # simmetrica (altrimenti avrei fatto `continue`), quindi stampo # la coppia; poi aggiorno coppie_gia_stampate print coppia coppie_gia_stampate.append(coppia)
Come sopra.
Soluzione:
numeri = range(10) for elemento_1 in numeri: for elemento_2 in numeri: if 2 * elemento_1 == elemento_2: print elemento_1, elemento_2
Soluzione:
numeri = [8, 3, 2, 9, 7, 1, 8] for elemento_1 in numeri: for elemento_2 in numeri: if elemento_1 + elemento_2 == 10: print elemento_1, elemento_2
Soluzione:
numeri = [8, 3, 2, 9, 7, 1, 8] # parto da una lista vuota lista_delle_coppie = [] for elemento_1 in numeri: for elemento_2 in numeri: if elemento_1 + elemento_2 == 10: # aggiorno la lista con append() lista_delle_coppie.append((elemento_1, elemento_2)) # stampo la lista che ho appena costruito print lista_delle_coppie
Soluzione:
numeri_1 = [5, 9, 4, 4, 9, 2] numeri_2 = [7, 9, 6, 2] # qui itero sulla *prima* lista for i in range(len(numeri_1)): numero_in_pos_i = numeri_1[i] # qui itero sulla *seconda* lista for j in range(len(numeri_2)): numero_in_pos_j = numeri_2[j] if numero_in_pos_i == numero_in_pos_j: print "posizioni:", i, j, "; valore ripetuto:", numero_in_pos_i
Soluzione:
numeri_1 = [5, 9, 4, 4, 9, 2] numeri_2 = [7, 9, 6, 2] # parto da una lista vuota lista_delle_triplette = [] # qui itero sulla *prima* lista for i in range(len(numeri_1)): numero_in_pos_i = numeri_1[i] # qui itero sulla *seconda* lista for j in range(len(numeri_2)): numero_in_pos_j = numeri_2[j] if numero_in_pos_i == numero_in_pos_j: # al posto di stampare, aggiorno la lista lista_delle_triplette.append((i, j, numero_in_pos_i)) # stampo la lista che ho appena costruito print lista_delle_triplette
Soluzione:
n = 5 matrice = [range(n) for i in range(n)] # inizializzo con il primo elemento (un qualunque altro elemento # andrebbe comunque bene) max_elemento_fino_ad_ora = matrice[0][0] # itero... for riga in matrice: for elemento in riga: # se trovo un elemento piu' grande di max_elemento_fino_ad_ora, # aggiorno quest'ultimo if elemento > max_elemento_fino_ad_ora: max_elemento_fino_ad_ora = elemento print max_elemento_fino_ad_ora
Soluzione:
sequenze = [ "ATGGCGCCCGAACAGGGA", "GTCCCTGTTCGGGCGCCA", ] # parto da una lista vuota risultato = [] # itero... for sequenza in sequenze: # spezzo la sequenza corrente in triplette triplette = [] for i in range(0, len(sequenza), 3): triplette.append(sequenza[i:i+3]) # appendo (*non* extend()!!!) le triplette # ottenute alla lista risultato risultato.append(triplette) # stampo la lista che ho appena costruito print risultato
Soluzione:
numeri = [5, 9, 4, 4, 9, 2] num_ripetizioni = {} for numero in numeri: if not num_ripetizioni.has_key(numero): num_ripetizioni[numero] = 1 else: num_ripetizioni[numero] += 1
o in alternativa:
numeri = [5, 9, 4, 4, 9, 2] num_ripetizioni = {} for numero in numeri: if not num_ripetizioni.has_key(numero): num_ripetizioni[numero] = 0 num_ripetizioni[numero] += 1
oppure, sfruttando
count()
:numeri = [5, 9, 4, 4, 9, 2] num_ripetizioni = {} for numero in numeri: if not num_ripetizioni.has_key(numero): num_ripetizioni[numero] = numeri.count(numero)
Si noti che in quest’ultima variante, l’
if
(ma non il suo “contenuto”!) e’ opzionale.Avvertimento
Nella formulazione originale, l’esercizio richiedeva di usare due cicli
for
innestati. Una possibile soluzione a questa versione dell’esercizio e’ la seguente:numeri = [5, 9, 4, 4, 9, 2] num_ripetizioni = {} for numero in numeri: if num_ripetizioni.has_key(numero): continue else: num_ripetizioni[numero] = 0 for numero_2 in numeri: if numero == numero_2: num_ripetizioni[numero] += 1
Una versione meno “ottimizzata”:
numeri = [5, 9, 4, 4, 9, 2] num_ripetizioni = {} for numero in numeri: num_ripetizioni[numero] = 0 for numero_2 in numeri: if numero == numero_2: num_ripetizioni[numero] += 1
Soluzione:
gruppi = [["gene1", "gene2"], ["gene3"], [], ["gene4", "gene5"]] # inizializzo con il primo gruppo gruppo_piu_grande_fino_ad_ora = gruppi[0] # itero... for gruppo in gruppi[1:]: if len(gruppo) > len(gruppo_piu_grande_fino_ad_ora): gruppo_piu_grande_fino_ad_ora = gruppo print gruppo_piu_grande_fino_ad_ora
Soluzione:
sequenze_2HMI = { "A": "PISPIETVPVKLKPGMDGPKVKQWPLTEEKI", "B": "PISPIETVPVKLKPGMDGPKVKQWPLTEEKI", "C": "DIQMTQTTSSLSASLGDRVTISCSASQDISS", "D": "QITLKESGPGIVQPSQPFRLTCTFSGFSLST", "E": "ATGGCGCCCGAACAGGGAC", "F": "GTCCCTGTTCGGGCGCCA", } # parto dal dizionario vuoto istogrammi = {} for chiave, sequenza in sequenze_2HMI.items(): # associo a questa chiave un istogramma vuoto istogrammi[chiave] = {} for residuo in sequenza: if not istogrammi[chiave].has_key(residuo): istogrammi[chiave][residuo] = 1 else: istogrammi[chiave][residuo] += 1 # stampo il risultato print istogrammi # stampo il risultato in modo piu' leggibile for chiave, istogramma in istogrammi.items(): print chiave print istogramma print ""
Soluzione:
tabella = [ "protein domain start end", "YNL275W PF00955 236 498", "YHR065C SM00490 335 416", "YKL053C-A PF05254 5 72", "YOR349W PANTHER 353 414", ] # come prima cosa estraggo i nomi delle colonne dalla prima riga nomi_colonne = tabella[0].split() # parto da una lista vuota righe_come_dizionari = [] # ora itero sulle altre righe for riga in tabella[1:]: # compilo il dizionario per questa riga dizionario = {} parole = riga.split() for i in range(len(parole)): # estraggo la parola corrispondente parola = parole[i] # estraggo il nome della colonna corrispondente nome_colonna = nomi_colonne[i] # aggiorno il dizionario dizionario[nome_colonna] = parola # ho compilato il dizionario per la riga corrente, # aggiorno la lista completa righe_come_dizionari.append(dizionario) # ho finito! stampo il risultato (una riga per volta, # per renderlo un po' piu' leggibile) for riga_come_dizionario in righe_come_dizionari: print riga_come_dizionario
Soluzione:
alfabeto_min = "abcdefghijklmnopqrstuvwxyz" alfabeto_mai = alfabeto_min.upper() # costruisco il dizionario min_to_mai = {} for i in range(len(alfabeto_min)): min_to_mai[alfabeto_min[i]] = alfabeto_mai[i] stringa = "sono una stringa" # converto la stringa caratteri_convertiti = [] for carattere in stringa: if min_to_mai.has_key(carattere): # e' un carattere alfabetico, lo devo convertire caratteri_convertiti.append(min_to_mai[carattere]) else: # non e' un carattere alfabetico, non lo converto caratteri_convertiti.append(carattere) stringa_convertita = "".join(caratteri_convertiti) print stringa_convertita
Soluzione:
righe_1 = open(raw_input("percorso 1: ")).readlines() righe_2 = open(raw_input("percoros 2: ")).readlines() # devo stare attento perche' i due file possono essere di # lunghezza diversa! max_righe = len(righe_1) if len(righe_2) > max_righe: max_righe = len(righe_2) # itero sulle righe di entrambi i file for i in range(max_righe): # prendo la i-esima riga del primo file, # sempre che esista if i < len(righe_1): riga_1 = righe_1[i].strip() else: riga_1 = "" # prendo la i-esima riga del secondo file, # sempre che esista if i < len(righe_2): riga_2 = righe_2[i].strip() else: riga_2 = "" print riga_1 + " " + riga_2
Soluzione:
# qui leggo il file fasta fasta_come_dizionario = {} for riga in open("data/dna-fasta/fasta.1").readlines(): # mi sbarazzo di eventuali a capo riga = riga.strip() if riga[0] == ">": intestazione = riga fasta_come_dizionario[intestazione] = "" else: fasta_come_dizionario[intestazione] += riga # itero sulle coppie intestazione-sequenza for intestazione, sequenza in fasta_come_dizionario.items(): print "processo", intestazione # conto quante volte appare ogni nucleotide conta = {} for nucleotide in ("A", "C", "T", "G"): conta[nucleotide] = sequenza.count(nucleotide) print "le conte sono", conta # calcolo il gc-content gc_content = (conta["G"] + conta["C"]) / float(len(sequenza)) print "il GC-content e'", gc_content # calcolo il AT/GC-ratio somma_at = conta["A"] + conta["T"] somma_cg = conta["C"] + conta["G"] at_gc_ratio = float(somma_at) / float(somma_cg) print "la AT/GC-ratio e'", at_gc_ratio