L'indentazione e' un elemento fondamentale del linguaggio e definisce la struttura del codice:
a=10
#la seguente istruzione non e' permessa, tutte le istruzioni/espressioni dello stesso livello
#devono essere indentate allo stesso modo
b=20
Ma quali sono le circostanze in cui si hanno cambi di livello nel codice?
Elenchiamo i pi ù importanti:
Avevamo gia' visto la sintassi del costrutto if (lezione sui numeri)
Vediamo una proposizione composta da if annidati:
import random
#lista delle ore
ore=list(range(24))
#scelta casuale dalla lista delle ore
ora = random.choice(ore)
#formattazione di una stringa
str = 'sono le {0} e cio è è '.format(ora)
#
if ora >= 0 and ora <= 5 or ora > 20 and ora <=24:
str += "notte"
if ora <=3:
str += " fonda"
elif ora <= 12:
str += "mattina"
if ora <=8:
str += " presto"
elif ora <= 18 :
str += "pomeriggio"
if ora >=17:
str += " inoltrato"
elif ora <= 20 :
str += "sera"
else:
str = 'ERRORE!!'
print(str)
Una caratteristica interessante di Python, che pu ò essere utilizzata in particolare nei costrutti if e while, e' che qualsiasi oggetto puo' essere testato come se fosse un Bool.
I seguenti valori sono considerati falsi:
Vedi anche truth value testing.
Sperimentiamo quanto detto sopra:
#definisco una funzione
def truthtest(a):
if a:
print('{0} è vero'.format(a))
else:
print('{0} è falso'.format(a))
truthtest([])
truthtest(0)
truthtest([2])
truthtest(0+0j)
truthtest(print)#una funzione
truthtest(math)#un modulo
Anche dell'istruzione for abbiamo gia' parlato durante la lezione sulle liste, aggiungiamo qui il costrutto completo, che comprende anche una clausola else che viene eseguita solo se si terminano le iterazioni senza avere incontrato alcuna istruzione break, che vedremo meglio dopo.
esempio:
d = {'Nicola':23255656 , 'Alfredo':32447778 , 'fernando' : 34546677, 'Gino':233657898}
#funzione per ordinamento case-insensitive
def mylower(s):
return s.lower()
for k in sorted(d.keys(),key=mylower):
print(k,'-->',d[k])
else:
print('---- Ho finito ----')
Nel costrutto while si condiziona l'esecuzione di un blocco di istruzioni al valore di un'espressione:
Anche il costrutto while comprende anche una clausola else che viene eseguita solo se si terminano le iterazioni senza avere incontrato alcuna istruzione break.
vediamo un esempio:
#partita a dadi virtuale
import random
#punteggio complessivo dei giocatori
p1 = 0
p2 = 0
win = 5
#si inizia a giocare...si vince a 5
while p1 < win and p2 < win:
#i giocatori tirano i dadi
s1=random.randint(1,6)
s2=random.randint(1,6)
print(s1,s2)
#valuto gli score ed eventualmente assegno un punto
if s1>s2:
p1 += 1
print('un punto a 1')
elif s1<s2:
p2 += 1
print('un punto a 2')
else:
print('patta')
#la partita e' finita, decreto il vincitore
else:
print('-'*20)
if p1>p2:
print('Vince 1 !!!!')
else:
print('Vince 2 !!!!')
l'interprete esce immediatamente dal ciclo while o for esterno 'pi ù vicino', saltando la eventuale clausola else.
Vediamo un esempio con due cicli for annidati:
for i in range(5):
print('i=',i)
for j in range(100,104):
print(' ',j)
if i==2 and j >= 101:
#esco dal ciclo for su j
#solo quando si presentano
#specifiche condizioni
print(' break!!!')
break
else:
print(' else')
print('fine')
break e' spesso usato per uscire da cicli while con espressione sempre vera.
Vediamo un esempio nel quale, all'interno di un ciclo while 'indefinito' genero un numero casuale ed esco con break solo se si manifesta un valore predefinito
import random
while True:
a=random.randint(0,20)
print(' è uscito {0}'.format(a))
if a == 5:
print('finalmente, break!!!')
break
se incontra una istruzione continuel'interprete va immediatamente all'inizio del ciclo while o for 'pi ù vicino' e riprende l'iterazione
In altre parole salta tutta la restante parte dell'elenco di espressioni da eseguire ad ogni iterazione e riparte con l'iterazione successiva.
#salto i miltipli del 3
for i in range(1,20):
if i%3==0:
continue
print('{0:02d} non è multiplo di 3'.format(i))
Vediamo cosa succede nel caso di cicli annidati:
for j in range(3):
print('----{0}----'.format(j))
for i in range(5):
##
if i == 2:
print('continue')
continue
#
print('{0:02d}'.format(i))
Gli esempi sopra sarebbero facilente implementabili anche senza continue.
In ogni caso si fa notare che l'aggiunta dei costrutti if ... continue è formalmente pi ù corretta nel caso di condizioni speciali permette di non mettere mano al codice che definisce la logica successiva (neanche con un cambio di indentazione)