Laboratorio di Python Code Lab13 28 Aprile 2017
Outline Correzione esercizi per oggi Code Teoria Esercizi Esercizi per casa
Esercizio 1 per casa Scrivere una funzione che determina se uno studente può prendere il punto aggiuntivo all esame (ovvero se ha consegnato almeno 10 volte gli esercizi)
Esercizio 1 per casa Scrivere una funzione che determina se uno studente può prendere il punto aggiuntivo all esame (ovvero se ha consegnato almeno 10 volte gli esercizi) 1 import s t u d e n t i 2 3 def p u o p r e n d e r e p u n t o ( s ) : 4 return len ( s t u d e n t i. c o n s e g n e s t u d e n t e ( s ) )>=10
Esercizio 2 per casa Scrivere un programma che stampa un istogramma (con gli asterischi) delle consegne per ogni laboratorio (anche quelli con 0 consegne), ordinate dal laboratorio con più consegne a quello con meno consegne. I laboratori sono numerati da 1 a 15.
Esercizio 2 per casa 1 import s t u d e n t i 2 #s t a t i s t i c a consegne >0 3 ds = s t u d e n t i. s t a t i s t i c a c o n s e g n e ( ) 4 #aggiungo g l i z e r i 5 f o r i i n range ( 1, 1 6 ) : 6 i f i not i n ds : 7 ds [ i ] = 0 8 #r e s t i t u i s e i l secondo elemento d i una t u p l a 9 def second ( t ) : 10 return t [ 1 ] 11 ds. i t e m s ( ) r e s t i t u i s e una sequenza d i c o p p i e ( c h i a v e, v a l o r e ), l a t r a s f o r m o i n una l i s t a o r d i n a t a con s o r t e d, o r d i n a n d o l a i n modo d e c r e s c e n e ( r e v e r s e=true ) e i n base a l secondo elemento d e l l a t u p l a. 12 l i s t a = sorted ( ds. i t e m s ( ), key=second, r e v e r s e=true ) 13 f o r nlab, f r e q i n l i s t a : 14 p r i n t ( nlab, ' ' f r e q, sep=' \ t ' )
Esercizio 3 per casa Scrivere una funzione che prende in input una stringa e crea un dizionario in cui le chiavi sono i caratteri alfanumerici (string.digits+string.ascii letters) presenti nella stringa i valori sono dei dizionari che hanno: come chiavi tutti i caratteri che seguono il carattere considerato come valori la frequenza con cui quel carattere segue il carattere considerato
Esercizio 3 per casa 1 import s t r i n g 2 d e f s t a t f r e q ( s ) : 3 d r e s = d i c t ( ) 4 an = s t r i n g. d i g i t s+s t r i n g. a s c i i l e t t e r s 5 #non c o n s i d e r o l ' u l t i m a l e t t e r a p e r c h e ' non ha s u c c 6 f o r i i n range ( l e n ( s ) 1) : 7 c = s [ i ] 8 i f c i n an : 9 i f c not i n d r e s : 10 #nuovo d i z. p e r l e l e t t e r e s e g u e n t i c... 11 d r e s [ c ] = d i c t ( ) 12 # i n c u i i n s e r i s c o f r e q d e l s u c c e s s o r e d i c 13 d r e s [ c ] [ s [ i +1]] = 1 14 e l s e : #c e ' g i a ' p r e s e n t e 15 d r e s [ c ] [ s [ i +1]] = d r e s [ c ]. g e t ( s [ i +1],0)+1 16 r e t u r n d r e s
Outline Correzione esercizi per oggi Code Teoria Esercizi Esercizi per casa
Code Vogliamo utilizzare una nuova struttura dati: le code. Collezione ordinata e mutabile di elementi Ha un inizio (head) e una fine (tail) Operazioni: Accodamento (enqueue), aggiunge un elemento alla fine della coda Estrazione (dequeue), rimuove un elemento all inizio della coda
Code Vogliamo utilizzare una nuova struttura dati: le code. Collezione ordinata e mutabile di elementi Ha un inizio (head) e una fine (tail) Operazioni: Accodamento (enqueue), aggiunge un elemento alla fine della coda Estrazione (dequeue), rimuove un elemento all inizio della coda Questa struttura non esiste nativamente in Python, quindi dobbiamo costruircela noi, come tipo di dato astratto (abstract data type, ADT). Dobbiamo quindi costruire Un interfaccia, cioè (i nomi del)le le funzioni con cui manipoleremo il tipo di dato (e lo faremo solo con quelle) Un implementazione, cioè il modo con cui concretamente sono rappresentati i dati ed eseguite le operazioni in Python. Una volta costruita, non accederemo più a questa rappresentazione concreta per manipolare i dati.
Interfaccia e Implementazione Costruire un file di Python coda.py che contenga un implementazione tramite liste della seguente interfaccia. Poiché si tratta di un interfaccia, cioè un accordo comune su come utilizzare le code, nomi e numero di file, funzioni e parametri deve essere esattamente lo stesso. queue() - Crea una coda vuota enqueue(a, c) - Accoda a alla fine della coda c. Ritorna inoltre c. dequeue(c) - Rimuove il primo elemento della coda c e ne ritorna il valore. Se c è vuota ritorna None. is empty(c) - Ritorna True sse la coda c è vuota head(c) - Ritorna il primo elemento della coda c (senza rimuoverlo). Se c è vuota ritorna None. tail(c) - Ritorna l ultimo elemento della coda c (senza rimuoverlo). Se c è vuota ritorna None. length(c) - Ritorna il numero di elementi presenti nella coda
coda.py 1 def queue ( ) : 2 r e t u r n [ ] 3 4 def enqueue ( a, c ) : 5 c. append ( a ) 6 r e t u r n c 7 8 def dequeue ( c ) : 9 i f l e n ( c ) >0: 10 a = c [ 0 ] 11 d e l c [ 0 ] 12 r e t u r n a 13 r e t u r n None 14 15 def i s e m p t y ( c ) : 16 r e t u r n l e n ( c ) == 0 17 def head ( c ) : 18 i f l e n ( c ) >0: 19 r e t u r n c [ 0 ] 20 e l s e : 21 r e t u r n None 22 23 def t a i l ( c ) : 24 i f l e n ( c ) >0: 25 r e t u r n c [ 1] 26 e l s e : 27 r e t u r n None 28 29 def l e n g t h ( c ) : 30 r e t u r n l e n ( c )
Ufficio Postale All ufficio postale apre un solo sportello. Arrivano Michael, Davide, Matteo e Simone. Come rappresentiamo questo con una coda in Python? 1 from coda import 2 up = queue ( ) 3 enqueue ( Michael, up ) 4 enqueue ( Davide, up ) 5 enqueue ( Matteo, up ) 6 enqueue ( Simone, up ) Ma se volessimo costruire direttamente la coda up e riempirla contestualmente con 4 elementi? Possiamo sfruttare il fatto che enqueue restituisce anche la coda stessa. Costruisco una nuova coda a partire dalla coda vuota: 1 from coda import 2 up = enqueue ( Simone, enqueue ( Matteo, enqueue ( Davide, enqueue ( Michael, queue ( ) ) ) ) )
Outline Correzione esercizi per oggi Code Teoria Esercizi Esercizi per casa
Aggiornamento dell interfaccia Aggiungere al file coda.py una funzione pretty print q(c) che stampa il contenuto della coda c senza virgole o parentesi, come una sequenza di elementi separati da spazi, che inizia con il carattere (potete pensarlo come lo sportello al quale sono in coda le persone). Esempio c = enqueue( Q, enqueue( T, enqueue( S, enqueue( P, queue())))) allora verrà stampato: P S T Q
Aggiornamento dell interfaccia Aggiungere al file coda.py una funzione pretty print q(c) che stampa il contenuto della coda c senza virgole o parentesi, come una sequenza di elementi separati da spazi, che inizia con il carattere (potete pensarlo come lo sportello al quale sono in coda le persone). Esempio c = enqueue( Q, enqueue( T, enqueue( S, enqueue( P, queue())))) allora verrà stampato: P S T Q 1 def p r e t t y p r i n t q ( c ) : 2 p r i n t (, end= ) 3 f o r e i n c : 4 p r i n t ( e, end= ) 5 p r i n t ( )
Attenzione! Negli esercizi seguenti ci dimenticheremo dell implementazione che abbiamo costruito. Accederemo alle code solo con le funzioni presenti nell interfaccia.
Esercizio d esame semplificato Si scriva una funzione Python fattorizza(a) che, data una coda a i cui elementi sono etichettati da numeri naturali positivi, ritorni una nuova coda b (i cui elementi sono numeri naturali) ottenuta da a rimpiazzando ciascun numero naturale con i suoi fattori primi (presi in un qualunque ordine e con la loro molteplicità). Ad esempio, sulla coda enqueue(4,enqueue(3,enqueue(10,queue()))), la funzione potrebbe ritornare la coda enqueue(2,enqueue(2,enqueue(3,enqueue(5,enqueue(2,queue()))))). La coda a può essere distrutta. E possibile usare la funzione ausiliaria: 1 def s c o m p o s i z i o n e ( n ) : 2 f a t t o r i = [ ] 3 d = 2 4 while n >= d : 5 i f n % d == 0 : 6 f a t t o r i. append ( d ) 7 n = n//d #NB: d i v i s i o n e i n t e r a 8 e l s e : 9 d = d + 1 10 return f a t t o r i
Esercizio d esame 1 from coda import #c o s i ' non s e r v e coda. 2 3 def f a t t o r i z z a ( a ) : 4 r e s = queue ( ) 5 while not i s e m p t y ( a ) : 6 f o r i i n s c o m p o s i z i o n e ( head ( a ) ) : 7 enqueue ( i, r e s ) 8 dequeue ( a ) 9 return r e s
Usare le code per una simulazione Un piccolo negozio con una sola cassa deve decidere se assumere una seconda cassiera. Per farlo vuole eseguire una simulazione sui tempi di attesa attuali alla cassa. Costruire una funzione simulazione(durata) che simula i clienti in coda alla cassa per una certa durata. In particolare: La durata è espressa in minuti. Il passare dei minuti è simulato semplicemente dall aumento di uno di una variabile intera. Un cliente è rappresentato in una coda di interi dal minuto al quale è arrivato Ad ogni minuto: se c è un cliente in coda, viene servito (dunque il tempo di servizio è costante ed uguale ad un minuto) Con probabilità 1/4, arriva un cliente, con probabilità 1/4 arrivano due clienti e con probabilità 2/4 non arriva nessun cliente. Usare la funzione random.randint(0,3) per decidere quanti clienti arrivano, e, se necessario, inserirli in coda. (Suggerimento: usare 0 e 3 per decidere nessun cliente, 1 e 2 per l arrivo di 1 o 2 clienti.) La funzione stamperà opportuni messaggi e la situazione della coda (usare la pretty print). In particolare, ogni volta che un cliente esce dalla coda, dovrà stampare quanto tempo ha aspettato (suggerimento: differenza tra il valore del cliente e il minuto attuale).
Esempio: simulazione(5) *** Minuto 0 *** Arriva un cliente *** Minuto 1 *** 0 Finito di servire un cliente, che ha aspettato 1 minuti Non e' arrivato nessun cliente *** Minuto 2 *** Arrivano due clienti *** Minuto 3 *** 2 2 Finito di servire un cliente, che ha aspettato 1 minuti Arrivano due clienti *** Minuto 4 *** 2 3 3 Finito di servire un cliente, che ha aspettato 2 minuti Arrivano due clienti
Soluzione 1 def s i m u l a z i o n e ( d u r a t a ) : 2 c a s s a = queue ( ) 3 f o r minuto i n range ( d u r a t a ) : 4 p r i n t ( Minuto, minuto, ) 5 p r e t t y p r i n t q ( c a s s a ) 6 i f not i s e m p t y ( c a s s a ) : 7 c l = dequeue ( c a s s a ) 8 a t t e s a = minuto c l 9 p r i n t ( F i n i t o d i s e r v i r e un c l i e n t e, che ha a s p e t t a t o, a t t e s a, m i n u t i ) 10 a r r i v o = random. r a n d i n t ( 0, 3 ) 11 i f a r r i v o == 1 : 12 p r i n t ( A r r i v a un c l i e n t e ) 13 enqueue ( minuto, c a s s a ) 14 e l i f a r r i v o == 2 : 15 p r i n t ( A r r i v a n o due c l i e n t i ) 16 enqueue ( minuto, c a s s a ) 17 enqueue ( minuto, c a s s a ) 18 e l s e : 19 p r i n t ( Non e ' a r r i v a t o nessun c l i e n t e )
Migliorare la simulazione Scrivere una nuova funzione simulazione2(durata), molto simile alla precedente, ma che in più tiene traccia: Del totale di clienti arrivati durante la simulazione Della somma totale dei tempi di attesa Del tempo massimo di attesa registrato La funzione non stampa nulla ma restituisce una tupla che contiene le seguenti informazioni: (durata, totale clienti, media attesa, attesa massima)
Soluzione I 1 def s i m u l a z i o n e 2 ( d u r a t a ) : 2 c a s s a = queue ( ) 3 t o t a l e c l i e n t i = 0 4 s o m m a t o t a l e a t t e s a = 0 5 a t t e s a m a s s i m a = 0 6 m e d i a a t t e s a = 0 7 f o r minuto i n range ( d u r a t a ) : 8 #p r e t t y p r i n t q ( c a s s a ) 9 i f not i s e m p t y ( c a s s a ) : 10 c l = dequeue ( c a s s a ) 11 a t t e s a = minuto c l 12 s o m m a t o t a l e a t t e s a += a t t e s a 13 i f a t t e s a >a t t e s a m a s s i m a : 14 a t t e s a m a s s i m a = a t t e s a 15 a r r i v o = random. r a n d i n t ( 0, 3 ) 16 i f a r r i v o == 1 : 17 enqueue ( minuto, c a s s a ) 18 t o t a l e c l i e n t i +=1
Soluzione II 19 e l i f a r r i v o == 2 : 20 enqueue ( minuto, c a s s a ) 21 enqueue ( minuto, c a s s a ) 22 t o t a l e c l i e n t i +=2 23 i f t o t a l e c l i e n t i >0: 24 n u m s e r v i t i = t o t a l e c l i e n t i l e n g t h ( c a s s a ) #Contiamo i c l i e n t i s e r v i t i ( T u t t i meno q u e l l i r i m a s t i i n coda ) 25 i f n u m s e r v i t i >0: 26 m e d i a a t t e s a = s o m m a t o t a l e a t t e s a / n u m s e r v i t i 27 return ( durata, t o t a l e c l i e n t i, m e d i a a t t e s a, a t t e s a m a s s i m a )
Esercizi per casa (per il 10/05/2017 ore 8:59) (Mail: Lab13-...) 1. (Usando il tipo coda costruito a lezione) Scrivere una funzione che prende come parametro una coda ed elimina dalla coda tutti gli elementi in posizione pari (es. se c = a b c d e, verrà modificata in a c e ). La funzione modifica la coda originaria e non fa uso di strutture dati ausiliarie (liste, altre code, ecc). 2. (Usando le funzioni di simulazione costruite a lezione) Scrivere un programma che esegue 5 simulazioni della cassa del negozio per minuti: 5, 30, 60, 120, 480. Salva le tuple risultati in una lista. Dopodiché stampa la lista con i risultati. Usare la funzione round(f,2) per arrotondare f a 2 decimali. Esempio: Dur Tot Media Max 5 5 0.8 2 30 30 1.77 3 60 45 2.38 5 120 104 2.41 6 480 376 2.44 9 continua...
Esercizi per casa (per il 10/05/2017 ore 8:59) (Mail: Lab13-...) 3. (Dizionari) La moda di una lista di valori è data da quei valori che compaiono nella lista con la massima frequenza. Ad esempio, la moda (unica) di [1,4,5,4,6,5,4,1,4] è 4, mentre la moda di [1,4,5,6,5,4,1] è costituita da 1,4,5. Si scriva una funzione moda(x) che restituisce come lista la moda della lista x. Suggerimento: usare un dizionario e una funzione che restituisce il massimo elemento di una sequenza. 4. (Dizionari) L orlo di una matrice è costituito dalle sue righe e dalle sue colonne più esterne (prima riga, prima colonna, ultima riga, ultima colonna). Scrivere una funzione orlo(a,m,n) che presa una matrice A di ordine m n restituisce True sse tutti gli elementi di A compaiono nel suo orlo (cioè gli elementi che non sono nell orlo sono presenti almeno una volta anche nell orlo). Si supponga che una matrice A sia memorizzata come un dizionario, i cui elementi sono coppie (i,j):e, in cui le chiavi sono le coppie di riga e colonna e il valore è l elemento della matrice: in questo modo l usuale notazione A[i,j] indica l elemento nella riga i e colonna j (partendo da 0).