Python Pratico: 3 Esercizi su Cicli e Condizionali per Sviluppare la Logica di Programmazione

Cerca:

Generic selectors
Exact matches only
Search in title
Search in content
Post Type Selectors
esercizi Python su if, cicli while e for

Imparare a programmare non è memorizzare una lista di comandi, ma capire come dare ordini sensati a una macchina che, di base, non ha un briciolo di buonsenso.

Se hai appena iniziato con Python, probabilmente ti senti come se avessi in mano una scatola di LEGO senza istruzioni.

Invece di perderci in definizioni astratte, ho preparato tre sfide concrete.

Passeremo dal fare i vigili urbani digitali al gestire un distributore automatico che non va in tilt se sbagli moneta.

Niente giri di parole: solo codice vero e un pizzico di logica per capire come ragiona un software quando deve prendere delle decisioni.


Esercizio 1: Il Vigile del Futuro (Facile)

Testo:
Un comune intelligente ha installato un nuovo sistema di rilevamento della velocità. Il sistema rileva la velocità di un’auto e deve determinare la sanzione da applicare secondo queste regole:

  • Se la velocità è inferiore o uguale al limite, stampa “Velocità regolare”.

  • Se la velocità supera il limite di non più di 10 km/h, stampa “Multa lieve: 50€”.

  • Se la velocità supera il limite di più di 10 km/h ma non più di 30 km/h, stampa “Multa grave: 150€”.

  • Se la velocità supera il limite di oltre 30 km/h, stampa “Multa grave e sospensione della patente”.

Scrivi un programma che, presi in input limite (intero) e velocità_rilevata (intero), produca l’output corretto.

Soluzione:

# 1. Acquisizione dei dati dall'utente
# La funzione input() restituisce una stringa, che viene convertita in intero con int()
limite = int(input("Inserisci il limite di velocità (km/h): "))
velocita_rilevata = int(input("Inserisci la velocità rilevata (km/h): "))

# 2. Calcolo della differenza
eccesso = velocita_rilevata - limite

# 3. Logica condizionale: la struttura if-elif-else permette di valutare più condizioni in sequenza.
#    Viene eseguito il primo blocco la cui condizione è vera.
if eccesso <= 0:
    print("Velocità regolare.")
elif eccesso <= 10: # Se siamo qui, significa che eccesso > 0 (altrimenti il primo if sarebbe stato vero)
    print("Multa lieve: 50€")
elif eccesso <= 30:
    print("Multa grave: 150€") 
else: 
# Se nessuna delle condizioni precedenti è vera, significa eccesso > 30
    print("Multa grave e sospensione della patente.")
Inserisci il limite di velocità (km/h): 90
Inserisci la velocità rilevata (km/h): 110
Multa grave: 150€

💡 Attenzione all’ordine delle condizioni!

In una struttura if-elif-else, l’ordine è cruciale. Se avessimo messo elif eccesso <= 30 prima di elif eccesso <= 10, un eccesso di 5 km/h avrebbe soddisfatto la prima condizione (eccesso <= 30), stampando erroneamente “Multa grave”.

Mini Quiz:
Quale proprietà della logica booleana abbiamo sfruttato per rendere la seconda condizione elif eccesso <= 10 corretta, anche se non abbiamo esplicitamente controllato che eccesso > 0?

Esercizio 2: Il Distributore Automatico Sostenibile (Facile/Medio)

Testo:
Un distributore automatico di bevande accetta solo monete da 0.50€, 1€ e 2€. Il programma deve:

  1. Chiedere all’utente il prezzo della bevanda (es. 1.50€).

  2. Chiedere all’utente di inserire una moneta alla volta (0.5, 1 o 2) fino a quando il totale inserito non copre il prezzo.

  3. Se l’utente inserisce un valore non valido (es. 0.20€), il programma deve ignorarlo, avvisarlo e continuare a chiedere monete.

  4. Una volta raggiunto o superato il prezzo, il programma deve calcolare e stampare il resto (con un messaggio come “Resto: X€”).

