Il ciclo while

Come ripetere un ciclo un numero di volte non predeterminato.

Abbiamo visto come ripetere blocchi di istruzioni, ma con l’istruzione for il numero di ripetizioni deve essere noto prima che inizi il ciclo. Non sempre ciò è possibile. Supponiamo di voler leggere dei numeri dalla tastiera e continuare a farlo fin quando l’utente non immette un numero convenuto. Il programma non può sapere, all’inizio del ciclo, se l’utente immetterà 3, 5 o 5000 numeri. I linguaggi di programmazione mettono a disposizione un costrutto che permette di risolvere questo problema: il ciclo while. In Pyhton la sintassi è:

while <condizione>:
    <istruzioni>

Scriviamo la procedura che legge numeri scritti dall’utente, ne calcola la somma, e si ferma quando viene immesso il numero 0. La procedura deve:

  • predisporre la variabile che conterrà la somma inizializzandola a 0.
  • eseguire un ciclo in cui legge un numero e lo aggiunge alla somma fin quando il numero è diverso da 0.

Una prima procedura potrebbe essere:

def sommanumeri():
    somma = 0
    while numero <> 0:
        numero = int(raw_input("scrivi un numero: "))
        somma += numero
    print "la somma dei numeri immessi è: %s" % somma

Alcune osservazioni:

  1. somma = 0 è messo prima del ciclo altrimenti verrebbe continuamente azzerato e non memorizzerebbe la somma dei numeri.
  2. L’istruzione print è fuori dal ciclo while infatti non è indentata come le altre istruzioni del blocco di while, quindi verrà eseguita quando il ciclo termina.
  3. Prima di mettere in numero quello che ho letto dalla tastiera, devo convertirlo in intero.

Quando proviamo la procedura otteniamo un errore:

Traceback (most recent call last):
  File "<pyshell#1>", line 1, in -toplevel-
    sommanumeri()
  File "/sorgenti/while.py", line 9, in sommanumeri
    while numero<>0:
UnboundLocalError: local variable 'numero' referenced before assignment

Questo messaggio ci dice che nella linea 9 del file while.py, all’interno della funzione sommanumeri() e precisamente nell’istruzione while numero <> 0:, Pyhton dovrebbe trovare qualcosa dentro la variabile numero, variabile che non è ancora stata definita, quindi non sa come andare avanti. Mettiamo in numero un valore a fantasia, basta che sia diverso da 0 altrimenti il ciclo non viene eseguito neppure una volta. Poi proviamo la procedura:

def sommanumeri():
    somma = 0
    numero = 2652
    while numero <> 0:
        numero = int(raw_input("scrivi un numero: "))
        somma += numero
    print "la somma dei numeri immessi è: %s" % somma

>>> sommanumeri()
scrivi un numero: 4
scrivi un numero: 5
scrivi un numero: 6
scrivi un numero: 0
la somma dei numeri immessi è: 15

Funziona, ma non è scritta bene:

  1. numero deve essere inizializzato con un numero che poi non viene usato.
  2. il numero immesso convenzionalmente per terminare il ciclo viene usato. Fin che è 0 e finché eseguiamo addizioni, non dà fastidio, ma se il numero convenzionale forre 999 o se stessimo eseguendo moltiplicazioni?

Riporto, di seguito due possibili soluzioni:

def sommanumeri2():
    somma = 0
    numero = int(raw_input("scrivi il primo numero: "))
    while numero <> 0:
        somma += numero
        numero = int(raw_input("scrivi un altro numero: "))
    print "la somma dei numeri immessi è: %s" % somma

def sommanumeri3():
    somma = 0
    while True:
        numero = int(raw_input("scrivi un numero: "))
        if numero == 0: break
        somma += numero
    print "la somma dei numeri immessi è: %s" % somma

In quest’ultimo caso la condizione che comanda la ripetizione del ciclo è sempre vera quindi il ciclo non termina naturalmente, ma continua all’infinito. All’interno del ciclo c’è però un’istruzione di selezione che, in certe condizioni, segue l’istruzione break. L’istruzione break fa terminare immediatamente il ciclo in cui si trova.

Riassumendo

  • Il ciclo while permette di ripetere un blocco di istruzioni fin quando è vera una certa condizione. La sintassi è:

    while <condizione>:
        <istruzioni>
    
  • Il ciclo while si usa quando prima di avviare il ciclo non è possibile conoscere per quante volte dovrà essere ripetuto il blocco di istruzioni.

  • In certi casi è comodo realizzare un ciclo infinito e farlo terminare quando si determinano determinate condizioni con l’istruzione break.

Prova tu

  1. Scrivi la procedura che stampa il prodotto di numeri immessi dall’utente.
  2. Scrivi le funzioni che restituiscono la somma e il prodotto di numeri immessi dall’utente.
  3. Scrivi la procedura che legge numeri finquando sono maggiori di 0 e poi stampa la media, il massimo e il minimo dei numeri immessi.