Parte III — Organizzare
Capitolo 13 — File e cartelle
I programmi visti finora dimenticano tutto quando finiscono: i dati vivono in memoria e svaniscono alla chiusura. Per ricordare tra un'esecuzione e l'altra — salvare una lista di cose da fare, leggere un file di configurazione, produrre un rapporto — bisogna scrivere su disco. Leo rende l'operazione diretta, con qualche attenzione in più che ti risparmia grattacapi.
🦁 Curiosità — Un disco da una tonnellata per 5 MB
Il primo disco rigido della storia, l'IBM 350 del 1956, era alto come un armadio e pesava quasi una tonnellata, eppure conteneva soltanto circa 5 MB: oggi una singola foto scattata col telefono può occupare più spazio di così. Per spostarlo serviva un carrello elevatore; per spostare le tue foto basta un dito. La capacità di «ricordare su disco» è diventata enormemente più leggera in meno di settant'anni.
Una nota prima di cominciare: i percorsi relativi ("nota.txt") partono dalla cartella da cui lanci il programma. Le cartelle si separano con la barra /, anche su Windows.
💡 L'idea — Il percorso è un indirizzo
Il percorso di un file (la sua path) funziona come l'indirizzo di casa: provincia, città, via, numero civico restringono il campo un pezzo alla volta, finché non arrivi alla porta giusta. Così
documenti/2026/nota.txtè «cartella documenti, dentro la cartella 2026, il file nota.txt». Una volta che leggi un percorso come un indirizzo, non ti perdi più nell'albero delle cartelle.
Leggere e scrivere testo
Le due operazioni fondamentali sono scrivere un testo in un file e rileggerlo:
scrivi_file("nota.txt", "Prima riga\nSeconda riga")
aggiungi_a_file("nota.txt", "Terza riga")
variabile contenuto = leggi_file("nota.txt")
scrivi "--- contenuto ---"
scrivi(contenuto)
scrivi "--- righe ---"
per ogni riga in leggi_righe("nota.txt") fai
scrivi "> {riga}"
fine
scrivi "Esiste nota.txt? {esiste("nota.txt")}"
scrivi "Esiste manca.txt? {esiste("manca.txt")}"--- contenuto ---
Prima riga
Seconda riga
Terza riga
--- righe ---
> Prima riga
> Seconda riga
> Terza riga
Esiste nota.txt? vero
Esiste manca.txt? falsoscrivi_file(percorso, testo) crea il file (o ne sostituisce il contenuto, se esiste già). aggiungi_a_file(percorso, testo) aggiunge in fondo senza cancellare — comodo per un registro che cresce nel tempo — e va a capo da sé. leggi_file(percorso) restituisce tutto il contenuto come un unico testo; leggi_righe(percorso) lo dà invece come lista di righe, già senza i caratteri di a-capo, perfetto per scorrerle con per ogni. Infine esiste(percorso) controlla se un file (o una cartella) c'è prima di toccarlo.
Dietro questa semplicità c'è parecchia cura. leggi_file riconosce da solo la codifica del testo (UTF-8, i formati Unicode del Blocco note, la codifica di Excel su Windows) e normalizza gli a-capo di Windows. Se provi a leggere come testo un file che non lo è — un'immagine, un programma — ottieni un ErroreFile in italiano invece di caratteri illeggibili. E su Windows i nomi di file vietati vengono rifiutati con una spiegazione, prima ancora di aprire il file.
JSON e CSV: dati strutturati
Il testo libero va bene per le note; per i dati strutturati — liste di dizionari, tabelle — ci sono formati dedicati, e Leo li legge e scrive con una riga. Il JSON è lo standard per scambiare dati tra programmi:
variabile persone = [
{"nome": "Ada", "eta": 36},
{"nome": "Marco", "eta": 29}
]
scrivi_json("persone.json", persone)
variabile lette = leggi_json("persone.json")
per ogni p in lette fai
scrivi "{p["nome"]} ha {p["eta"]} anni"
fineAda ha 36 anni
Marco ha 29 anniscrivi_json trasforma una struttura Leo (liste, dizionari, numeri, testi) in un file JSON ben formattato, e leggi_json fa il percorso inverso, restituendo di nuovo liste e dizionari pronti all'uso. Il bello è che il dato che rileggi è identico a quello che hai salvato: niente conversioni manuali.
Per le tabelle in stile foglio di calcolo c'è il CSV, che Excel e gli altri programmi d'ufficio capiscono:
scrivi_tabella("persone.csv", persone)
scrivi(leggi_file("persone.csv"))nome,eta
Ada,36
Marco,29scrivi_tabella prende una lista di dizionari e ne fa un CSV, mettendo in cima i nomi delle colonne. C'è anche leggi_tabella, che fa il contrario e indovina da solo il separatore (virgola, punto e virgola o tabulazione). Vedremo nel tour della libreria che esiste anche un tipo tabella più potente, con filtri, ordinamenti e raggruppamenti.
Lavorare con le cartelle
Oltre ai singoli file, puoi creare cartelle ed elencarne il contenuto:
crea_cartella("sotto")
scrivi_file("sotto/a.txt", "a")
scrivi_file("sotto/b.txt", "b")
scrivi(elenca_file("sotto"))["a.txt", "b.txt"]crea_cartella crea la cartella (e quelle intermedie, se nel percorso ce ne sono di mancanti). elenca_file(cartella) restituisce i nomi dei file in ordine alfabetico; puoi anche filtrarli per estensione. C'è il gemello elenca_cartelle per le sottocartelle. Con questi mattoni puoi scrivere programmi che riordinano una cartella, elaborano tutti i file di un certo tipo o costruiscono un indice.
🦁 Curiosità — Nomi presi in prestito dall'ufficio di carta
Parole come «file» (in inglese, l'archivio di documenti), «cartella» e «cestino» non sono nate col computer: vengono dritte dall'ufficio di carta. Chi progettò le prime interfacce grafiche copiò di proposito la scrivania, le cartelline e il cestino della spazzatura, per rendere familiare una cosa del tutto nuova. Ancora oggi buttiamo i file nel «cestino»: una metafora di carta sopravvissuta dentro lo schermo.
Un esempio che mette tutto insieme
Pensa a un piccolo diario: a ogni esecuzione aggiunge una riga con la data e un pensiero, e poi mostra tutto quello che hai scritto finora. Scrivere, aggiungere, rileggere e scorrere: con aggiungi_a_file e leggi_righe lo costruisci in pochissime righe. Questo è il momento in cui i tuoi programmi smettono di essere esercizi e cominciano a servire a qualcosa, perché ricordano.
Prova tu
- Scrivi un programma «diario» che chiede un pensiero all'utente, lo aggiunge a un file con la data di oggi (usa
oggi()), poi stampa tutte le righe scritte finora. - Salva in JSON una piccola rubrica (nome, telefono, email per ogni contatto), poi scrivi un secondo programma che la rilegge e la stampa ordinata per nome.
- Scrivi un programma che crea una cartella
backup, vi copia dentro il contenuto di un file di testo esistente, e conferma stampando l'elenco dei file nella cartella.
Con questo si chiude la Parte III. Sai organizzare il codice in oggetti e moduli, e far sì che i tuoi programmi ricordino i dati su disco. Nella Parte IV alziamo il tiro: parallelismo, sequenze pigre e il grande catalogo della libreria.