Archivio tag: if else

Realizzare un ciclo iterativo con l’istruzione repeat

Abbiamo già visto come realizzare un ciclo iterativo in R sfruttando le istruzioni for e while. Se il primo ciclo è definito da un numero predeterminato di iterazioni, il secondo è invece potenzialmente infinito e sarà la condizione logica espressa al momento del lancio a stabilire il criterio d’arresto. Di solito, il ciclo for si usa quando già prima della sua esecuzione è noto il numero di iterazioni da eseguire, mentre il ciclo while non richiede questa conoscenza: se all’interno del ciclo accade qualcosa che soddisfa la condizione d’arresto, allora il while si chiuderà.

Per comprendere il terzo ciclo, il repeat, è necessario aver ben digerito i primi due, che consiglio di andare a rivedere nel caso di dubbi (qui e qui).

Il ciclo repeat è, come il while, potenzialmente infinito. La differenza è che, rispetto al while, il repeat è ancora meno restrittivo perché non richiede di specificare alcuna condizione d’arresto; se non si presta molta attenzione, infatti, si rischia veramente di far perdere l’interprete R all’interno di un loop infinito! In questi casi, solo la brutale chiusura del programma potrà fermare il ciclo.

Utilizzare l’istruzione repeat è semplicissimo (attenzione: il codice qui sotto genera un ciclo infinito):

repeat {
    # Codice da eseguire
}

Fra i tre cicli iterativi di R, il repeat è certamente il più flessibile: l’arresto è determinato esclusivamente da quello che accade al suo interno. La vera sfida nell’uso di repeat non è tanto comprendere come funziona il comando quanto piuttosto capire come fermarlo!

Per controllare l’evolversi delle iterazioni, R mette a disposizione due istruzioni che sono next e break. La prima interrompe una iterazione per saltare direttamente alla successiva, mentre la seconda ferma tutto e chiude definitivamente il ciclo.

Per esempio, il seguente codice lancia un ciclo di iterazioni che vengono immediatamente bloccate con la conseguente uscita dal loop:

repeat {
    break
}

Ovviamente, questo non è sufficiente per utilizzare repeat in maniera proficua. Noi dobbiamo essere in grado non solo di bloccare le iterazioni ma anche di controllare quando bloccarle. Per questo motivo, le istruzioni next e break devono essere combinate con altre due istruzioni, che sono if ed else. Queste indicano a R cosa fare “se” (if) si presenta una certa situazione, e cosa fari “altrimenti” (else), nel caso in cui la condizione espressa dalla if non fosse verificata.

Dato che vedere il codice in azione è sempre più eloquente di mille spiegazioni, vediamo di utilizzare un po’ questi comandi per comprenderli meglio.

Cerchiamo di realizzare un ciclo di dieci iterazioni utilizzando l’istruzione repeat. Il ciclo non dovrà fare altro che stampare a video il numero di iterazioni eseguite, e bloccarsi al termine della decima. Ecco quindi il codice che dovremo utilizzare:


i <- 0 repeat { i <- i+1 print(i) if(i == 10) { break } } [/code]

Analizziamolo. Abbiamo inizializzato la variabile i col valore zero. Dopodiché siamo entrati nel ciclo e abbiamo aggiornato il valore di i, incrementandolo di uno. Questa operazione verrà eseguita a ogni iterazione, in modo che i conti quante iterazioni sono state eseguite sino a quel momento. Quindi, con il comando print, stampiamo a video il valore di i.

A questo punto viene la parte difficile: dobbiamo verificare a quale iterazione siamo arrivati, ovvero qual è il valore di i, perché, se siamo arrivati a 10, dobbiamo arrestare il ciclo. Per farlo ci serviamo dell’istruzione if, che verifica se i è uguale a 10.

Attenzione! if è un comando che valuta la verità di una condizione logica: se la condizione è vera, allora il codice inserito all’interno delle sue parentesi graffe verrà eseguito, altrimenti, se c’è un else consecutivo verranno eseguite le operazioni interne alla else. Se dopo la if non ci dovesse essere un else (come nel nostro caso), semplicemente l’esecuzione del codice proseguirà indisturbata. Facciamo subito un esempio:


i <- 0 repeat { i <- i+1 print(i) if(i == 10) { break } else { print("Via al prossimo ciclo!") } } [/code]

Qui sopra è stata aggiunta una condizione alternativa alla if che stampa a video una stringa nel caso i non dovesse valere 10.

Ora immaginiamo di voler saltare il secondo ciclo; vogliamo sì arrivare al decimo, ma senza eseguire il secondo. È in questi casi che entra in gioco l’istruzione next:


i <- 0 repeat { i <- i+1 if(i == 2) { next } else { print(i) if(i == 10) { break } } } [/code]

Il codice qui sopra, non appena troverà che i vale due, salterà direttamente alla terza iterazione, altrimenti proseguirà con le operazioni. Quando si iniziano ad annidare istruzioni if ed else il rischio di scordarsi la chiusura di una parentesi è sempre molto elevato, ed è per questo che ho scelto di indentare il codice.

Si faccia attenzione che, quando il corpo dell’istruzione if contiene un’unica riga di codice, le parentesi graffe possono anche essere omesse (lo stesso vale per else).


i <- 0 repeat { i <- i+1 if(i == 2) { next } else { print(i) if(i == 10) break } } [/code]

A questo punto non mi resta che augurarvi buon divertimento!