Forse potrebbe interessarti anche:  Guida Pratica: Quale Test Statistico Usare? Dalla Teoria al Codice Python

Soluzione:

# Inizializzazione delle variabili
prezzo = float(input("Inserisci il prezzo della bevanda (€): "))
totale_inserito = 0.0
# Lista delle monete accettate per una facile verifica
monete_valide = [0.5, 1.0, 2.0]

print(f"Totale da pagare: {prezzo:.2f}€. Inserisci monete (0.5€, 1€, 2€):")

# Il ciclo while continua finché la condizione 'totale_inserito < prezzo' è vera
while totale_inserito < prezzo:
    # Gestione degli errori di input: usiamo try-except per evitare crash se l'utente inserisce testo
    try:
        moneta = float(input("Inserisci una moneta: "))
    except ValueError:
        print("Errore: inserisci un numero valido.")
        continue  # 'continue' salta il resto del ciclo e ricomincia dall'inizio

    # Logica di validazione della moneta
    if moneta in monete_valide:
        totale_inserito += moneta
        print(f"Inserito {moneta}€. Totale attuale: {totale_inserito:.2f}€")
    else:
        print(f"Moneta non valida. Inserisci solo {monete_valide}.")

# Usciti dal ciclo, calcoliamo il resto
resto = totale_inserito - prezzo
print(f"\nPagamento completato! Il resto è: {resto:.2f}€")
Inserisci il prezzo della bevanda (€): 0.6
Totale da pagare: 0.60€. Inserisci monete (0.5€, 1€, 2€):
Inserisci una moneta: 1
Inserito 1.0€. Totale attuale: 1.00€

Pagamento completato! Il resto è: 0.40€

💡 Cicli a condizione di uscita:

Il ciclo while è perfetto quando non sappiamo a priori quante iterazioni saranno necessarie. La condizione totale_inserito < prezzo è la guardia del ciclo.
💡 Validazione dell’input:

L’uso di try-except e della lista monete_valide rende il programma robusto e resistente agli errori dell’utente.

Mini Quiz:
Cosa succederebbe se rimuovessimo la riga continue all’interno del blocco except?

Esercizio 3: Il Mosaico di Numeri (Medio)

Testo:
Un artista digitale vuole creare un mosaico basato su un numero intero n fornito dall’utente. Il programma deve stampare un quadrato di n x n caratteri, seguendo queste regole:

  • Il bordo esterno del quadrato è composto dal carattere #.

  • L’interno del quadrato (se n > 2) è composto dal carattere O.

  • L’angolo in alto a sinistra e l’angolo in basso a destra devono essere stampati con il carattere *.

Ad esempio, per n = 5:

* # # # #
# O O O #
# O O O #
# O O O #
# # # # *

Soluzione:

n = int(input("Inserisci la dimensione del mosaico (n): "))

# Ciclo esterno: scorre le righe (da 0 a n-1)
for riga in range(n):
    # Ciclo interno: scorre le colonne (da 0 a n-1)
    for colonna in range(n):
        # Logica complessa per decidere il carattere da stampare
        # Condizioni combinate con operatori logici (and, or)

        # Angolo alto-sinistra (riga 0, colonna 0)
        if riga == 0 and colonna == 0:
            print("*", end=" ")
        # Angolo basso-destra (riga n-1, colonna n-1)
        elif riga == n - 1 and colonna == n - 1:
            print("*", end=" ")
        # Bordo superiore (riga 0) o bordo inferiore (riga n-1)
        # Bordo sinistro (colonna 0) o bordo destro (colonna n-1)
        elif riga == 0 or riga == n - 1 or colonna == 0 or colonna == n - 1:
            print("#", end=" ")
        # Interno: tutti gli altri casi
        else:
            print("O", end=" ")
    # Dopo ogni riga, andiamo a capo
    print()
Inserisci la dimensione del mosaico (n): 6
* # # # # # 
# O O O O # 
# O O O O # 
# O O O O # 
# O O O O # 
# # # # # * 

💡 Nested Loops (Cicli annidati):

