8 a lezione Università di Bologna 2, 4 maggio 2012
Sommario 1 2 3
Diversi Python 2.6 vs 2.7 v.s 3.x La versione di Python installata sulle macchine del laboratorio è la 2.6 (per l esattezza 2.6.6 ). Versioni successive, come 2.7 e 3.1, possono avere differenze significative (comandi aggiunti, rimossi o modificati). Ad esempio, in Python 3 la divisione tra interi si fa con l operatore //, mentre / fa la divisione tra float (non c è overloading di / come in Python 2). Inoltre in Python 3 il comando range non restituisce una lista ma un iteratore (quello che in Python 2 è xrange), quindi se testate le soluzioni con Python 3 sostituite range(start,end,step) con list(range(start,end,step)). In generale è meglio cercare di scrivere codice che sia forward-compatible con Python 3. Se sul vostro computer usate versioni di Python successive alla 2.6 e notate che il codice non gira come previsto, segnalatelo.
Codice ben scritto In matematica quando si scrivono definizioni o teoremi si tende ad utilizzare certe notazioni per indicare il tipo di oggetti di cui si parla (ad esempio lettere maiuscole per le matrici, i, j come indici, k, n, m come interi, p e q o p 1,..., p n come primi). In informatica è bene fare lo stesso perché il codice risulti più chiaro (sia per chi lo scrive, per evitare di fare errori, che per chi lo legge, per capirlo più facilmente). Se si verifica una situazione anomala (ad esempio un argomento di tipo diverso da quanto previsto) in generale non basta stampare un messaggio di errore, bisogna terminare la funzione corrente con return. def inverso(x): if type(x) not in (int,long,float) or x==0: print "Argomento non numerico o zero." return return 1./x
List comprehension L assioma di comprensione permette, dato un insieme, di isolare il sottoinsieme degli elementi che soddisfano una certa proprietà (infatti si chiama anche assioma di isolamento). Python possiede un costrutto noto come List comprehension che consente analogamente di filtrare gli elementi di una lista. def non_zero(l): return [x for x in L if x!=0] Più in generale una list comprehension valuta un espressione in un contesto dato dalle clausole for e if che seguono. Esempio: [(x, y) for x in [1,2,3] for y in [3,1,4] if x!= y] produce [(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
Metodi dizionari Agli elementi di un dizionario si accede comodamente indicando la chiave come fosse l indice di un array. >>> phonebook={'bill':'900123','jim':'984363'} Usare una chiave inesistente causa un errore di runtime. >>> phonebook['kate'] Traceback (most recent call last): File "<pyshell#11>", line 1, in <module> phonebook['kate'] KeyError: 'Kate' Si può usare l operatore in per controllare se la chiave esiste. >>> if 'Kate' in phonebook: print phonebook['kate'] Altra possibilità è usare il metodo get del tipo dizionario, che ha un parametro opzionale (valore di default: None) che viene restituito se la chiave non esiste. >>> phonebook.get('kate','donotcallme') 'donotcallme'
Il metodo keys() dà la lista delle chiavi di un dizionario. >>> phonebook.keys() ['Jim', 'Bill'] Il metodo values() restituisce la lista dei valori di un dizionario. >>> phonebook.values() ['984363', '900123'] Infine il metodo items() dà la lista delle coppie di un dizionario. >>> phonebook.items() [('Jim', '984363'), ('Bill', '900123')] Per altri dettagli: scrivere help(dict) sulla shell di Python. Oppure consultare http://docs.python.org/release/2. 6.6/tutorial/datastructures.html#dictionaries.
Variabili e Python usa i dizionari locals() e globals() per memorizzare variabili locali e globali. Per verificare se esiste una variabile globale possiamo scrivere 'n' in globals().keys(). Utile ad esempio per scrivere codice che usa variabili globali (non si dovrebbe usare una variabile già in uso). Per assegnare/modificare una variabile locale scriviamo locals()['n']=3.
def impiccato(filename="/usr/share/doc/idle-python2.6/re if k>=26: print "Cosi' e' troppo facile!" return import string W=parole_da_file(filename) w=random_word(w,minlen) if w==none: print 'Nessuna parola di lunghezza almeno',minle return wl=['_']*len(w) print W print "Gioco dell'impiccato. Indovina una parola di" print wl C=[]
while True: c=raw_input("inserisci una lettera: ").upper() if len(c)!=1 or not(c in string.uppercase): continue elif c in C: print c,"gia' scelta." print "Lettere gia' scelte:",c continue C.append(c) occur=false for i in range(len(w)): if w[i]==c: wl[i]=c occur=true
if not(occur): print c,'non compare.' k-=1 if k>0: print "Hai ancora",k,"possibilita'." continue else: print 'La parola era',w+". Hai perso!" return elif not('_' in wl): print 'La parola era',w+". Indovinato!" return print wl
Esercizi 1 Calcolare le frequenze delle sole vocali in testo con la list comprehension. 2 Somma e prodotto di matrici sparse con dizionari. 3 Frequenze lettere da dizionario frequenze parole (scrivere un programma che dato un dizionario contenente la frequenza di parole in un testo, ovvero un insieme di coppie del tipo (stringa,intero positivo), calcoli le frequenze delle lettere in quel testo. Esercizio per casa: scrivere la soluzione in un file chiamato frequenze.cognome.nome.py e mandarlo via email a python2012unibo@gmail.com entro il prossimo laboratorio (subject email: frequenze ).
Suggerimenti 1 Usare la list comprehension per filtrare le frequenze delle vocali da quelle di tutte le lettere. 2 Una matrice sparsa è una matrice che contiene pochi elementi non-zero. Mettere questi in un dizionario. 3 Usare i metodi visti a lezione e commentare il codice ove necessario.