Abbiamo visto che in un while
Python esegue il ciclo ed ogni volta che giunge alla
fine ricontrolla la condizione di controllo ed eventualmente esce dal ciclo. A volte la condizione
per uscire dal while
risulta troppo complicata, altre volte sarebbe preferibile uscire
dal ciclo non alla fine di esso ma ad una linea intermedia. Questo è possibile mediante l'istruzione
break
.
Quando, durante un ciclo, Python incontra l'istruzione break
tutta le linee
dal break
fino alla fine del ciclo vengono saltate ed il programma esce dal ciclo continuando
con la prima istruzione successiva.
Il break
si usa spesso quando dobbiamo fare una ricerca su un insieme di elementi. Supponiamo
di avere un insieme di tante scatole, una delle quali contiene 100 euro. Potenzialmente dobbiamo esaminarle
tutte: apriamo la prima, poi la seconda ... e quando troviamo la scatola giusta smettiamo perchè non
abbiamo bisogno di esaminare le rimanenti. Ecco un esempio.
Questo programma cerca un divisore di un numero intero immesso dall'utente. Per prima cosa chiede
all'utente di inserire il numero n
, poi entra in un ciclo while
che usa un
contatore k
. Partentdo da 2, il programma controlla (con l'operatore %
) il resto
di tutte le divisioni n : k. Se una di queste da resto 0 n
è divisibile per k
ed il
programma esce dal ciclo con il break
. Se invece non trova divisori esce (con la condizione
del while
) quando k
è maggiore di n // 2
(se k
è maggiore
della metà di n
la divisione darà sicuramente 1 con il resto).
n = int (input("Scrivi un numero ")) # controlliamo se questo numero è primo
k = 2 # contatore: parte da 2 ...
while k <= n // 2: # ... e arriva a n//2
if n % k == 0: # se questo e' vero, n e' divisibile per k
print(n, "e' divisibile per", k)
break # trovato un divisore, usciamo dal ciclo
k += 1 # altrimenti incrementiamo il contatore
A volte, alla fine del ciclo, è necessario che il programma "sappia" se si è usciti a causa di
un break
oppure perchè la condizione di controllo è risultata falsa. Per questo
motivo è possibile inserire subito dopo il while
(allo stesso livello di
indentazione) un'istruzione else
: questa viene eseguita se la condizione è falsa (e quindi
si è usciti dal ciclo non a causa del break
) mentre viene saltata se si è usciti con il
break
.
"xxx e' un numero primo"
. (Basta aggiungere alla fine un'istruzione else
,
indentata allo stesso livello del while
, che verrà eseguita solo se il ciclo non è
uscito a causa del break
)Attenzione! E' sempre possibile inserire un else
alla fine del while
,
ma questo non ha nessuna utilità se non c'è un break
all'interno, in quanto l'
else
verrebbe eseguito comunque alla fine del ciclo (perchè la condizione è diventata
falsa). Verrebbe addirittura eseguito anche se non si entrasse per niente nel ciclo.
a = 0
while a < 10:
print ("a =", a)
a = a + 1
else: #l'else viene SEMPRE eseguito
print ("Ho eseguito l'else")
Modificare il programma precedente ponendo nella prima riga a = 1000
. Cosa
succede?
Una soluzione drastica che si adotta qualche volta quando le condizioni di uscita sono molto complicate è questa (aggiungete queste righe in coda al programma):
a = 0
while True: #questa e' sempre vera! qui non si esce mai!
#a volte si usa anche while 1:
print("Sto facendo calcoli mooooolto complicati")
if a == 10:
break #in realta' si esce dal ciclo qui
a += 1
Questa istruzione provoca immediatamente la prossima iterazione: si salta tutta la parte dal
continue
alla fine del ciclo. E' un'istruzione in effetti non indispensabile (si
potrebbe ottenere lo stesso effetto con un if
o un else
), ma che permette
spesso di rendere più leggibile il programma. Usarla o no è questione di gusti del programmatore:
tipicamente si usa se vogliamo saltare qualche iterazione nel ciclo.
Questo programma scrive i quadrati e i cubi dei numeri da 1 a 100, meno un numero scelto da noi:
salta = int(input("Che numero devo saltare? "))
i = 0
while i < 100:
i += 1
if i == salta:
continue
print("i =", i)
print("Il quadrato di i e'", i ** 2)
print("Il cubo di i e'", i ** 3)
print ("Fine")
In questo caso è evidente che potremmo ottenere lo stesso comportamento con un else
,
ma supponiamo che il ciclo while
sia composto di un gran numero di linee: dovremmo indentarle
tutte due volte. Così il programma è più semplice da scrivere.
Domanda: perchè ho incrementato il contatore all'inizio? Cosa succederebbe se lo incrementassi alla fine del ciclo come ho sempre fatto finora?
Un grande problema nei programmi che richiedono interattività è il controllo dell'input dell'utente. Consideriamo ad esempio questo frammento di codice:
risp = input("Vuoi la pizza o la pasta?")
if risp == "pizza":
print ("Hai ordinato la pizza")
else:
print ("Hai ordinato la pasta")
Qui il controllo è molto debole perchè il programma assume che voi scriviate "pizza" o "pasta". Cosa
succederebbe se all'input
voi rispondeste "qwertyuiop"
? (provate a pensarci)...
Vediamo ora un programma un po' più sofisticato che ci chiede di rispondere "s" o "n" e continua a ripetere la domanda se scriviamo qualcosa di diverso: cercate di capire come ho usato le varie tecniche descritte in questa lezione:
# non c'e' bisogno di inizializzazione in quanto l'espressione di controllo non contiene variabili
while True:
risp = input("Vuoi una tazzina di caffe'? (s/n) ")
if risp == "s" or risp == "n":
break
print("Input non valido")
print ("Ciao!")
Il ciclo viene sempre eseguito (while True:
). Si esce solo con il break
quando
la risposta è "s"
o "n"
, altrimenti viene stampato "Input non valido"
ed il ciclo ricomincia.
Scrivi un numero da 3 a 15
.
Usare una costruzione simile a questa per controllare che l'input dell'utente sia effettivamente un numero
nell'intervallo indicato.Attenzione! Questo programma dovrà comunque assumere che il nostro input sia un numero. Se
immettessimo una stringa come xyzw
andrà in crash con un ValueError.
Per controllare queste situazioni servono istruzioni che ancora non conosciamo.
Fine della lezione