Forse potrebbe interessarti anche:  File Parquet: La Guida Pratica per Usarli con Python (Esempi e Vantaggi su CSV)

Quando si lavora con strutture bidimensionali (griglie, matrici), un ciclo esterno per le righe e uno interno per le colonne è l’approccio standard.
💡 Decomposizione del problema:

La condizione per il bordo (riga == 0 or riga == n-1 or colonna == 0 or colonna == n-1) è molto più elegante che scrivere otto condizioni separate per ogni lato. Abbiamo usato l’algebra di Boole per semplificare la logica.

Mini Quiz:
Quale problema di progettazione si verificherebbe se avessimo messo la condizione per gli angoli (*) dopo la condizione per il bordo (#)?

Risposte Dettagliate ai Mini Quiz

Esercizio 1:
Quale proprietà della logica booleana abbiamo sfruttato per rendere la seconda condizione elif eccesso <= 10 corretta, anche se non abbiamo esplicitamente controllato che eccesso > 0?

Risposta:

Abbiamo sfruttato la proprietà della valutazione sequenziale (o short-circuit evaluation) e la mutua esclusività della struttura if-elif-else. La condizione del primo if (eccesso <= 0) viene valutata per prima. Se questa è falsa, possiamo essere certi che la sua negazione (eccesso > 0) è vera. Quindi, quando si valuta elif eccesso <= 10, il contesto logico garantisce implicitamente che eccesso sia già maggiore di 0.

Questo è un esempio di come l’ordine delle condizioni costruisca una logica implicita senza bisogno di usare l’operatore and.

Esercizio 2:
Cosa succederebbe se rimuovessimo la riga continue all’interno del blocco except?

Risposta:

Se rimuovessimo continue, il flusso del programma, dopo aver stampato l’errore, uscirebbe dal blocco except e proseguirebbe con le istruzioni successive all’interno del ciclo while.

In particolare, arriverebbe alla riga if moneta in monete_valide:. A questo punto, la variabile moneta non sarebbe stata definita a causa dell’errore di conversione, causando un NameError e il crash del programma. continue serve proprio a saltare il resto del ciclo e ripartire con l’iterazione successiva, evitando di usare variabili non inizializzate.

Forse potrebbe interessarti anche:  Come calcolare la Divisione tra Polinomi in Python (vs Metodo di Ruffini)

Esercizio 3:
Quale problema di progettazione si verificherebbe se avessimo messo la condizione per gli angoli (*) dopo la condizione per il bordo (#)?

Risposta:

Se la condizione per il bordo (riga == 0 or ...) fosse stata prima di quella per gli angoli, allora per i punti angolo (es. riga 0, colonna 0) la condizione del bordo sarebbe risultata vera (perché fanno parte del bordo). Quindi, il programma avrebbe stampato # invece di *.

L’ordine delle condizioni è fondamentale: le condizioni più specifiche (gli angoli) devono essere valutate prima di quelle più generali (il bordo) per essere “catturate” correttamente.

Commento Applicativo

Esercizio 1: Il Vigile del Futuro

  • Introduce il concetto di esclusività logica.

  • Molti principianti pensano di dover scrivere if eccesso > 0 and eccesso <= 10. Questo esercizio insegna che la struttura stessa dell’ elif “pulisce” il codice, eliminando ridondanze. È un esercizio di economia cognitiva: meno scrivi, meno sbagli.

Esercizio 2: Il Distributore Sostenibile

  • Affronta il mondo reale, dove gli utenti sbagliano.

  • Insegna la resilienza del software. L’uso del while combinato con try-except trasforma un semplice script in un programma “robusto”. È il salto di qualità tra “scrivere codice che funziona” e “scrivere codice che non si rompe”.

Esercizio 3: Il Mosaico di Numeri

  • Allena la visione spaziale e astratta.

  • Lavorare con le coordinate (riga, colonna) è la base per tutto: dalla creazione di videogame 2D alla manipolazione di dati in tabelle (Data Science). La sfida qui è tradurre un’immagine visiva in regole booleane matematiche.

Pubblicità