Preliminari Dizionari Impiccato Laboratorio di Python (con Linux) 8a lezione Giulio Pellitta Università di Bologna 2, 4 maggio 2012 Giulio Pellitta Laboratorio di Python (con Linux) Preliminari Dizionari Impiccato Sommario 1 Preliminari 2 Dizionari 3 Impiccato Giulio Pellitta Laboratorio di Python (con Linux) Preliminari Dizionari Impiccato 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. Giulio Pellitta Laboratorio di Python (con Linux) Preliminari Dizionari Impiccato 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 p1 , . . . , pn 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 Giulio Pellitta Laboratorio di Python (con Linux) Preliminari Dizionari Impiccato 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)] Giulio Pellitta Laboratorio di Python (con Linux) Preliminari Dizionari Impiccato 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' Giulio Pellitta Laboratorio di Python (con Linux) Preliminari Dizionari Impiccato 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. Giulio Pellitta Laboratorio di Python (con Linux) Preliminari Dizionari Impiccato Variabili e Dizionari 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. Giulio Pellitta Laboratorio di Python (con Linux) Preliminari Dizionari Impiccato Impiccato 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=[] Giulio Pellitta Laboratorio di Python (con Linux) Preliminari Dizionari Impiccato 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 Giulio Pellitta Laboratorio di Python (con Linux) Preliminari Dizionari Impiccato 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 Giulio Pellitta Laboratorio di Python (con Linux) Preliminari Dizionari Impiccato 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 [email protected] entro il prossimo laboratorio (subject email: “frequenze”). Giulio Pellitta Laboratorio di Python (con Linux) Preliminari Dizionari Impiccato Suggerimenti 1 2 3 Usare la list comprehension per filtrare le frequenze delle vocali da quelle di tutte le lettere. Una matrice sparsa è una matrice che contiene pochi elementi non-zero. Mettere questi in un dizionario. Usare i metodi visti a lezione e commentare il codice ove necessario. Giulio Pellitta Laboratorio di Python (con Linux)