Una delle caratteristiche di un computer è la velocità e le precisione nello svolgere azioni ripetitive: quello che annoierebbe a morte una persona umana, portandola a deconcentrarsi ed a sbagliare, viene fatto senza batter ciglio da un computer, che può ripetere un blocco di istruzioni miliardi di volte senza stancarsi. Nei linguaggi di programmazione ci sono sempre istruzioni per ottenere dei cicli (Inglese: loops).
Un ciclo è un blocco di istruzioni (sempre riconosciuto da Python per mezzo dell'indentazione) che può essere ripetuto più volte.
Il controllo su quante volte ripetere un ciclo sarà assunto da un'apposita istruzione di controllo di flusso, che determinerà quando si deve uscire dal ciclo (cioè continuare con le istruzioni successive). Se commettiamo uno sbaglio in questa istruzione, possiamo entrare in un ciclo senza fine (Inglese: "endless loop") cioè in un ciclo che si ripete all'infinito: è un comune errore di programmazione che fa in genere "inchiodare" il programma. Se questo ci accade in Python possiamo premere insieme Control C per terminare il programma "a forza bruta".
Aprite l'editor e digitate questo nuovo esempio (potete omettere i commenti, che servono solo a spiegarvi cosa fa il programma):
s = "" # stringa vuota: serve per inizializzare la variabile s
while s != "mamma": # while con l'espressione di controllo
s = input("Scrivi 'mamma' ") # questo è il blocco da ripetere
print ("Bravo!") # qui si esce dal ciclo
Provate a lanciare il programma, che vi chiederà di scrivere "mamma". Scrivete per due o tre volte un'altra parola e vedrete che il programma continuerà a chiedervi la stessa cosa. Solo quando scriverete esattamente "mamma" (con tutte lettere minuscole) il programma vi dirà "Bravo!"
L'istruzione while
permette di ripetere un blocco di linee finchè una
condizione di controllo (espressione booleana) rimane vera. Quando il programma giunge al while
valuta l'espressione: se essa è vera entra nel ciclo (cioè in una serie di linee
indentate come nell'if
); alla fine dell'indentazione ritorna al while
e
valuta di nuovo l'espressione: se essa è ancora vera riesegue il ciclo e così via. Quando
l'espressione diventa falsa il programma esce dal ciclo e continua con la prima linea allo stesso
livello di indentazione del while
.
Quindi il programma funziona così: all'inizio si assegna a s
la stringa vuota. Nella seconda
riga il while
si chiede se essa sia diversa da "mamma"
: poichè questo è vero il
programma entra nel ciclo (cioè la terza riga indentata). Questa viene ripetuta finchè s
è diversa da "mamma", e si esce dal solo quando la condizione di controllo diventa falsa (cioè
quando s
diventa uguale a "mamma").
Provate ad eliminare la prima riga: cosa succede? Otterrete un NameError
perchè nell'espressione s != "mamma"
Python trova la variabile s
non
ancora definita (ricordate questo). Provate invece
a sostituire la prima riga con questa
s = "mamma"
:
adesso invece il programma scriverà direttamente "Bravo!": infatti il primo while
trova falsa l'espressione booleana s != "mamma"
e non entra per niente nel ciclo.
Prima di entrare in un ciclo while
è necessario che le variabili che compaiono
nella condizione di controllo siano già definite (altrimenti si ottiene un errore). Se all'entrata nel
ciclo la condizione è falsa il ciclo viene completamente saltato.
Vuoi giocare ancora (s/n)? s
Vuoi giocare ancora (s/n)? s
Vuoi giocare ancora (s/n)? s
Vuoi giocare ancora (s/n)? n
Ciao!
SUGGERIMENTO: Create all'inizio una stringa risp = "s"
Il while
e l'if
ci permettono già di programmare un semplice
giochino. Cercate per il momento di non usare ancora il copia-incolla: è opinione comune che scrivere
le righe una per una faciliti la comprensione del programma; eventualmente potete saltare i commenti.
from random import * # verra' spiegata in seguito
num = randrange(1, 21) # questa istruzione genera un numero casuale da 1 a 20: dovremo indovinarlo
print ("Ho pensato un numero da 1 a 20. Prova ad indovinarlo!")
mio_num = -1 # inizializza mio_num ad un valore sicuramente diverso da num ...
while mio_num != num: # ... quindi la prima volta entra sicuramente nel while
mio_num = int(input("??? ")) # qui introduciamo il nostro tentativo (mio_num)
if mio_num < num:
print("Troppo basso")
elif mio_num > num:
print("Troppo alto")
print("Hai indovinato!")
Provate a lanciare il programma e ad indovinare il numero; cercate poi di capire qual è la funzione di ogni singola riga. Questo programma può essere usato come base per altri sviluppi:
num = randrange(1, 21)
alla fine in un while
esterno come quello implementato nell'esercizio 8.1. Per indentare molte linee in una sola volta conviene
selezionarle con il mouse ed usare la voce di menu Format=>Indent Region.tentativi
che va inizializzata a 0 prima del gioco ed incrementata
di uno ad ogni tentativo. Attenti a dove dovete scrivere le istruzioni di inizializzazione e di
incremento. All'uscita dal ciclo basta modificare l'istruzione print
facendole scrivere
anche il numero di tentativi.import
, creare una
variabile record
inizializzandola ad un numero altissimo (es. record = 100000000
).
Dopo ogni partita controllare se tentativi
è minore di record
: in questo caso
abbiamo battuto il vecchio record: stampare un messaggio di complimenti ed assegnare a record
il nuovo valore (che diventa così il nuovo record). Inizializzando record
al valore fittizio
1000000000 siamo sicuri che la prima volta che giocherà l'utente batterà sicuramente il record.Ho pensato un numero da 1 a 20. Prova a indovinarlo!
??? 12
Troppo basso
??? 16
Troppo alto
??? 14
Troppo alto
??? 13
Hai indovinato! Hai impiegato 4 tentativi
Hai battuto il tuo record.
SOLUZIONI
A volte sappiamo esattamente prima del ciclo quante volte dovremo eseguirlo (ad esempio, se
dobbiamo stampare 10 righe di testo, ...). In questi casi si usa in genere un'altra istruzione,
il for
, ma a scopo didattico useremo una costruzione equivalente che ci renderà poi
più facile capire l'altra istruzione.
Una variabile contatore viene inizializzata (in genere a 0) prima del ciclo e viene incrementata ogni volta che il ciclo viene eseguito. La condizione di controllo fa eseguire il ciclo fino a quando la variabile raggiunge il valore voluto.
Vediamo un esempio:
Partiamo con un programma che stampa i numeri da 0 a 9.
i = 0 # inizializza il contatore
while i < 10:
print(i)
i += 1 # incrementa il contatore (vuol dire: i = i + 1)
Il while
viene ripetuto esattamente 10 volte: i
parte da 0 ed ogni volta è
incrementata di 1; si uscirà quando i
diventerà 10 (cioè i < 10
risulterà falsa).
Nell'uso comune, se dobbiamo ripetere un ciclo 100 volte, il contatore andrà da 0 a 99, e quindi la
condizione di controllo sarà while i < 100
: questa tradizione viene dal linguaggio C.
Modifichiamo temporaneamente il programma così e lanciamolo:
i = 0
while i < 100:
print("AMO GIULIETTA")
i += 1
Ora ritorniamo al nostro programma e vediamo gli esercizi.
3 x 1 = 3
3 x 2 = 6
. . .
3 x 10 = 30
ESERCIZIO 8.6: Modificare il programma in modo che all'inizio chieda all'utente "Quale tabellina vuoi
stampare?", accetti in input un numero e stampi quella tabellina.1 1 1
2 4 8
3 9 27
4 16 64
...
SUGGERIMENTO: usa il carattere di tabulazione \t
per distanziare i numeri, vedi
quiFine della lezione