# Parentesi graffe: quando si possono omettere? * `if`, `else`, `for`, e `while` possono essere utilizzati senza parentesi graffe * In questo caso è come se le parentesi si trovassero intorno all'istruzione che segue (e **solo a quella**) * Questi quattro `if` sono tutti equivalenti ```C if(a == 1) printf("a == 1\n"); if(a == 1) printf("a == 1\n"); if(a == 1) printf("a == 1\n"); if(a == 1) { printf("a == 1\n"); } ```
Quale di queste versioni è la più chiara? E quale la meno ambigua?
--- # Un esempio * Cosa stampa questo codice? ```C #include <stdio.h> int main() { int i, j, N = 10; for(i = 0; i < N; i++) j = i * 2; printf("%d %d\n", i, j); return 0; } ``` ```bash $ ./es_graffe 10 18 ```
Omettere le parentesi vi fa risparmiare due (!) caratteri ma perdere in chiarezza e robustezza. Compilate con
-Wall
per trovare questo e altri problemi!
--- # Un problema di analisi dati * Conducete un esperimento che dà come risultato un valore numerico, $x$ * Volete confrontare i risultati sperimentali con una predizione teorica, che vi dà la probabilità che si verifichi $x$, cioè $P(x)$ * Esempio: volete capire se un dado è truccato o meno * Vi aspettate che ogni faccia appaia con una probabilità $1 / 6$ * Lanciate il dado 100 volte ottenendo questi risultati: `2 3 6 3 3 1 2 2 5 4 3 1 5 1 3 3 5 4 6 1 5 1 1 1 5 5 2 1 2 3 1 5 1 3 5 1 2 6 5 6 1 5 2 4 2 2 5 1 1 6 4 5 1 1 3 4 5 1 5 3 6 2 6 1 1 3 4 6 6 3 4 3 6 1 5 5 5 6 4 4 4 4 3 3 1 5 5 2 2 1 4 1 6 5 4 3 4 4 3 6`
Come possiamo capire se il dado è truccato o meno? Generandone l'istogramma!
--- # Istogramma di numeri interi * Dati $N$ numeri interi $\in [{\rm MIN}, {\rm MAX}]$, l'istogramma è un grafico che mostra quante volte ogni intero appare nella sequenza (mostra quindi le *occorrenze* di ogni intero) * Nel programma usiamo un array `int occorrenze[MAX - MIN + 1]` per immagazzinare le occorrenze * Scorriamo la sequenza: ogni volta che troviamo `num` incrementiamo la casella corrispondente, `occorrenze[num - MIN]++`
* In questo caso * `MIN == 1` * `MAX == 6`
--- # Istogramma di interi - esempio in C ```C [|4-6|10,11|13,14|15|18-20] #include <stdio.h> #include <stdlib.h> #define LANCI 100 #define MIN 1 #define MAX 6 int main() { int i; int occorrenze[MAX - MIN + 1] = {0}; srand48(41239); for(i = 0; i < LANCI; i++) { int faccia = (int)(drand48() * (MAX - MIN + 1)) + MIN; occorrenze[faccia - MIN]++; } for(i = 0; i < MAX - MIN + 1; i++) { printf("%d %d\n", i + MIN, occorrenze[i]); } return 0; } ``` --- # Istogramma di sequenze generiche * In un esperimento normale i risultati possono essere dei numeri decimali * Esempio: abbiamo un dataset con le altezze (in metri) di 1000 persone * I numeri sono *continui*, `1.86 != 1.87`... * Dobbiamo fare una scelta: dividiamo l'intervallo in `N_BINS` sotto-intervalli o *bin* * Ogni bin avrà una larghezza pari a `width = (MAX - MIN) / N_BINS` * Un dato `x` appartiane al bin numero `(int) ((x - MIN) / width)`
* In questo caso * `MIN == 1.5` * `MAX == 1.9` * `N_BINS == 10`
--- # Istogramma generico - esempio in C ```C [|4-7|11,12|14|16,21|17,20|18-19|23-25] #include <stdio.h> #include <stdlib.h> #define N_DATI 1000 #define N_BINS 10 #define MIN 1.5 // può essere inserito dall'utente o calcolato automaticamente #define MAX 1.9 // può essere inserito dall'utente o calcolato automaticamente int main() { int i, occorrenze[N_BINS] = {0}; double width = (MAX - MIN) / N_BINS; double dati[N_DATI]; /* generiamo o leggiamo da file i dati */ for(i = 0; i < N_DATI; i++) { if(dati[i] < MAX && dati[i] > MIN) { // assicuriamoci di non accedere a bin non esistenti int bin = (int)((dati[i] - MIN) / width); occorrenze[bin]++; } } for(i = 0; i < N_BINS; i++) { printf("%lf %d\n", i * width + MIN, occorrenze[i]); } return 0; } ``` --- # Occorrenze $\to$ probabilità * Per passare dal numero di occorrenze alla probabilità si divide l'istogramma per il numero **totale** di occorrenze ```C[|3-7|9-12] // prima calcoliamo le occorrenze (non mostrato) // sommiamo su tutti i bin double sum = 0.; for(i = 0; i < N_bins; i++) { sum += occorrenze[i]; } // stampiamo la probabilità for(i = 0; i < N_BINS; i++) { printf("%lf %lf\n", i * width + MIN, occorrenze[i] / sum); } ```