Leggere i messaggi di errore e un piccolo progetto
Un traceback di Python si legge dal fondo: l'ultima riga indica l'errore e la riga di codice subito sopra mostra dove si è verificato.
Una falena incollata in un registro nel 1947
Oggi la maggior parte dei bug sono errori nel codice, e Python sa segnalarti quelli che riesce a rilevare. I principianti spesso vedono un errore rosso come un verdetto. È più vicino a una bolla di consegna: che cosa è andato storto, su quale riga, e in quale pezzo di codice. Il trucco è sapere dove guardare.
Leggi un traceback dal fondo verso l'alto
total = 0
count = 0
print(total / count)Traceback (most recent call last):
File "main.py", line 3, in <module>
print(total / count)
~~~~~~^~~~~~~
ZeroDivisionError: division by zeroParti dall'ultima riga. ZeroDivisionError: division by zero dà il tipo di errore e una breve spiegazione. Poi sali alla riga File: il nome del file (sul tuo computer compare il percorso completo della cartella; qui è abbreviato in main.py) e il numero di riga, 3. La riga sotto è il codice stesso, e Python 3.12 segna l'operazione esatta che è fallita con ^ sotto il segno /. Solo dopo aver letto tutte e tre dovresti cominciare a cambiare le cose. Quando l'errore avviene dentro una funzione, il traceback elenca ogni chiamata fatta per arrivarci, e la riga File più in basso è di solito quella da guardare per prima.
| Errore | Causa abituale | Esempio |
|---|---|---|
| SyntaxError | La riga non è Python valido: parentesi, due punti o virgolette mancanti | print("hi" |
| IndentationError | Rientro mancante o irregolare | if x > 1: senza riga rientrata |
| NameError | Un nome che non esiste ancora, spesso un errore di battitura | pritn("hi") |
| TypeError | Un'operazione sul tipo sbagliato | "Age: " + 15 |
| ValueError | Tipo giusto, valore impossibile | int("abc") |
| IndexError | Indice oltre la fine di una lista o di una stringa | [1, 2][2] |
| KeyError | Chiave non presente nel dizionario | {"a": 1}["b"] |
| ZeroDivisionError | Divisione per zero | 5 / 0 |
Un SyntaxError è diverso dagli altri. Python lo trova prima di eseguire qualsiasi cosa, quindi non viene eseguita nemmeno la riga 1, e non c'è l'intestazione «Traceback». Tutti gli altri avvengono mentre il programma gira, dopo che le righe precedenti hanno già fatto il loro lavoro. Quando ti aspetti un particolare errore, puoi catturarlo con try ed except, che il tutorial tratta nel suo capitolo sugli errori: Python prova il blocco rientrato, e se quell'errore avviene, esegue il blocco except invece di fermarsi.
print("before")
n = int("abc")
print("after")before
Traceback (most recent call last):
File "main.py", line 2, in <module>
n = int("abc")
^^^^^^^^^^
ValueError: invalid literal for int() with base 10: 'abc'text = "abc"
try:
n = int(text)
except ValueError:
n = 0
print(n)0Gli errori più difficili non danno alcun messaggio. Un errore logico è un programma che gira e stampa la risposta sbagliata, come il programma di valutazione dell'unità sull'if che dava una C a 85. Python non può sapere che cosa intendevi. Per questi, torna alla tabella di traccia, oppure aggiungi righe print temporanee che mostrano le variabili a ogni passo, poi toglile quando il bug è trovato.
Piccolo progetto: un registro della paghetta
Il progetto usa qualcosa da quasi ogni unità: un dizionario delle spese, una funzione che restituisce un totale, un ciclo for, una f-string e un if. Scrivilo, eseguilo, poi rendilo tuo: cambia le voci, aggiungi una categoria, o avvisa quando una singola voce costa più di metà della paghetta.
def total(spent):
t = 0
for amount in spent.values():
t += amount
return t
allowance = 30000
spent = {"snacks": 4500, "bus card": 10000, "notebook": 2500}
used = total(spent)
left = allowance - used
for item, amount in spent.items():
print(f"{item}: {amount} won")
print(f"Spent {used}, left {left}")
if left < 15000:
print("Less than half left")snacks: 4500 won
bus card: 10000 won
notebook: 2500 won
Spent 17000, left 13000
Less than half leftPrima di cambiarlo, scrivi una tabella di traccia per used e left, e prevedi che cosa succede se aggiungi una voce da 6000 won. Poi fai debug di proposito: cancella i due punti dopo la riga def, sbaglia una volta a scrivere spent e dividi used per zero. Leggi ogni traceback dal fondo prima di correggere. Saper rompere un programma e aggiustarlo di nuovo è la vera abilità che questo corso ha costruito.
| traceback | Il rapporto di errore di Python; leggilo dal fondo |
| SyntaxError | Codice non valido, trovato prima che parta qualsiasi cosa |
| NameError | Un nome che non esiste, spesso un errore di battitura |
| TypeError | Un'operazione su un tipo di valore sbagliato |
| ValueError | Il tipo giusto con un valore impossibile, come int("abc") |
| errore logico | Gira senza messaggio ma dà la risposta sbagliata |
| try / except | Esegue il blocco except invece di fermarsi quando avviene quell'errore |
- Quale riga di un traceback nomina il tipo di errore?
- La prima riga
- La riga File
- L'ultima riga
- La riga con i segni ^
- Quale errore causa
int("12a")?- TypeError
- ValueError
- NameError
- SyntaxError
- Quale errore causa
pritn("hi")?- SyntaxError
- NameError
- TypeError
- Nessun errore
- Un programma stampa la riga 1 e poi si ferma con un errore alla riga 2. Quale tipo di errore non può essere la causa?
- SyntaxError
- NameError
- TypeError
- ZeroDivisionError
- Cosa stampa questo codice?
try: x = 10 / 0 except ZeroDivisionError: x = -1 print(x) - Cosa succede quando questo codice viene eseguito?
print("start") print(5 / 0) print("end")- Stampa start ed end
- Stampa start, poi si ferma con ZeroDivisionError
- Si ferma con ZeroDivisionError prima di stampare qualsiasi cosa
- Stampa start, inf ed end
- Un programma gira senza alcun messaggio ma stampa il totale sbagliato. Che tipo di errore è?
- SyntaxError
- Errore logico
- NameError
- IndentationError
- Cosa stampa questo codice?
spent = {"a": 4500, "b": 10000} print(30000 - sum(spent.values())) - Metti le righe di questo piccolo programma in ordine perché stampi il risultato qui sotto.Output
80.0 - Dov'è il bug? def avg(nums): return sum(nums) / len(nums), chiamata con avg([]).
- sum di una lista vuota è un errore
- len([]) è 0, quindi divide per zero
- return non può contenere una divisione
- Non c'è nessun bug
- «L'errore è sulla riga che nomina il messaggio, quindi la correzione va lì.» Spesso, ma non sempre. Nell'unità sulle funzioni, x = show_area(4, 3) seguito da x * 2 si ferma con un TypeError sulla riga x * 2, eppure il vero sbaglio è il print dentro show_area che avrebbe dovuto essere un return. Leggi la riga nominata, poi chiediti da dove vengono i suoi valori.
- «Avvolgere tutto in try/except risolve gli errori.» Li nasconde soltanto. Cattura un errore specifico che ti aspetti, come ValueError da int(input()), e gestiscilo in modo sensato.
- «Nessun messaggio di errore significa che il programma è corretto.» Gli errori logici passano inosservati. Prova con input di cui conosci già la risposta, compresi i casi limite come una lista vuota o un'età al limite.
- Leggi un traceback dal fondo: tipo di errore, poi file e riga, poi il codice segnato.
- Un SyntaxError ferma il programma prima che parta la riga 1; gli altri errori lo fermano a metà.
- try/except gestisce un errore che ti aspetti.
- Gli errori logici non danno messaggio: traccia e prova con risposte note.
- Fare debug significa rompere e aggiustare di proposito finché i messaggi sembrano ordinari.
Fonti di questo corso (6)
- Python Software Foundation, The Python Tutorial for Python 3.12 (docs.python.org/3.12/tutorial: 2 Using the Python Interpreter, 3 An Informal Introduction to Python (numbers, text, lists), 4 More Control Flow Tools (if, for, range, break and continue, defining functions, default argument values, 4.10 coding style: 4-space indentation), 5 Data Structures (list methods, 5.5 dictionaries, insertion order), 8 Errors and Exceptions (syntax errors, exceptions, reading the traceback, handling exceptions), 15 Floating-Point Arithmetic (0.1 + 0.2))
- Built-in Functions (docs.python.org/3.12/library/functions.html: print, input, len, int, float, str, type, round (round half to even: round(0.5) and round(-0.5) are 0, round(1.5) is 2), range, sum, min, max, sorted)
- Built-in Types (str methods upper, lower, replace, strip; dict.get; list.append, pop, remove, sort returning None)
- General Python FAQ (docs.python.org/3.12/faq/general.html: Guido van Rossum began Python in the 1989 Christmas holidays, posted it to USENET in February 1991, named it after Monty Python's Flying Circus)
- Curriculum for the Korean pages: 교육부 고시 제2022-33호 [별책 10] 정보과 교육과정 (PDF read 2026-10-19: 중학교 정보 [9정03-05] 리스트 등 데이터를 순차적으로 저장하는 구조, [9정03-06] 논리 연산과 중첩 제어 구조, [9정03-07] 함수 활용과 디버거로 오류 수정, [9정03-08] 실생활 문제를 프로그래밍으로 해결, 적용 시 고려 사항 「학생의 수준을 고려하여 적합한 프로그래밍 언어를 선정」; 고등학교 정보 [12정03-04] 자료형, [12정03-05] 표준입출력, [12정03-07] 제어 구조)
- Bug story only: Smithsonian National Museum of American History, Log Book With Computer Bug, 1947, Harvard Mark II, "first actual case of bug being found", probably not Hopper's log book (americanhistory.si.edu/collections/object/nmah_334663, read 2026-10-19)
Consultato il: 2026-10-19