Vai al contenuto

Capitolo 3 · Strutture decisionali e logica booleana

Cosa impari

  • a far scegliere al programma che cosa fare con if, if-else e if-elif-else;
  • a scrivere condizioni con gli operatori relazionali (>, <, >=, <=, ==, !=);
  • a combinare più condizioni con and, or e not;
  • a usare le variabili booleane (True / False) come indicatori.

Finora i programmi eseguivano le istruzioni una dopo l'altra, dall'alto verso il basso: è la struttura sequenziale. Molti problemi però richiedono una scelta. Ad esempio, nel calcolo di una paga gli straordinari vanno calcolati solo se il dipendente ha lavorato più di 40 ore. Serve una struttura decisionale.

L'istruzione if

if condizione:
    istruzione
    istruzione

Se la condizione è vera, Python esegue il blocco di istruzioni rientrate sotto l'if; se è falsa, le salta. Due regole da non dimenticare: la riga dell'if finisce con i due punti e il blocco è rientrato (4 spazi). È il rientro a dire a Python dove comincia e dove finisce il blocco.

Nel diagramma di flusso la condizione è un rombo con due uscite: vero e falso.

# Media di tre voti: se è alta, il programma si congratula
high_score = 95
test1 = int(input("Immettere il voto dell'esame 1: "))
test2 = int(input("Immettere il voto dell'esame 2: "))
test3 = int(input("Immettere il voto dell'esame 3: "))
average = (test1 + test2 + test3) / 3
print('La media dei voti è', average)
if average >= high_score:
    print('Congratulazioni!')
    print("Veramente un'ottima media!")

Prova con 82, 76, 91 (media 83.0: nessun messaggio) e poi con 93, 99, 96 (media 96.0: congratulazioni).

Operatori relazionali

Una condizione è un'espressione booleana: vale True (vero) oppure False (falso).

Operatore Significato
> maggiore di
< minore di
>= maggiore o uguale a
<= minore o uguale a
== uguale a
!= diverso da
x = 1
y = 0
z = 1
print(x > y, y > x)
print(x >= z, x <= y)
print(x == z, x != y)

== non è =

= assegna un valore a una variabile; == confronta due valori. Scrivere if a = 4: è un errore di sintassi.

if-else: due strade

Con if-else il programma sceglie uno solo dei due blocchi: quello sotto if se la condizione è vera, quello sotto else se è falsa. if ed else devono essere allineati.

temperature = float(input('Temperatura di oggi: '))
if temperature < 0:
    print("Un po' freddino, non trovi?")
else:
    print('Ma che bella giornata.')

Confrontare stringhe

Gli stessi operatori funzionano con le stringhe. Attenzione: il confronto distingue maiuscole e minuscole, quindi 'Prospero' è diverso da 'prospero'.

password = input('Inserisci la password: ')
if password == 'prospero':
    print('Password accettata.')
else:
    print('Spiacente, la password è sbagliata.')

Decisioni annidate

Una struttura decisionale può stare dentro un'altra. Nell'esempio del prestito il cliente deve guadagnare almeno 30.000 € e lavorare da almeno 2 anni. Il secondo controllo serve solo se il primo è superato. Ogni else è allineato con il proprio if.

min_salary = 30000.0   # retribuzione annua minima
min_years = 2          # anni minimi nel posto di lavoro

salary = float(input('Immettere la retribuzione annua: '))
years_on_job = int(input('Immettere il numero di anni sul posto di lavoro: '))

if salary >= min_salary:
    if years_on_job >= min_years:
        print('Il cliente può ricevere il prestito.')
    else:
        print(f'Il cliente deve essere stato impiegato almeno {min_years} anni per ricevere il prestito.')
else:
    print(f'Il cliente deve guadagnare almeno €{min_salary:,.2f} annui per ricevere il prestito.')

if-elif-else: una serie di condizioni

Quando le condizioni sono tante, gli if annidati spingono il codice sempre più a destra. La forma if-elif-else è equivalente ma più leggibile: Python controlla le condizioni nell'ordine ed esegue solo il blocco della prima vera; se nessuna è vera, esegue else.

A_score = 90
B_score = 80
C_score = 70
D_score = 60

score = int(input('Inserire il punteggio: '))
if score >= A_score:
    print('Il voto è A.')
