gl/ripetizioni

Stringhe e file in Python: esercizi per la verifica

Stringhe, slicing, metodi e lettura di file in Python per la terza superiore: tre esercizi con codice completo e output, più gli errori da evitare.

di Gaetano Livornese

  • #informatica
  • #terza superiore
  • #liceo scientifico
  • #stringhe
  • #file
  • #python

Se fai informatica in terza al liceo scientifico, opzione scienze applicate, con due ore alla settimana, tra novembre e gennaio il programma arriva a stringhe e file, subito dopo cicli e funzioni. La verifica di solito è una prova pratica in laboratorio, fra cinque e nove settimane da oggi: un testo da leggere, un programma da scrivere e far girare. È il momento giusto per esercitarsi, perché la prova pratica non si prepara rileggendo: si prepara scrivendo codice con le mani sulla tastiera.

Qui trovi le regole delle stringhe, i metodi che servono davvero, la lettura e scrittura di file e tre esercizi con codice completo e output. Ho eseguito ogni riga: puoi copiare e provare. Se Python ti è ancora nuovo, parti da programmare in Python da zero.

Le stringhe sono sequenze immutabili

Una stringa è una sequenza di caratteri, e ogni carattere ha un indice che parte da 0. Gli indici negativi contano dalla fine: -1 è l’ultimo carattere.

frase = "Python è bello"
print(frase[0])      # P
print(frase[-1])     # o
print(frase[2:5])    # tho
print(frase[::-1])   # olleb è nohtyP

Lo slicing s[a:b] prende dal carattere a fino a b escluso. Il terzo valore è il passo: [::-1] percorre la stringa al contrario e la rovescia.

Le stringhe sono immutabili: non puoi scrivere frase[0] = "J", Python dà TypeError. Per cambiare qualcosa si costruisce una nuova stringa, e la si assegna a una variabile.

I metodi da conoscere

MetodoCosa faEsempio
upper() / lower()maiuscole / minuscole"ciao".upper() → 'CIAO'
strip()toglie spazi e \n agli estremi" ciao ".strip() → 'ciao'
split()spezza in una lista"a b c".split() → ['a', 'b', 'c']
replace(a, b)sostituisce"ciao".replace("a", "o") → 'cioo'
find(x)indice della prima occorrenza, -1 se non c’è"Python è bello".find("è") → 7
separatore.join(lista)unisce una lista"-".join(["a","b","c"]) → 'a-b-c'

Ogni metodo restituisce una nuova stringa e non modifica quella originale: se scrivi solo s.upper() senza assegnare il risultato, non succede nulla alla tua s. È uno degli errori più frequenti in laboratorio.

Per visitare i caratteri si usa un ciclo for:

def vocali(s):
    n = 0
    for c in s.lower():
        if c in "aeiou":
            n += 1
    return n

print(vocali("Programmazione"))   # 6

Le vocali di «Programmazione» sono o, a, a, i, o, e: sei. Il ciclo for c in s dà ogni carattere, senza bisogno di indici, e la forma c in "aeiou" controlla se il carattere compare nella stringa.

Il cifrario di Cesare con ord e chr

ord(c) restituisce il codice numerico di un carattere, chr(n) fa il contrario: ord("a") è 97, chr(100) è 'd'. Con questi due si sposta una lettera di k posti:

def cesare(testo, k):
    risultato = ""
    for c in testo:
        if "a" <= c <= "z":
            nuova = (ord(c) - ord("a") + k) % 26 + ord("a")
            risultato += chr(nuova)
        else:
            risultato += c
    return risultato

print(cesare("ciao mondo", 3))   # fldr prqgr

Il passaggio chiave è % 26: sposta la lettera senza uscire dall’alfabeto, e quindi la x con k = 3 diventa a. Gli spazi e i simboli non sono lettere e passano inalterati. Il cifrario è spiegato anche dal lato matematico in crittografia: Cesare, Vigenère, RSA.

Lavorare con i file

Il modo corretto di aprire un file è with, che lo chiude da solo a fine blocco:

with open("voti.txt") as f:
    for riga in f:
        print(riga.strip())

Il ciclo for riga in f legge una riga alla volta, e ogni riga si porta dietro il carattere \n di a capo: per questo quasi sempre serve strip(). Le modalità di apertura sono tre:

  • "r" (default): lettura. Se il file non esiste, errore.
  • "w": scrittura. Se il file esiste, lo svuota subito.
  • "a": aggiunta in coda, senza toccare il contenuto.

Se ti serve tutto il contenuto in una volta, f.read() restituisce un’unica stringa, mentre f.readlines() restituisce una lista con una stringa per riga, \n compreso. Per file piccoli vanno bene entrambi; il ciclo riga per riga resta la scelta più ordinata e funziona anche con file grandi.

Per scrivere si usa f.write(testo), e anche qui il \n va messo a mano: f.write("Anna\n"). Un file che non esiste si gestisce così:

try:
    with open("voti.txt") as f:
        contenuto = f.read()
except FileNotFoundError:
    print("File non trovato")

Esercizio 1: palindromo e anagramma

Scrivi una funzione che dica se una frase è palindroma (si legge uguale da destra a sinistra, ignorando spazi e maiuscole) e una che dica se due parole sono anagrammi.

def e_palindromo(s):
    pulita = s.replace(" ", "").lower()
    return pulita == pulita[::-1]

def e_anagramma(a, b):
    return sorted(a.lower()) == sorted(b.lower())

print(e_palindromo("Anna"))                       # True
print(e_palindromo("i topi non avevano nipoti"))  # True
print(e_palindromo("ciao"))                       # False
print(e_anagramma("Roma", "Amor"))                # True
print(e_anagramma("casa", "cosa"))                # False

