Python if, elif, else: gestire i casi limite con chiarezza

by theArchitect
SHARE
Python if, elif, else: gestire i casi limite con chiarezza
© Guida-HTML5.it

Introduzione

Quando si inizia a usare if, elif, else in Python, il primo obiettivo è quasi sempre scegliere tra più rami di esecuzione. Tuttavia, nella pratica professionale c’è un aspetto altrettanto importante: gestire correttamente i casi limite. In altre parole, come si comporta il programma quando il dato è mancante, fuori intervallo, inatteso o ambiguo?

Questo sotto-argomento è molto utile perché permette di scrivere codice più robusto, leggibile e sicuro. Un controllo di flusso ben progettato non serve solo a “far funzionare” il programma, ma anche a evitare errori difficili da diagnosticare e a comunicare chiaramente l’intenzione del codice.

In questo tutorial vedremo come usare if, elif, else per validare input, intercettare valori anomali e definire un comportamento di fallback sensato. L’esempio sarà realistico: un sistema che calcola un punteggio di priorità per una richiesta di supporto tecnico.

Codice completo

def calcola_priorita(ticket):
    """
    Calcola la priorità di un ticket di supporto.
    Il ticket è un dizionario con chiavi:
    - ´urgenza´: da 1 a 5
    - ´cliente_premium´: booleano
    - ´blocco_servizio´: booleano
    - ´descrizione´: stringa non vuota
    """

    # Caso limite 1: struttura dati non valida
    if not isinstance(ticket, dict):
        return "Errore: ticket non valido"

    # Caso limite 2: campi mancanti
    if ´urgenza´ not in ticket or ´cliente_premium´ not in ticket or ´blocco_servizio´ not in ticket:
        return "Errore: dati incompleti"

    urgenza = ticket[´urgenza´]
    cliente_premium = ticket[´cliente_premium´]
    blocco_servizio = ticket[´blocco_servizio´]

    # Caso limite 3: tipo o range non validi
    if not isinstance(urgenza, int):
        return "Errore: urgenza deve essere un intero"

    if urgenza < 1:
        return "Errore: urgenza troppo bassa"
    elif urgenza > 5:
        return "Errore: urgenza troppo alta"

    # Caso limite 4: descrizione assente o vuota
    descrizione = ticket.get(´descrizione´, ´´)
    if not isinstance(descrizione, str) or descrizione.strip() == "":
        return "Errore: descrizione mancante"

    # Logica principale
    if blocco_servizio:
        priorita = "critica"
    elif cliente_premium and urgenza >= 4:
        priorita = "alta"
    elif urgenza == 3:
        priorita = "media"
    elif urgenza == 2:
        priorita = "bassa"
    else:
        priorita = "molto bassa"

    # Caso limite finale: ticket valido ma descrizione troppo breve
    if len(descrizione.strip()) < 10:
        return f"Ticket valido, ma descrizione troppo breve. Priorità calcolata: {priorita}"

    return f"Priorità assegnata: {priorita}"


# Esempi di utilizzo
ticket1 = {
    "urgenza": 5,
    "cliente_premium": True,
    "blocco_servizio": False,
    "descrizione": "Il servizio non risponde da 20 minuti"
}

ticket2 = {
    "urgenza": 6,
    "cliente_premium": False,
    "blocco_servizio": False,
    "descrizione": "Problema generico"
}

ticket3 = {
    "urgenza": 2,
    "cliente_premium": True,
    "blocco_servizio": True,
    "descrizione": "Down totale"
}

ticket4 = {
    "urgenza": 3,
    "cliente_premium": False,
    "blocco_servizio": False,
    "descrizione": ""
}

print(calcola_priorita(ticket1))
print(calcola_priorita(ticket2))
print(calcola_priorita(ticket3))
print(calcola_priorita(ticket4))

Spiegazione

Il codice mostra un approccio molto comune nello sviluppo reale: validare prima i dati, poi applicare la logica di business. Questa separazione è fondamentale perché evita di mescolare controlli tecnici e regole applicative nello stesso blocco in modo confuso.

1. Controllo del tipo di dato

La funzione inizia verificando che ticket sia un dizionario. Se un chiamante passa una lista, una stringa o un altro tipo, il programma restituisce subito un messaggio di errore. Questo è un tipico caso limite: non bisogna assumere che i dati siano sempre nel formato atteso.

2. Verifica dei campi obbligatori

Subito dopo, il codice controlla la presenza delle chiavi essenziali. Se manca anche solo un dato necessario, non ha senso proseguire con il calcolo della priorità. In questi casi, if è perfetto per interrompere presto il flusso.

3. Range checking con if, elif, else

La variabile urgenza deve essere compresa tra 1 e 5. Qui si vede molto bene l’utilità di if / elif / else: prima si intercettano i valori troppo bassi, poi quelli troppo alti. Questo evita che il programma continui con un valore fuori specifica.

Questo schema è molto usato per:

  • punteggi numerici
  • percentuali
  • età, quantità, soglie di sicurezza
  • codici di stato

4. Gestione delle stringhe vuote

La descrizione viene letta con ticket.get(´descrizione´, ´´) per evitare un errore se il campo non esiste. Poi si controlla che sia una stringa non vuota. Usare strip() è importante perché una stringa composta solo da spazi non è davvero utile.

5. Logica di priorità

Una volta superati i controlli preliminari, il programma assegna una priorità. L’ordine delle condizioni è importante:

  • se c’è un blocco del servizio, la priorità è critica
  • altrimenti, se il cliente è premium e l’urgenza è alta, la priorità è alta
  • poi vengono i casi medi, bassi e molto bassi

Questa sequenza rappresenta una scelta di business precisa. In un sistema reale, l’ordine dei rami può cambiare completamente il risultato, quindi va progettato con attenzione.

6. Controllo finale sulla qualità del dato

Anche se il ticket è formalmente valido, la descrizione potrebbe essere troppo breve. Questo è un esempio interessante di caso limite “soft”: il dato non è sbagliato in senso stretto, ma non è abbastanza informativo. In questi casi si può decidere di restituire un avviso invece di bloccare tutto.

Best practice

  • Controlla prima i casi di errore: se un input è invalido, esci subito dalla funzione.
  • Separa validazione e logica: prima verifica i dati, poi applica le regole di business.
  • Ordina le condizioni per priorità reale: il primo ramo che risulta vero viene eseguito, quindi l’ordine conta molto.
  • Evita condizioni troppo lunghe: se un if diventa complesso, valuta di scomporlo in variabili o funzioni più piccole.
  • Usa messaggi chiari: in caso di errore, restituisci o registra informazioni comprensibili.
  • Non nascondere i casi limite: gestirli esplicitamente rende il codice più affidabile e più facile da testare.
  • Preferisci il fallback esplicito: l’else dovrebbe rappresentare davvero il comportamento predefinito, non una scorciatoia ambigua.

Riepilogo

Il controllo di flusso con if, elif, else non serve solo a scegliere tra alternative, ma anche a gestire in modo elegante i casi limite. Questo approccio migliora la qualità del software perché:

  • riduce gli errori dovuti a input inattesi
  • rende il codice più leggibile
  • separa chiaramente validazione e logica
  • permette di definire comportamenti di fallback sensati

In pratica, un buon controllo di flusso non si limita a dire “se succede A fai B”, ma include anche la domanda: “e se i dati non fossero quelli che mi aspetto?”. È qui che il codice diventa davvero robusto.

Approfondisci con risorse ufficiali

SHARE