True

True = 13

"""
Explanation: Variabili Booleane ed Espressioni Logiche
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.
End of explanation
"""


True and False

True or False

False and False or True

True or False and False

"""
Explanation: In qualsiasi linguaggio di programmazione, oltre ad espressioni aritmetiche, è possibile valutare delle espressioni logiche, utilizzando gli operatori logici and, or, e not:
End of explanation
"""


# Importa dalla libreria solo i tre operatori logici
from operator import and_, or_, not_

not_(or_(True, and_(False, True)))

"""
Explanation: 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:
End of explanation
"""


not (True or (False and True))

"""
Explanation: In alternativa, per dichiarare una precedenza tra gli operatori si possono usare le parentesi tonde:
End of explanation
"""


True == True

6*3 < 7*2

14*2 == 4*7

from operator import lt, le, gt, ge, eq

eq(14*2, 4*7)

"""
Explanation: Operatori di confronto
Oltre agli operatori logici è possibile utilizzare gli operatori di confronto seguenti:
| Simbolo matematico | Keyword Python | Notazione prefix |
|:--:|:--:|:--:|
|  $a < b$  | a &lt; b   | lt(a, b) | 
|  $a \leq b$  | a &lt;= b   | le(a, b) | 
|  $a > b$  | a &gt; b   | gt(a, b) | 
|  $a \geq b$  | a &gt;= 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.
End of explanation
"""


if not 3 > 4:
    a = 3*2
else:
    a = 4*2

a

print(a)

def Test(x):
    return x > 5 and x < 10

Test(2)

Test(6)

def ThreeAnd(x,y,z):
    return x and y and z

ThreeAnd(2>4, 1<2, 1==3)

def Abs(x):
    if x >= 0:
        return x
    else:
        return -x

Abs(-3)

Abs(5)

"""
Explanation: Espressioni condizionali e predicati
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 &lt;predicato1&gt;:
    &lt;body1&gt;
elif &lt;predicato2&gt;:
    &lt;body2&gt;
else:
    &lt;body3&gt;
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:
End of explanation
"""


def F(a, b):
    if b > 0:
        return add
    else:
        return sub
    
def G(a, b):
    return F(a,b)(a,b)

G(-2,-3)

"""
Explanation: Esercizi
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)
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)}$
ESERCIZIO 1.3: Si scriva una procedura che prenda tre numeri come argomenti e restituisca la somma dei quadrati dei due numeri più grandi.
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:
End of explanation
"""


def P():
    return P()

def Test(x, y):
    if x == 0:
        return 0
    else:
        return y

"""
Explanation: 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:
End of explanation
"""


Test(0,P())

"""
Explanation: 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.
End of explanation
"""


