Subsections

10. Espressioni booleane

Questo è un piccolo esempio di espressioni booleane (non dovete scriverlo):
a = 6
b = 7
c = 42
print 1, a == 6
print 2, a == 7
print 3,a == 6 and b == 7
print 4,a == 7 and b == 7
print 5,not a == 7 and b == 7
print 6,a == 7 or b == 7
print 7,a == 7 or b == 6
print 8,not (a == 7 and b == 6)
print 9,not a == 7 and b == 6
Questo è l'output:
1 1
2 0
3 1
4 0
5 1
6 1
7 0
8 1
9 0
Cosa succede? Il programma consiste in una serie di istruzioni print. Ogni istruzione print visualizza un numero e un'espressione. Il numero serve a farvi capire quale istruzione viene eseguita. Potete notare che ogni espressione consiste in uno 0 o in un 1. In Python equivalgono a falso (0) e a vero (1).

Le linee:

print 1, a == 6
print 2, a == 7
Restituiscono infatti vero e falso, esattamente come dovrebbero fare finché la prima affermazione è vera e la seconda è falsa. La terza istruzione print è un po' diversa: print print 3,a == 6 and b == 7. L'operatore and indica che se entrambe le affermazioni prima e dopo l'operatore logico sono vere tutta l'espressione è vera, altrimenti tutta l'espressione è falsa. L'espressione successiva, print 4,a == 7 and b == 7, dimostra che se una parte dell'espressione and è falsa, tutta l'espressione sarà falsa. Il significato di and può essere riassunto come segue:

espressione risultato
vero and vero vero
vero and falso falso
falso and vero falso
falso and falso falso

Potete notare che se la prima espressione è falsa Python non esegue un controllo sulla seconda espressione perché sa già che tutta l'espressione è falsa.

La linea successiva, print 5,not a == 7 and b == 7, utilizza l'operatore not che restituisce semplicemente l'opposto dell'espressione. L'espressione può infatti essere riscritta semplicemente come print 5,a != 7 and b == 7. Questa è la tabella:

espressione risultato
not vero falso
not falso vero

Le due linee seguenti, print 6,a == 7 or b == 7 e print 7,a == 7 o b == 6, utilizzano l'operatore logico or che ritorna vero se una delle affermazioni (o entrambe) è vera. Questa è la tabella:

espressione risultato
vero or vero vero
vero or falso vero
falso or vero vero
falso or falso falso

Anche qui Python non esegue il controllo sulla seconda espressione se riconosce la prima come vera dato che anche se la seconda affermazione risultasse falsa l'intera espressione sarebbe comunque vera.

Le ultime due linee, print 8,not (a == 7 and b == 6)e print 9,not a == 7 and b == 6, mostrano come le parentesi possano raggruppare espressioni e forzarne l'esecuzione prima di altre al di fuori dalle parentesi. Potete osservare infatti che le parentesi cambiano il valore dell'espressione da falso a vero, visto che obbligano l'operatore not a valutare l'intera espressione anziché solamente la porzione a == 7.

Ecco un esempio sull'utilizzo delle espressioni booleane:

list = ["Life","The Universe","Everything","Jack","Jill","Life","Jill"]

# Crea una copia della lista. Vedi il capitolo ``Ancora sulle liste''
# per una spiegazione del costrutto [:].
copy = list[:]
# Ordina la copia.
copy.sort()
prev = copy[0]
del copy[0]

count = 0

# Esamina la lista per trovare una corrispondenza.
while count < len(copy) and copy[count] != prev:
    prev = copy[count]
    count = count + 1

# Se non viene trovata una corrispondenza allora count non può essere
# < len(copy) in quel momento, quindi usciamo dal ciclo while. 
if count < len(copy):
    print "First Match: ",prev

Ecco l'output:

First Match:  Jill

Questo programma continua a scorrere la lista cercando duplicati (while count < len(copy and copy[count]). Quando uno dei due contatori è più grande dell'ultimo indice di copy o viene trovato un duplicato, l'operatore and non risulta più vero e si esce dal ciclo. if si occupa semplicemente di accertarsi che l'uscita dal ciclo while sia dovuta alla presenza di un duplicato.

Nell'esempio viene utilizzato un'altro 'trucco' dell'operatore and. Se guardate la tabella di and potete osservare che la terza espressione è falsa senza che Python esegua un controllo sul secondo elemento. Se count >= len(copy) (in altre parole count < len(copy) è falsa) allora copy[count] non viene processata. Questo avviene perché Python sa che se la prima accezione è falsa, lo sono entrambe. Questo piccolo trucco è utile se la seconda metà dell'and causa un errore. Ho usato la prima espressione (count < len(copy)) per eseguire un controllo su count e controllare se count sia un indice valido (se non mi credete, rimuovete 'Jill' e 'Life', eseguite il programma e vedete se funziona ancora, quindi invertite l'ordine di count < len(copy) and copy[count] != prev con copy[count] != prev and count < len(copy)).

Le espressioni booleane possono essere usate quando avete bisogno di verificare due o più elementi in una volta.

10.1 Esempi

password1.py

## Questo programma chiede ad un utente un nome ed una password,
#  poi controlla per accertarsi che gli sia consentito l'accesso.

name = raw_input("What is your name? ")
password = raw_input("What is the password? ")
if name == "Josh" and password == "Friday":
    print "Welcome Josh"
elif name == "Fred" and password == "Rock":
    print "Welcome Fred"
else:
    print "I don't know you."

Semplice esecuzione:

What is your name? Josh
What is the password? Friday
Welcome Josh

What is your name? Bill
What is the password? Money
I don't know you.

10.2 Esercizi

Scrivete un programma che spinga l'utente ad indovinare il vostro nome dandogli solamente 3 possibilità, dopo le quali il programma termina.