Basi 2 - booleani

Scarica zip esercizi

Naviga file online

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

False

False

False

False

True

False

True

False

False

True

True

True

or

a

b

a or b

False

False

False

False

True

True

True

False

True

True

True

True

not

a

not a

False

True

True

False

Booleani - Domande con costanti

DOMANDA: Per ciascuna delle seguenti espressioni booleane, prova a indovinare il risultato (prima indovina, e poi provale !):

  1. not (True and False)
    
  2. (not True) or (not (True or False))
    
  3. not (not True)
    
  4. not (True and (False or True))
    
  5. not (not (not False))
    
  6. True and (not (not((not False) and True)))
    
  7. 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.

  1. x or (not x)
    
  2. (not x) and (not y)
    
  3. x and (y or y)
    
  4. x and (not y)
    
  5. (not x) or  y
    
  6. y or not (y and x)
    
  7. x and ((not x) or not(y))
    
  8. (not (not x)) and not (x and y)
    
  9. 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

  1. x or ((not y) or z)
    
  2. x or (not y) or (not z)
    
  3. not (x and y and (not z))
    
  4. not (x and (not y) and (x or z))
    
  5. y or ((x or y) and (not z))
    

De Morgan

Ci sono un paio di leggi che a volte tornano utili:

Formula

Equivalente a

x or y

not(not x and not y)

x and y

not(not x or not y)

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

  1. (not x) or y
    
  2. (not x) and (not y)
    
  3. (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?

  1. bool(True)
    
  2. bool(False)
    
  3. bool(2 + 4)
    
  4. bool(4-3-1)
    
  5. int(4-3-1)
    
  6. True + True
    
  7. True + False
    
  8. True - True
    
  9. 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):

  1. 0 and True
    
  2. 1 and 0
    
  3. True and -1
    
  4. 0 and False
    
  5. 0 or False
    
  6. 0 or 1
    
  7. False or -6
    
  8. 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):

  1. True and 1/0
    
  2. 1/0 and 1/0
    
  3. False or 1/0
    
  4. True or 1/0
    
  5. 1/0 or True
    
  6. 1/0 or 1/0
    
  7. True or (1/0 and True)
    
  8. (not False) or not 1/0
    
  9. True and 1/0 and True
    
  10. (not True) or 1/0 or True
    
  11. 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

a == b

True se e solo se a = b

a != b

True se e solo se a \(\neq\) b

a < b

True se e solo se a < b

a > b

True se e solo se a > b

a <= b

True se e solo se a \(\leq\) b

a >= b

True se e solo se a \(\geq\) b

[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 risposta

DOMANDA: Guarda le espressioni seguenti, e per ciascuna cerca di indovinare quale risultato produce (o se produce un errore).

  1. x = 3 == 4
    print(x)
    
  2. x = False or True
    print(x)
    
  3. True or False = x or False
    print(x)
    
  4. x,y = 9,10
    z = x < y and x == 3**2
    print(z)
    
  5. a,b = 7,6
    a = b
    x = a >= b + 1
    print(x)
    
  6. 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 scrivere 50…)

img/lawnmower-1

Mostra soluzione
[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

img/lawnmower-2

Mostra soluzione
[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

img/lawnmower-3

Mostra soluzione
[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 :-)

img/lawnmower-4

Mostra soluzione
[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

bool-temple-1.png

Mostra soluzione
[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 di 360

Ci sono due modi di risolvere il problema:

  1. semplice: potresti scrivere una espressione lunga con diversi and e or

  2. più difficile: riesci a scrivere una sola espressione breve senza andor ?

gradius-tower-1

Mostra soluzione
[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 …

img/bool-jump-1.png

Mostra soluzione
[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 e m possono essere maggiori di 360

gradius-tower-2

Mostra soluzione
[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