Una variabile booleana p è un simbolo che prende un valore booleano: p è uguale a vero, oppure è uguale a falso, non può mai assumere i due valori allo stesso tempo, e deve sempre essere uguale a uno (e uno solo) dei due. L'aggettivo booleano si deve a George Boole, il pioniere della logica matematica.
In python i due valori booleani sono dei dati primitivi, rappresentati dai simboli True
e False
. In pratica, True
e False
sono altre due parole chiave (keyword) che sono riservate all'interprete del linguaggio, e non possono essere usate per definire variabili o funzioni.
In [1]:
True
Out[1]:
In [2]:
True = 13
In qualsiasi linguaggio di programmazione, oltre ad espressioni aritmetiche, è possibile valutare delle espressioni logiche, utilizzando gli operatori logici and
, or
, e not
:
In [3]:
True and False
Out[3]:
In [4]:
True or False
Out[4]:
In [5]:
False and False or True
Out[5]:
In [6]:
True or False and False
Out[6]:
DOMANDA: guardando gli ultimi due esempi, si riesce a capire se l'operatore and
ha la precedenza sull'operatore or
? La descrizione completa delle precedenze sugli operatori si trova nella documentazione ufficiale
Anche per gli operatori logici è possibile usare una notazione prefix, importando la libreria operator
:
In [7]:
# Importa dalla libreria solo i tre operatori logici
from operator import and_, or_, not_
In [8]:
not_(or_(True, and_(False, True)))
Out[8]:
In alternativa, per dichiarare una precedenza tra gli operatori si possono usare le parentesi tonde:
In [9]:
not (True or (False and True))
Out[9]:
Oltre agli operatori logici è possibile utilizzare gli operatori di confronto seguenti:
Simbolo matematico | Keyword Python | Notazione prefix |
---|---|---|
$a < b$ | a < b |
lt(a, b) |
$a \leq b$ | a <= b |
le(a, b) |
$a > b$ | a > b |
gt(a, b) |
$a \geq b$ | a >= b |
ge(a, b) |
$a = b$ | a == b |
eq(a, b) |
IMPORTANTE: non si confonda l'operatore di assegnamento =
con l'operatore di confronto ==
, in quanto hanno due significati completamente diversi.
In [10]:
True == True
Out[10]:
In [11]:
6*3 < 7*2
Out[11]:
In [12]:
14*2 == 4*7
Out[12]:
In [13]:
from operator import lt, le, gt, ge, eq
In [14]:
eq(14*2, 4*7)
Out[14]:
Qualsiasi linguaggio di programmazione deve avere un modo per poter verificare delle condizioni particolari e applicare delle procedure specifiche in base all'esito di tali condizioni. Ovvero, si devono poter definire delle espressioni condizionali. In python la sintassi per le espressioni condizionali è la seguente:
if <predicato1>:
<body1>
elif <predicato2>:
<body2>
else:
<body3>
Per predicato si intende una espressione logica o una procedura (meglio, una funzione) che restituisce un valore boolean, ovvero True
o False
.
Per definire delle espressioni logiche, si possono utilizzare gli operatori di confronto e gli operatori logici (o nuovi predicati definiti nel programma che si sta scrivendo).
ESEMPIO:
In [15]:
if not 3 > 4:
a = 3*2
else:
a = 4*2
In [16]:
a
Out[16]:
In [17]:
print(a)
In [18]:
def Test(x):
return x > 5 and x < 10
In [19]:
Test(2)
Out[19]:
In [20]:
Test(6)
Out[20]:
In [21]:
def ThreeAnd(x,y,z):
return x and y and z
In [22]:
ThreeAnd(2>4, 1<2, 1==3)
Out[22]:
In [23]:
def Abs(x):
if x >= 0:
return x
else:
return -x
In [24]:
Abs(-3)
Out[24]:
In [25]:
Abs(5)
Out[25]:
ESERCIZIO 1.1: Viene data sotto una serie di espressioni. Qual è il risultato dell'interprete in risposta a ciascuna espressione? Si assuma che la sequenza viene valutata nell'ordine in cui vi viene presentata.
from operator import add, sub, mul
10
5 + 3 + 4
sub(9, 1)
add(mul(2, 4), sub(4, 6))
a = 3
b = add(a, 1)
a = b
b = add(a, add(b, mul(a, b)))
if gt(a, b) = lt(b, mul(a, b)):
print(b)
else:
print(a)
In [ ]:
ESERCIZIO 1.2: Si traduca l'espressione seguente in notazione prefix:
$\frac{5+4+(2 - (3 - ( 6 + \frac{4}{5})))}{3(6-2)(2-7)}$
In [ ]:
ESERCIZIO 1.3: Si scriva una procedura che prenda tre numeri come argomenti e restituisca la somma dei quadrati dei due numeri più grandi.
In [ ]:
ESERCIZIO 1.4: Si osservi che il modello di valutazione dell'interprete visto sino ad ora permette la valutazione di procedure in cui si hanno procedure composte. Si osservi l'esempio seguente e si commenti il comportamento dell'interprete in questo caso:
In [ ]:
def F(a, b):
if b > 0:
return add
else:
return sub
def G(a, b):
return F(a,b)(a,b)
In [ ]:
G(-2,-3)
ESERCIZIO 1.5: Il sig. Bit ha inventato un test per determinare se l'interprete del linguaggio che sta usando segue un applicative-order evaluation oppure un normal-order evaluation. L'idea è di definire due procedure:
In [ ]:
def P():
return P()
In [ ]:
def Test(x, y):
if x == 0:
return 0
else:
return y
e poi de valutare l'espressione:
Test(0,P())
Quale comportamento osserverà il signor Bit con un interprete che usa una applicative-order evaluation? Quale comportamento osserverà con un interprete che usa una normal-order evaluation? Spiegare la risposta data.
In [ ]:
Test(0,P())
In [ ]: