Un "function handle" e una variabile il cui valore e una funzione. Data una funzione esistente, il suo function handle è dichiarato come handle = @nome dove nome è il nome di tale funzione esistente. Una volta dichiarato l handle, è possibile invocarlo come fosse una funzione: 1 handle_sum = @sum; 3 handle_sum([3 ]); Un function handle può essere dichiarato anche al volo, ossia su una funzione non esistente. Ad esempio: handle = @(x) x*3 e un handle di una funzione anonima che accetta in ingresso un parametro formale x e svolge su di esso una moltiplicazione. Si noti che x 3 è a tutti gli effetti il corpo della funzione anonima. 1 handle = @(x) x*3 3 handle(10) Essendo variabili, gli handle possono essere passati ad altre funzioni, e così via, creando le cosiddette funzioni di ordine superiori, in quanto ricevono in ingresso altre funzioni (come handle). 1 handle_es = @(vett, func) func(vett) 3 handle_es([3 ], @sum) 4 handle_es([3 ], handle_sum) 1
14.1 Esercizi Esercizio 14.1 Si definisca una funzione che riceve in ingresso un function handle e due variabili x e y contenenti numeri. Tale funzione, chiamata controlla_funzione, dovrà controllare se applicando ad x la funzione passata tramite function handle si ottiene y, e ritornare 1 o 0 a seconda che tale controllo vada a buon fine o meno. Estendere l esempio ai vettori, ovvero costruire controlla_funzione_vettori affinchè riceva in ingresso un vettore X e un vettore Y, e controlli che la condizione di cui sopra valga per tutti gli elementi corrispondenti di X e Y. Si implementi operazione affinchè controlli che y sia il doppio di x. Esercizio 14. Scrivere una funzione filtra che riceva come parametri una funzione cond (function handle) e un vettore strutturato: 1 vett(1).x vett(1).y 3 4 vett().x 5 vett().y 6 7... 8 9 vett(n).x 10 vett(n).y La funzione cond riceve in ingresso due parametri, a e b, e ritorna 1 (true) se a è maggiore di b, altrimenti ritorna 0 (false). La funzione di ordine superiore filtra dovrà utilizzare la funzione cond, ricevendone in ingresso un suo function handle, al fine di filtrare il vettore ricevuto in ingresso, costruendo un vettore che contenga solo quegli elementi che hanno il campo x maggiore del campo y. Sperimentare con altre funzioni al posto di cond. Ad esempio minore di, oppure uguale a, oppure uno il doppio dell altro, etc. Esercizio 14.3 Implementare la funzione di ordine superiore vrand che riceve in ingresso un function handle e un numero reale tra 0 e 1. Non si sa nulla sul function handle, se non che va A.A.014 015 Informatica B (081369) - Politecnico di Milano Pag.
chiamato senza alcun argomento. Ad esempio: handle(). vrand dovrà chiamare la funzione passata come handle. Se il numero ritornato da tale chiamata è maggiore del numero reale ricevuto come parametro, questo viene ritornato immediatamente, se invece è inferiore, si dovrà continuare a chiamare la funzione finchè questa non restituirà un numero maggiore del reale passato. Utilizzare vrand per realizzare un dado a sei facce truccato. Chiamare 100 volte la vrand e salvare i valori così ottenuti in un vettore V. Realizzare poi altre 100 estrazioni usando la rand al posto della vrand e salvare tali valori in un vettore R. Infine, utilizzare plot() per visualizzare le estrazioni di R e V: su due grafici diversi sullo stesso grafico con colori diversi. Esercizio 14.4 Il sistema di messaggistica di Facebook permette di ricevere messaggi da qualsiasi mittente. Un messaggio e caratterizzato da un mittente e da un testo. Vogliamo implementare un sistema di filtraggio per rilevare automaticamente messaggi indesiderati, basandoci sulle seguenti ipotesi semplificative: se il messaggio e ricevuto da una persona conosciuta, ossia da una persona nella lista degli amici, allora il messaggio non e da scartare se il messaggio e ricevuto da una persona sconosciuta, ossia non presente nella lista degli amici, allora e necessario esaminare la storia dei messaggi ricevuti in passato, per determinare un "valore atteso" che ci permetta di decidere se il messaggio appena ricevuto e nella media. Quindi servira una funzione: 1 [buono motivo] = filtra_messaggio(messaggio, messaggi, amici); dove: buono e di tipo logical che vale vero solo se il messaggio e buono motivo e di tipo char, e vale: a ad indicare che il messaggio e buono perche inviato da un amico m ad indicare che il messaggio e buono perche nella media dei messaggi passati A.A.014 015 Informatica B (081369) - Politecnico di Milano Pag. 3
x ad indicare che il messaggio e cattivo perche non ha passato nessuno dei due criteri precedenti messaggio e una struttura dati a due campi (mittente e testo), entrambi stringhe il cui significato e autoesplicativo. Ad esempio: 1 messaggio.testo = 'Ciao come stai?' messaggio.mittente.nome = 'Federico' 3 messaggio.mittente.cognome = 'Maggi' messaggi e un vettore contenente i messaggi ricevuti in passato. Utilizzeremo la medesima struttura dati di cui sopra. amici e un vettore contenente gli amici. Utilizzeremo una struttura dati contenente i campi nome e cognome. Il filtraggio basato sul mittente e semplice: e sufficiente verificare che il mittente sia presente nel vettore degli amici. Invece, il filtraggio basato sul contenuto e piu complesso. Implementare 1 [l v c] = estrai_caratteristiche(testo) l e la lunghezza del messaggio, esclusi gli spazi v e il numero di vocali c e il numero di consonanti 1 [Mm, Dm] = valore_atteso(messaggi) Mm e un vettore riga di 3 colonne, con il valor medio dei tre valori [l v c] calcolati su tutti i messaggi Dm e un vettore riga di 3 colonne, con la deviazione standard dei tre valori [l v c] calcolati su tutti i messaggi Facoltativamente implementare anche 1 buono = controlla_contenuto(messaggio, messaggi) la quale ritornera un valore logical vero solo se il messaggio ha le caratteristiche [l v c] che soddisfano tutte le tre seguenti condizioni: medio(l) - sqrt() * std(l) <= l <= medio(l) + sqrt() * std(l) A.A.014 015 Informatica B (081369) - Politecnico di Milano Pag. 4
medio(v) - sqrt() * std(v) <= v <= medio(v) + sqrt() * std(v) medio(c) - sqrt() * std(c) <= c <= medio(c) + sqrt() * std(c) Supporre che le strutture dati amici e messaggi sono già disponibili in un file facebook.mat, vanno caricate all inizio dello script. A.A.014 015 Informatica B (081369) - Politecnico di Milano Pag. 5