Per il palindromo tolgo gli spazi con replace, porto tutto in minuscolo e confronto la stringa con la sua versione rovesciata. Per l’anagramma sorted trasforma ogni parola in una lista di lettere ordinate: due parole sono anagrammi se, ordinate, danno la stessa lista. «roma» e «amor» danno entrambe ['a','m','o','r']; «casa» e «cosa» no, perché una ha una a dove l’altra ha una o.

Esercizio 2: parole e riga più lunga di un file

Il file parole.txt contiene tre righe. Conta le parole totali e trova la riga più lunga.

il gatto dorme
sul divano di casa
oggi piove
n_parole = 0
piu_lunga = ""

with open("parole.txt") as f:
    for riga in f:
        riga = riga.strip()
        n_parole += len(riga.split())
        if len(riga) > len(piu_lunga):
            piu_lunga = riga

print("Parole:", n_parole)
print("Riga più lunga:", piu_lunga, "(", len(piu_lunga), "caratteri )")

Output:

Parole: 9
Riga più lunga: sul divano di casa ( 18 caratteri )

Le righe hanno 3, 4 e 2 parole: 9 in tutto. «sul divano di casa» ha 3 + 1 + 6 + 1 + 2 + 1 + 4 = 18 caratteri, contando gli spazi, ed è più lunga di «il gatto dorme», che ne ha 14. Il strip() è prima del conteggio: senza, ogni riga avrebbe un carattere in più per il \n, e il risultato sarebbe sbagliato, 15 al posto di 14 per la prima riga.

Esercizio 3: media dei voti letti da un file

Il file voti.txt contiene, per ogni studente, il nome e tre voti separati da virgole. Stampa la media di ognuno e la media di tutti i voti.

Anna,7,8,6
Marco,5,6,7
Sara,9,8,10
somma_totale = 0
conta_voti = 0

try:
    with open("voti.txt") as f:
        for riga in f:
            campi = riga.strip().split(",")
            nome = campi[0]
            voti = [int(x) for x in campi[1:]]
            media = sum(voti) / len(voti)
            print(nome, round(media, 2))
            somma_totale += sum(voti)
            conta_voti += len(voti)
    print("Media generale:", round(somma_totale / conta_voti, 2))
except FileNotFoundError:
    print("File non trovato")

Output:

Anna 7.0
Marco 6.0
Sara 9.0
Media generale: 7.33

Si spezza ogni riga sulle virgole: campi[0] è il nome, campi[1:] sono i voti, ancora stringhe, quindi vanno convertiti con int. Anna: 21 / 3 = 7; Marco: 18 / 3 = 6; Sara: 27 / 3 = 9. La media generale è 66 / 9 = 7,33. Le somme si accumulano fuori dal ciclo, altrimenti il valore si azzera a ogni riga.

Gli errori che costano punti in laboratorio

  • Dimenticare il \n: leggendo, non togliere strip() falsa lunghezze e confronti; scrivendo, senza \n tutte le righe finiscono attaccate.
  • Modificare una stringa sul posto: s[0] = "x" non funziona, e s.upper() senza assegnazione non cambia s.
  • Aprire in "w" un file che volevi leggere o completare: lo svuota prima ancora di scrivere. Per aggiungere si usa "a".
  • Indice fuori range: s[len(s)] non esiste, l’ultimo indice valido è len(s) - 1. Con for c in s il problema non si pone.
  • Righe vuote in fondo al file: "".split(",") dà [''] e int('') dà ValueError. Se il file ha una riga vuota finale, controlla prima if riga.strip():.

Per i cicli annidati e l’uso degli indici, che qui si danno per noti, c’è cicli e array in terza informatica; le funzioni usate sopra sono in passaggio dei parametri, e per chi vuole il passo successivo, ricorsione, fattoriale e Fibonacci. La pagina materie: informatica spiega come lavoro.

Simulatore e prossimo passo

Per l’informatica non c’è un simulatore dedicato: nelle simulazioni per il liceo trovi prove di matematica e fisica, quindi non è la categoria giusta per questa verifica. Il modo migliore per prepararsi è rifare i tre esercizi senza guardare, cambiando i dati: un altro file, un’altra frase, una colonna in più.

Se la prova di laboratorio ti spaventa, scrivimi dalla pagina contatti: la diagnosi iniziale, in cui vediamo insieme dove ti blocchi, è gratuita.

Domande frequenti

Perché non posso modificare un carattere di una stringa in Python?

Perché le stringhe sono immutabili: per cambiarle si costruisce una nuova stringa, per esempio con replace, con lo slicing o concatenando i caratteri in un ciclo.

Che differenza c'è tra aprire un file in modalità 'w' e 'a'?

La modalità 'w' crea il file o ne cancella il contenuto, la modalità 'a' aggiunge in coda senza toccare quello che c'è già. Sbagliare modalità è un modo classico per perdere i dati.

Perché si usa with quando si apre un file?

Perché il blocco with chiude il file da solo alla fine, anche se nel mezzo c'è un errore, e così non rischi di lasciarlo aperto o di perdere dati non ancora scritti.

Come si gestisce un file che non esiste?

Si racchiude l'apertura in un blocco try e si intercetta FileNotFoundError nel blocco except, stampando un messaggio chiaro al posto dell'errore che interrompe il programma.

Continua a leggere

Vuoi applicare quello che hai letto?

Parliamone 30 minuti gratis: guardiamo insieme dove sei bloccato e ti dico onestamente come posso aiutarti.

Oppure scrivimi su WhatsApp.