Basi 2 - booleani
Scarica zip esercizi
REQUISITI:
I booleani sono usati nell’algebra booleana e hanno il tipo bool
.
I valori di verità sono rappresentati in Python con le parole chiave True
e False
: un oggetto booleano può solo avere i valori True
o False
.
[2]:
x = True
[3]:
x
[3]:
True
[4]:
type(x)
[4]:
bool
[5]:
y = False
[6]:
type(y)
[6]:
bool
Operatori tra booleani
Possiamo operare sui valori booleani con gli operatori booleani not
, and
, or
:
and
a |
b |
a and b |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
or
a |
b |
a or b |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
not
a |
not a |
---|---|
|
|
|
|
Booleani - Domande con costanti
DOMANDA: Per ciascuna delle seguenti espressioni booleane, prova a indovinare il risultato (prima indovina, e poi provale !):
not (True and False)
(not True) or (not (True or False))
not (not True)
not (True and (False or True))
not (not (not False))
True and (not (not((not False) and True)))
False or (False or ((True and True) and (True and False)))
Domande con variabili
DOMANDA: Per ciascuna di queste espressioni, per quali valori di x
e y
danno True
? Prova a pensare una risposta prima di provare !!!
NOTA: ci possono essere più combinazioni che producono True
, trovale tutte.
x or (not x)
(not x) and (not y)
x and (y or y)
x and (not y)
(not x) or y
y or not (y and x)
x and ((not x) or not(y))
(not (not x)) and not (x and y)
x and (x or (not(x) or not(not(x or not (x)))))
DOMANDA: Per ciascuna di queste espressioni, per quali valori di x
e y
danno False
?
NOTA: ci possono essere più combiinazioni che producono False
, trovale tutte
x or ((not y) or z)
x or (not y) or (not z)
not (x and y and (not z))
not (x and (not y) and (x or z))
y or ((x or y) and (not z))
De Morgan
Ci sono un paio di leggi che a volte tornano utili:
Formula |
Equivalente a |
---|---|
|
|
|
|
DOMANDA: Guarda la seguenti espressioni, e prova a riscriverla in una equivalente usando le leggi di De Morgan, eventualmente semplificando il risultato ove possibile. Verifica poi se la traduzione produce un risultato uguale all’originale per tutti i possibili valori di x
e y
(not x) or y
(not x) and (not y)
(not x) and (not (x or y))
Esempio:
x,y = False, False
#x,y = False, True
#x,y = True, False
#x,y = True, True
orig = x or y
trasf = not((not x) and (not y))
print('orig=',orig)
print('trasf=',trasf)
[7]:
# verifica qui
Conversione
Possiamo convertire booleani in interi con la funzione predefinita int
. Ogni intero può essere convertito in un booleano (e vice versa) con bool
:
[8]:
bool(1)
[8]:
True
[9]:
bool(0)
[9]:
False
[10]:
bool(72)
[10]:
True
[11]:
bool(-5)
[11]:
True
[12]:
int(True)
[12]:
1
[13]:
int(False)
[13]:
0
Ogni intero è valutato a True
, eccetto 0
. Nota che i valori di verità True
e False
si comportano rispettivamente come gli interi 1
e 0
Domande - cos’è un booleano?
DOMANDA: Per ciascuna di queste espressioni, che risultato produce?
bool(True)
bool(False)
bool(2 + 4)
bool(4-3-1)
int(4-3-1)
True + True
True + False
True - True
True * True
Ordine di valutazione
Per questioni di efficienza, se durante la valutazione di un’espressione booleana Python scopre che il risultato possibile può essere solo uno, allora evita di calcolare le espressioni seguenti. Per esempio, in questa espressione:
False and x
leggendo da sinistra a destra, nel momento in cui incontriamo False
sappiamo già che il risultato della and
sarà sempre False
indipendentemente dal valore della x
(convinciti!).
Se invece leggendo da sinistra a destra Python trova prima True
, continua la valutazione delle espressioni seguenti e come risultato dell’intera and
restituisce la valutazione dell’ *ultima* espressione. Se usiamo sempre booleani, non ci accorgeremo delle differenze, ma cambiando tipi potremmo ottenere delle sorprese:
[14]:
True and 5
[14]:
5
[15]:
5 and True
[15]:
True
[16]:
False and 5
[16]:
False
[17]:
5 and False
[17]:
False
Pensiamo a quale può essere l’ordine di valutazione nella or
. Guarda l’espressione:
True or x
leggendo da sinistra a destra, appena troviamo il True
possiamo stabilire che il risultato di tutta la or
dovrà essere True
indipendentemente dal valore di x
(convinciti!).
Se invece il primo valore è False
, Python continuerà la valutazione finchè trova un valore logico True
, quando questo accade quel valore sarà il risultato dell’intera espressione. Ce ne possiamo accorgere se usiamo costanti diverse da True
e da False
:
[18]:
False or 5
[18]:
5
[19]:
7 or False
[19]:
7
[20]:
3 or True
[20]:
3
I numeri che vedi hanno sempre un risultato logico coerente con le operazioni fatte, cioè se vedi 0
si intende che il risultato dell’espressione abbia valore logico False
e se vedi un numero diverso da 0
il risultato si intende True
(convinciti)
DOMANDA: Guarda le espressioni seguenti, e per ciascuna cerca di indovinare quale risultato produce (o se da errore):
0 and True
1 and 0
True and -1
0 and False
0 or False
0 or 1
False or -6
0 or True
Errori nella valutazione
Cosa succede se un’espressione booleana contiene del codice che genererebbe un errore? Intuitivamente, il programma dovrebbe terminare, ma non è sempre così.
Proviamo a generare di proposito un errore. Come ti avranno sicuramente detto più e più volte alle lezioni di matematica, provare a dividere un numero per zero è un errore perchè il risultato è indeterminato. Quindi se proviamo a chiedere a Python il risultato di 1/0
otterremo (prevedibilmente) lamentele:
print(1/0)
print('dopo')
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
<ipython-input-51-9e1622b385b6> in <module>()
----> 1 1/0
ZeroDivisionError: division by zero
Nota che 'dopo'
non viene stampato perchè il programma si interrompe prima.
E se proviamo a scrivere così, cosa otteniamo?
[21]:
False and 1/0
[21]:
False
Python produce un risultato senza lamentarsi ! Perchè? Valutando da sinistra a destra ha incontrato un False
e ha quindi concluso in anticipo che il risultato dell’espressione debba essere False
. Molte volte non ti accorgerai di questi potenziali problemi ma è bene conoscerli perchè vi sono situazioni in cui puoi persino sfruttare l’ordine di esecuzione per prevenire errori (per esempio negli if
e while
che vedremo in seguito).
DOMANDA: Guarda le espressioni seguenti, e per ciascuna cerca di indovinare quale risultato produce (o se da errore):
True and 1/0
1/0 and 1/0
False or 1/0
True or 1/0
1/0 or True
1/0 or 1/0
True or (1/0 and True)
(not False) or not 1/0
True and 1/0 and True
(not True) or 1/0 or True
True and (not True) and 1/0
Operatori di comparazione
Gli operatori di comparazione permettono di costruire espressioni che ritornano un valore booleano:
Comparatore |
Descrizione |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
[22]:
3 == 3
[22]:
True
[23]:
3 == 5
[23]:
False
[24]:
a,b = 3,5
[25]:
a == a
[25]:
True
[26]:
a == b
[26]:
False
[27]:
a == b - 2
[27]:
True
[28]:
3 != 5 # 3 è diverso da 5 ?
[28]:
True
[29]:
3 != 3 # 3 è diverso da 3 ?
[29]:
False
[30]:
3 < 5
[30]:
True
[31]:
5 < 5
[31]:
False
[32]:
5 <= 5
[32]:
True
[33]:
8 > 5
[33]:
True
[34]:
8 > 8
[34]:
False
[35]:
8 >= 8
[35]:
True
Dato che le comparazioni sono espressioni che producono booleani, possiamo anche assegnare il risultato ad una variabile:
[36]:
x = 5 > 3
[37]:
print(x)
True
Congiungere comparazioni
Data un paio di quantità:
[38]:
x, y = 7, 5
Come potremmo scrivere una espressione booleana per chiederci se x
e y
sono entrambe maggiori di zero?
Il modo corretto, per quanto un po’ verboso è il seguente:
[39]:
x > 0 and y > 0
[39]:
True
ATTENZIONE: la seguente scrittura invece NON è corretta:
x and y > 0 # SBAGLIATO!
Perchè? In apparenza su alcuni input parrebbe funzionare:
[40]:
x,y = 7, 5
x and y > 0 # ATTENZIONE!
[40]:
True
[41]:
x,y = 7, -6
x and y > 0 # ATTENZIONE!
[41]:
False
Ma funziona proprio su tutti?
[42]:
x,y = -3, 5
x and y > 0 # ATTENZIONE!
[42]:
True
Mmm abbiamo trovato qualcosa che non va… Qual’è il motivo? Python implicitamente ha considerato l’espressione come se fosse con queste parentesi:
[43]:
x,y = -3,5
(x) and (y>0) # ATTENZIONE!
[43]:
True
In questo modo risulta evidente che a sinistra Python sta considerando x
come se fosse una singola espressione booleana: in quanto tale, prova a rilevare il valore logico del valore intero -3
: essendo questo numero diverso da zero, viene considerato True
, da qui lo strano risultato.
DOMANDA: E se provassimo a mettere noi queste parentesi cosa succederebbe?
x,y = -3,5
(x and y) > 0 # ATTENZIONE!
Prova a pensare bene a tutti i passi che Python farà per calcolare questa espressione:
Mostra rispostaDOMANDA: Guarda le espressioni seguenti, e per ciascuna cerca di indovinare quale risultato produce (o se produce un errore).
x = 3 == 4 print(x)
x = False or True print(x)
True or False = x or False print(x)
x,y = 9,10 z = x < y and x == 3**2 print(z)
a,b = 7,6 a = b x = a >= b + 1 print(x)
x = 3^2 y = 9 print(x == y)
Esercizio - Il Tagliaerbe 1
Il dottor Angelo possiede un prato di area quadrata di lato d=100
metri che viene accudito ogni settimana da Jobe il giardiniere. Jobe passa sempre meticolosomente il tagliarbe su tutta l’area del prato, ma un giorno il dottore decide di rendere più elaborato il giardino e chiede a Jobe di tagliare solo alcune zone. Purtroppo, Jobe non è molto forte in geometria e per agevolarlo il dottore inventa un sensore in grado di rilevare la posizione, collegato ad una spia che si illumina solo quando
il tagliaerbe va azionato. Scrivi un’espressione che date due coordinate x,y
, produca True
quando il tagliaerbe è nella zona verde chiaro, e False
altrimenti.
Nota che l’origine delle coordinate è in basso a sinistra
NON usare istruzioni
if
SCRIVI una formula generica usando
d
(quindi non scrivere50
…)
[44]:
d = 100
x,y = 0, 0 # False
#x,y = 25, 25 # False
#x,y = 75, 75 # False
#x,y = 75, 25 # False
#x,y = 25, 75 # True
#x,y = 100, 100 # False
#x,y = 10, 90 # True
#x,y = 60, 60 # False
# scrivi qui
[44]:
False
Esercizio - Il Tagliaerbe 2
Il dottor Angelo adesso richiede a Jobe di tagliare più zone…
NON usare istruzioni
if
[45]:
d = 100
x,y = 0, 0 # True
#x,y = 25, 25 # True
#x,y = 75, 75 # True
#x,y = 75, 25 # False
#x,y = 25, 75 # False
#x,y = 100, 100 # True
#x,y = 10, 90 # False
#x,y = 60, 60 # True
# scrivi qui
[45]:
True
Esercizio - Il Tagliaerbe 3
Il dottor Angelo si è stufato di giardini squadrati, e vuole dividere il prato in diagonale.
NON usare istruzioni
if
[46]:
d = 100
x,y = 50, 10 # True
#x,y = 100,0 # True
#x,y = 75, 70 # True
#x,y = 25,75 # False
#x,y = 25, 5 # True
#x,y = 5, 80 # False
#x,y = 60, 70 # False
# scrivi qui
[46]:
True
Esercizio - Il Tagliaerbe 4
Altro giorno, altra diagonale per Jobe..
NON usare istruzioni
if
SUGGERIMENTO: se non ricordi l’equazione della retta è il momento di cercarla :-)
[47]:
d = 100
x,y = 50, 10 # True
#x,y = 0,0 # True
#x,y = 75, 70 # False
#x,y = 25,90 # False
#x,y = 25, 5 # True
#x,y = 80, 20 # False
#x,y = 25, 25 # True
# scrivi qui
[47]:
True
Esercizio - Il Tempio di Lava
Durante i tuoi studi scopri una mappa di un antico tempio, ove sono custoditi mirabolanti tesori.
Il tempio misura d=80
metri di lato ed è un labirinto di corridoi. Sai per certo che alcune aree mostrate in rosso contengono pavimento fragile sotto il quale scorrono fiumi di lava incandescente: per avvertirti del pericolo mentre cammini, ti costruisci un detector che emetterà un suono quando sarai in zone rosse.
Scrivi un’espressione booleana che restituisce True
se sei in una zona di pericolo, False
altrimenti.
NON usare istruzioni
if
[48]:
d = 80
x,y = 0, 0 # False
#x,y = 20, 20 # False
#x,y = 60, 10 # True
#x,y = 10, 60 # True
#x,y = 20, 70 # False
#x,y = 70, 20 # False
#x,y = 70, 70 # False
#x,y = 0,60 # True
#x,y = 60,0 # True
# scrivi qui
[48]:
False
Esercizio - La Torre di Gradius I
La lancetta dell’orologio sulla prima Torre di Gradius ha compiuto finora una rotazione di n
gradi. Scrivi del codice che mostra True
se la lancetta si trova nelle zone evidenziate, False
altrimenti.
NON usare istruzioni
if
n
può essere maggiore di360
Ci sono due modi di risolvere il problema:
semplice: potresti scrivere una espressione lunga con diversi
and
eor
più difficile: riesci a scrivere una sola espressione breve senza
and
nèor
?
[49]:
n = 20 # False
#n = 405 # False
#n = 70 # False
#n = 100 # True
#n = 460 # True
#n = 225 # True
#n = 182 # False
#n = 253 # False
#n = 275 # False
#n = 205 # False
#n = 350 # True
#n = 925 # False
#n = 815 # True
#n = 92 # True
# scrivi qui
[49]:
False
Esercizio - Il Salto del Tubo
Un idraulico italiano vede 3 tubi di altezza rispettivamente t1
, t2
e t3
, sopra cui vi sono rispettivamente sono 10
, 20
e 30
monete. Esaltato, spicca un balzo di altezza h
. Scrivi del codice che stampa quante monete raccoglie (10
,20
o 30
).
NON usare istruzioni
if
SUGGERIMENTO: Se non sai come fare, riguardati il paragrafo Ordine di valutazione e prova a pensare come produrre dei numeri solo quando una certa condizione è vera …
[50]:
t1,t2,t3 = 200,500,600
h=450 # 10
#h=570 # 20
#h=610 # 30
#h=50 # 0
# scrivi qui
[50]:
10
Esercizio - La Torre di Gradius II
Le lancette dell’orologio sulla seconda Torre di Gradius hanno compiuto finora una rotazione rispettivamente di n
e m
gradi. Scrivi del codice che mostra True
se entrambe le lancette si trovano nella stessa zona tra quelle evidenziate, False
altrimenti.
NON usare istruzioni
if
n
em
possono essere maggiori di360
[51]:
n,m = 160,170 # True
#n,m = 135, 140 # False
#n,m = 160,190 # False
#n,m = 70,170 # False
#n,m = 350,260 # False
#n,m = 350,340 # True
#n,m = 350,340 # True
#n,m = 430,530 # False
#n,m = 520,510 # True
#n,m = 730,740 # False
# scrivi qui
[51]:
True
Prosegui
Continua con Basi 3 - numeri reali