elif score >= B_score:
    print('Il voto è B.')
elif score >= C_score:
    print('Il voto è C.')
elif score >= D_score:
    print('Il voto è D.')
else:
    print('Il voto è F.')

Le soglie vanno dalla più alta alla più bassa: con 84 la prima condizione vera è score >= B_score.

Operatori logici and, or, not

Operatore È vero quando
a and b entrambe le condizioni sono vere
a or b almeno una delle condizioni è vera
not a la condizione è falsa

Python usa la valutazione a corto circuito: con and, se la prima condizione è falsa non controlla la seconda; con or, se la prima è vera non controlla la seconda.

MIN_SALARY = 30000.0
MIN_YEARS = 2
salary = float(input('Immettere la retribuzione annua: '))
years_on_job = int(input('Immettere il numero di anni sul posto di lavoro: '))

# Prova a cambiare "and" in "or": il requisito diventa piu' permissivo
if salary >= MIN_SALARY and years_on_job >= MIN_YEARS:
    print('Il cliente può ricevere il prestito.')
else:
    print('Il cliente non può ricevere il prestito.')

Intervalli numerici. Per controllare se un numero è dentro un intervallo si usa and; per controllare se è fuori si usa or.

x = int(input('Numero: '))
if x >= 20 and x <= 40:
    print("Il valore è all'interno dell'intervallo accettabile.")
if x < 20 or x > 40:
    print("Il valore è al di fuori dell'intervallo accettabile.")

Errore logico frequente

if x < 20 and x > 40: non è mai vero: un numero non può essere contemporaneamente minore di 20 e maggiore di 40. Python non segnala nessun errore, ma il blocco non viene mai eseguito.

Variabili booleane

Una variabile di tipo bool vale True oppure False. Si usa spesso come flag, cioè per ricordare se una condizione si è verificata. Nell'if non serve scrivere == True.

sales = float(input('Vendite del mese: '))
if sales >= 50000.0:
    sales_quota_met = True
else:
    sales_quota_met = False

if sales_quota_met:
    print('Hai raggiunto la quota di vendite!')
else:
    print('Quota non raggiunta.')

Errori tipici

Errore Cosa succede Come si corregge
if x > 2 senza : SyntaxError: expected ':' aggiungi i due punti
blocco non rientrato IndentationError sposta il blocco di 4 spazi
if scelta = 1: SyntaxError per confrontare usa ==
if voto > 18 and < 30: SyntaxError ripeti la variabile: voto > 18 and voto < 30
soglie elif in ordine sbagliato nessun errore, risultato sbagliato dalla soglia più alta alla più bassa (o viceversa con <)

Esercizi

Esercizio 1 · Pari o dispari. Chiedi un numero intero e scrivi se è pari o dispari. Suggerimento: un numero è pari se il resto della divisione per 2 è zero.

# Scrivi qui la tua soluzione
Soluzione
numero = int(input('Inserisci un numero intero: '))
if numero % 2 == 0:
    print(numero, 'è pari')
else:
    print(numero, 'è dispari')

Esercizio 2 · Voto d'esame. Chiedi un voto. Se è fuori dall'intervallo 0–30 scrivi Voto non valido; se è almeno 18 scrivi Esame superato, altrimenti Esame non superato.

# Scrivi qui la tua soluzione
Soluzione
voto = int(input('Voto: '))
if voto < 0 or voto > 30:
    print('Voto non valido')
elif voto >= 18:
    print('Esame superato')
else:
    print('Esame non superato')

Esercizio 3 · Biglietto ridotto. Un biglietto costa 8.50 €. Chi ha meno di 12 anni o almeno 65 paga la metà; gli studenti (risposta s) hanno 2 € di sconto. Gli sconti non si sommano: si applica il più conveniente. Mostra il prezzo finale con due decimali.

# Scrivi qui la tua soluzione
Soluzione
PREZZO = 8.50
eta = int(input('Età: '))
studente = input('Sei uno studente? (s/n) ') == 's'

prezzo = PREZZO
if eta < 12 or eta >= 65:
    prezzo = PREZZO / 2
if studente and PREZZO - 2 < prezzo:
    prezzo = PREZZO - 2
print(f'Prezzo del biglietto: {prezzo:.2f} euro')

Verifica