Fondamenti di Informatica Comandi condizionali, espressioni logiche e predicati Condizioni logiche Obiettivi di apprendimento generali espressioni e proposizioni logiche comandi condizionali selezione tra alternative (if-else) iterazione condizionale (while) casi di studio modifiche controllate di immagini rimozione occhi rossi posterizzazione 2
casi di studio eliminare occhi rossi posterizzare (I) posterizzare (II) 3 Eliminazione occhi rossi Effetto causato dal flash che viene riflesso dal fondo della retina Vogliamo sostituire il rosso con un colore a nostra scelta colore di sostituzione Possibile algoritmo! pixel px Pict :! se colore di px è rosso" allora assegna a px un colore di sostituzione"
Eliminazione occhi rossi traduzione in Python parametri? valori? comandi? Possibile algoritmo! pixel px Pict :! se colore di px è rosso" allora assegna a px un colore di sostituzione" def removeredeye_1(pict, replacementcolor) :" for px in getpixels(pict) :"oppure for x in range(0,getwidth(pict)) :"???! getcolor(px)" setcolor(px, replacementcolor)" for y in range(0,getheight(pict)) :" px = getpixel(pict,x,y)" Il comando if : sintassi if test1 :! elif test2 :! comando2!...! else :! comando! uno o più elif opzionali ( else if ) un blocco else opzionale if (elif) else facenti parte dello stesso comando devono essere allineati if test1 :! if test1 :! else :! comando! if test1 :! elif test2 :! comando2! else :! comando!...! 6
Il comando if : semantica (1) if test1 :! if test1 :! else :! comando! vero test1! falso vero test1! falso comando! 7 Il comando if : semantica (2) if test1 :! elif test2 :! comando2! else :! comando! vero test1! falso vero test2! falso comando2! comando! 8
Ritorniamo a : eliminazione occhi rossi Possibile algoritmo! pixel px Pict :! se colore di px è rosso" allora assegna a px un colore di sostituzione" traduzione in Python: def removeredeye_1(pic, replacementcolor) :" for px in getpixels(pict) :" oppure for x in range(0,getwidth(pict)) :" comando if for y in range(0,getheight(pict)) :" px = getpixel(pict,x,y)"???! getcolor(px)" setcolor(px, replacementcolor)" 9 Eliminazione occhi rossi : 1 a versione def removeredeye_1(pict, replacementcolor) :" # @param replacementcolor: color" for x in range(0,getwidth(pict)) :" for y in range(0,getheight(pict)) :" px = getpixel(pict,x,y)" if getcolor(px)==red :" setcolor(px, replacementcolor) " Provate a eseguirla con replacementcolor uguale a black, per esempio Che cosa osservate? Perchè? 10
Distanza tra colori? Serve definirla, p.es. per decidere se qualche colore è abbastanza vicino a qualcun altro Come misurare la distanza tra colori? Immaginiamo di essere in un sistema di coordinate cartesiane Distanza tra due punti :! Distanza tra due colori : 11 Eliminazione occhi rossi : 2 a versione def removeredeye_2(pict, replacementcolor) :" # @param replacementcolor: color" for x in range(0,getwidth(pict)) :" for y in range(0,getheight(pict)) :" px = getpixel(pict,x,y)" if (distance(getcolor(px),red) < 165) :" setcolor(px, replacementcolor) " Provate a eseguirla Che cosa osservate? Perchè? 12
Eliminazione occhi rossi : 3 a versione def removeredeye_3(pict, startx,starty,endx,endy,replacementcolor) :" # @param replacementcolor: color" # @param startx, starty, endx, endy : int" for x in range(startx,endx) :" for y in range(starty,endy) :" px = getpixel(pict,x,y)" if (distance(getcolor(px),red) < 165) :" setcolor(px, replacementcolor) " Che cosa abbiamo modificato rispetto alla 2a versione: dentro il rettangolo di pixel (startx,starty) fino a (endx, endy) : trova i pixel abbastanza rossi, e sostituiscili con un nuovo colore Perchè? perchè non vogliamo cambiare il colore del suo vestito rosso! 13 Eliminazione occhi rossi : possibili miglioramenti removeredeye(jenny, 109, 91, 202, 107, makecolor(0,0,0)) 14
Eliminazione occhi rossi : una versione differente (1) senza usare cicli annidati equivalenti complessità? quante iterazioni? come contarle? def removeredeye_3(pict, startx,starty,endx,endy,replacementcolor) :" # @param replacementcolor: color" # @param startx, starty, endx, endy : int" for x in range(startx,endx) :" for y in range(starty,endy) :" px = getpixel(pict,x,y)" if (distance(getcolor(px),red) < 165) :" setcolor(px, replacementcolor) " def removeredeye_3b(pict, startx,starty,endx,endy,replacementcolor) :" # @param replacementcolor: color" # @param startx, starty, endx, endy : int" for px in getpixels(pict):" x = getx(px)" y = gety(px)" if x >= startx and x < endx :" if y >=starty and y < endy :" if (distance(getcolor(px),red) < 165) :" setcolor(px, replacementcolor) " 16 confronto def removeredeye_3(pict, startx,starty,endx,endy,replacementcolor) :" # @param replacementcolor: color" # @param startx, starty, endx, endy : int" # @return int; numero iterazioni effettuate! count = 0! for x in range(startx,endx) :" for y in range(starty,endy) :" count = count+1! px = getpixel(pict,x,y)" if (distance(getcolor(px),red) < 165) :" conteggio del numero di iterazioni effettuate setcolor(px, replacementcolor)" def removeredeye_3b(pict, startx,starty,endx,endy,replacementcolor) :" return count! # @param replacementcolor: color" # @param startx, starty, endx, endy : int" # @return int; numero iterazioni effettuate! count = 0! for px in getpixels(pict):" count = count+1! notare l allineamento del x = getx(px)" comando return! y = gety(px)" if x >= startx and x < endx :" if y >=starty and y < endy :" if (distance(getcolor(px),red) < 165) :" setcolor(px, replacementcolor)" 17 return count!
Espressioni logiche Che cosa è un test? una espressione (proposizione) logica una espressione che assume i valori vero o falso Come si costruiscono espressioni logiche in Python? usando operatori di confronto : < <= ==!= > >=! usando operatori (connettivi) logici : if test1 :! elif test2 :! comando2!...! else :! comando! and or not! e costanti logiche (boolean) : true false! 18 Operatori logici a! b! a and b! a! b! a or b!!!!!! F! F! F! F!! F F!! F! F! F F! F! F a! not a!! F! F 19
Espressioni logiche esempi >>> max_candidates = 100" >>> started_exam = true" >>> participants = 58" espressione! started_exam! participants < max_candidates! participants == 40! (participants % 2) == 0! not started_exam! started_exam or participants == max_candidates! not(not started_exam and participants<=max_candidates)! participants>max_candidates and participants>=0! valore! F F F 20 Eliminazione occhi rossi : una versione differente (2) usando una espressione logica invece di if annidati def removeredeye_3b(pict, startx,starty,endx,endy,replacementcolor) :" # @param replacementcolor: color" # @param startx, starty, endx, endy : int" for px in getpixels(pict):" x = getx(px)" y = gety(px)" if x >= startx and x < endx :" if y >=starty and y < endy :" if (distance(getcolor(px),red) < 165) :" setcolor(px, replacementcolor)" def removeredeye_3c(pict, startx,starty,endx,endy,replacementcolor) :" # @param replacementcolor: color" # @param startx, starty, endx, endy : int" for px in getpixels(pict):" x = getx(px)" y = gety(px)" if x >= startx and x<endx and y >=starty and y<endy and (distance(getcolor(px),red)<165) :" 21 setcolor(px, replacementcolor) "
Posterizzazione : riduzione della gamma di colori 22 Posterizzazione: come realizzarla Cerchiamo una gamma di colori, e li riduciamo a un singolo colore. se la componente red è tra 63 e 128, assegnagli valore 95 se la componente green è minore di 64, assegnagli valore 31 31 95 191 0 < > 63, 64 < > 127, 128 < > 255 23
Posterizzazione : algoritmo possibile algoritmo:! pixel in picture :" se red di pixel è nel rangea! allora assegnagli valore reda;" se red di pixel è nel rangeb! allora assegnagli valore redb;" se red di pixel è nel rangec! allora assegnagli valore redc ;"... (si procede in modo analogo per green e blue)..." reda redb redc 31 95 191 rangea rangeb rangec 0 < > 63, 64 < > 127, 128 < > 255 24 Posterizzazione : codice Python def posterize(pict):" # iterazione su tutti i pixel" for p in getpixels(pict):" # ricava i valori RGB" red = getred(p)" green = getgreen(p)" blue = getblue(p)" # controlla e modifica i valori red" if(red < 64):" setred(p, 31)" if(red > 63 and red < 128):" setred(p, 95)" if(red > 127 and red < 256):" setred(p, 191)" # controlla e modifica i valori green" if(green < 64):" setgreen(p, 31)" if(green > 63 and green < 128):" setgreen(p, 95)" if(green > 127 and green < 256):" setgreen(p, 191)" # controlla e modifica i valori blue" if(blue < 64):" setblue(p, 31)" if(blue > 63 and blue < 128):" setblue(p, 95)" if(blue > 127 and blue < 256):" setblue(p, 191) 31 95 191 0 < > 63, 64 < > 127, 128 < > 255 25
Posterizzazione estrema: da colore a bianco o nero def bwposterize(pict):" for p in getpixels(pic):" r = getred(p)" g = getgreen(p)" b = getblue(p)" luminance = (r+g+b)/3" if luminance < 64:" setcolor(p,black)" if luminance >= 64:" setcolor(p,white)" Si controlla la luminanza di ogni pixel. Se è abbastanza bassa, è nero, altrimenti è bianco casi di studio data un immagine, verificare se il componente red di ogni suo pixel ha un valore maggiore di una certa soglia data un immagine e un colore, verificare se quel colore è presente nell immagine date due immagini, verificare se ogni colore presente nella prima esiste anche nella seconda problemi riconducibili allo scrivere funzioni logiche: funzioni che restituiscono un valore logico 27
Uso di Python per codificare proposizioni logiche Notazione preliminare: D : insieme di valori numeri, immagini, stringhe di caratteri, colori, pixel, x : elemento dell insieme D B : D {vero, falso} proposizione logica sull insieme D dato x D, B(x) può valere vero o falso 28 Esempi D : insieme di pixel (da un immagine) B : D {vero, falso} definita in questo modo: B(x) = vero se la componente red di x è 24 B(x) = falso altrimenti (cioè: se red di x è <24) oppure B(x) = vero se il colore di x è : red = r, green = g, blue = b B(x) = falso altrimenti r, g, b valori interi (compresi tra 0 e 255) 29
Codifica Python B : D {vero, falso} definita in questo modo: B(x) = vero se la componente red di x è 24 B(x) = falso altrimenti (cioè: red di x è <24) def B(x) :" # @param x : pixel;" if getred(x) >= 24 :" return true" else :" return false" Esempio di uso: " >>> pict = makepicture(pickafile())" def B(x) :" # @param x : pixel;" return getred(x) >= 24 " le due formulazioni sono equivalenti! " >>> if B(getPixel(pict,0,0)) : # applica B() al 1 pixel di pict" " 30 Codifica Python B : D {vero, falso} definita in questo modo: B(x) = vero se il colore di x è : red = r, green = g, blue = b B(x) = falso altrimenti r, g, b valori interi (compresi tra 0 e 255) def B(x,r,g,b) :" # @param x : pixel;" # @param r: int; (0 r 255)" # @param g: int; (0 g 255)" # @param b: int; (0 b 255)" if getcolor(x) == makecolor(r,g,b) :" return true" else :" return false" le tre formulazioni sono equivalenti! def B(x,r,g,b) :" # @param x : pixel;" # @param r: int; (0 r 255)" # @param g: int; (0 g 255)" # @param b: int; (0 b 255)" return getcolor(x) == makecolor(r,g,b)" def B(x,r,g,b) :" # @param x : pixel;" # @param r: int; (0 r 255)" # @param g: int; (0 g 255)" # @param b: int; (0 b 255)" 31 return getred(x) == r and getgreen(x) == g and getblue(x) == b"
def B(x) :" # @param x : pixel;" return getred(x) >= 24 " Proposizioni logiche def B(x,r,g,b) :" # @param x : pixel;" # @param r: int; (0 r 255)" # @param g: int; (0 g 255)" # @param b: int; (0 b 255)" return getcolor(x) == makecolor(r,g,b)" def B(x,r,g,b) :" # @param x : pixel;" # @param r: int; (0 r 255)" # @param g: int; (0 g 255)" # @param b: int; (0 b 255)" return getred(x) == r and getgreen(x) == g and getblue(x) == b" utte queste funzioni codificano proposizioni logiche costruite tramite operatori di relazione oppure operatori (connettivi) logici ma esistono anche altri tipi di operatori (predicati) definiti nella logica del 1 ordine 32 Quantificatori altri operatori logici: quantificatore universale: x D : B(x) vero sse B(x) è vero per ogni x D quantificatore esistenziale: x D : B(x) vero sse B(x) è vero per almeno un x D in entrambi i casi, B(x) è una qualunque proposizione logica definita sull insieme D come codificarli in Python? a differenza di operatori di relazione e connettivi logici (and, or, not), Python non offre una codifica predefinita per i quantificatori 33
Codifica di in Python Quantificatore universale: x D : B(x) Assunzione: D è rappresentabile come una sequenza Python def univ(d) :" # @param D : " for item in D :" if not B(item, ) :" return false" return true " 34 Esempio d uso della codifica di in Python Problema: data un immagine, verificare se il componente red di ogni suo pixel ha un valore maggiore di una certa soglia (24) B() definito come: def B(x) :" # @param x : pixel;" return getred(x) >= 24 " Funzione logica che risolve il problema: " " def univ(d) :" # @param D : sequence of pixels" for item in D :" if not B(item) :" return false" return true " chiamata di B(): un solo parametro, in questo caso >>> pict = makepicture(pickafile())" >>> univ(getpixels(pict)) 35
Codifiche alternative di in Python def univ(d) :" # @param D : " for item in D :" if not B(item) :" return false" return true " le tre formulazioni sono equivalenti! (ma non ugualmente efficienti ) def univ(d) :" # @param D : " res = true" for item in D :" if not B(item) :" res = false" return res" def univ(d) :" # @param D : " res = true" for item in D :" if not B(item) :" res = false" break" return res" il comando break interrompe l esecuzione di un comando iterativo; l esecuzione prosegue dal comando immediatemente successivo al comando iterativo 36