2025 – prof. Roberto Fuligni
Introduzione a Python per l'insegnamento
Questo capitolo fornisce le basi della programmazione Python orientate all'insegnamento delle discipline STEM. Acquisirai le competenze fondamentali che ti permetteranno di utilizzare Python come strumento didattico nelle tue lezioni.
Sintassi di base e prime operazioni
Python è un linguaggio di programmazione noto per la sua sintassi chiara e leggibile, che lo rende particolarmente adatto all'insegnamento.
Python segue una filosofia di design che privilegia la leggibilità e la semplicità. Questo approccio è riassunto nel documento "The Zen of Python" che puoi visualizzare digitando import this
in un interprete Python.
Commenti e documentazione
I commenti sono parti di codice non eseguite che servono a spiegare cosa fa il programma:
# Questo è un commento su una singola riga
"""
Questo è un commento
su più righe (docstring)
utile per documentare funzioni e moduli
"""
Indentazione
In Python, l'indentazione non è solo una convenzione stilistica ma è parte della sintassi:
if temperatura > 30:
print("Fa caldo!") # Notare l'indentazione
consiglio = "Bevi molta acqua"
else:
print("La temperatura è accettabile")
consiglio = "Goditi la giornata"
Operazioni aritmetiche
Python supporta tutte le operazioni matematiche di base:
# Operazioni fondamentali
somma = 5 + 3 # 8
differenza = 5 - 3 # 2
prodotto = 5 * 3 # 15
quoziente = 5 / 3 # 1.6666... (divisione)
quoziente_intero = 5 // 3 # 1 (divisione intera)
resto = 5 % 3 # 2 (resto della divisione)
potenza = 5 ** 3 # 125 (5 elevato a 3)
Operatori di confronto e logici
# Operatori di confronto
uguale = 5 == 5 # True
diverso = 5 != 3 # True
maggiore = 5 > 3 # True
maggiore_uguale = 5 >= 5 # True
minore = 5 < 10 # True
minore_uguale = 5 <= 5 # True
# Operatori logici
and_logico = True and False # False
or_logico = True or False # True
not_logico = not True # False
Input e output
L'interazione con l'utente avviene tramite le funzioni input()
e print()
:
# Output
print("Benvenuto al calcolatore di formule!")
print("Il risultato è:", 2 + 3) # Il risultato è: 5
# Input
nome = input("Come ti chiami? ")
print("Ciao", nome)
# Input numerico (converti la stringa in numero)
eta = int(input("Quanti anni hai? "))
print("Tra 10 anni avrai", eta + 10, "anni")
Formattazione del testo
Python offre diversi modi per formattare le stringhe:
nome = "Maria"
punteggio = 9.5
# Metodo f-string (più moderno, Python 3.6+)
messaggio = f"La studentessa {nome} ha ottenuto {punteggio} punti"
# Metodo format()
messaggio = "La studentessa {} ha ottenuto {} punti".format(nome, punteggio)
# Formattazione numerica
pi_greco = 3.14159
messaggio = f"Pi greco arrotondato a due decimali: {pi_greco:.2f}" # 3.14
Variabili, tipi di dati e strutture dati fondamentali
Variabili
In Python, le variabili sono etichette che puntano a oggetti in memoria:
x = 10 # x è un'etichetta che punta all'intero 10
y = x # ora anche y punta allo stesso oggetto
x = 20 # x ora punta a un nuovo oggetto (20), ma y punta ancora a 10
Tipi di dati principali
Python ha diversi tipi di dati integrati:
# Numeri
intero = 42
decimale = 3.14159
complesso = 2 + 3j
# Booleani
vero = True
falso = False
# Stringhe
nome = "Python"
frase = 'Didattica computazionale'
testo_lungo = """Questo è un testo
che si estende su
più righe"""
# None (valore nullo)
vuoto = None
Per verificare il tipo di una variabile, usiamo la funzione type()
:
x = 10
print(type(x)) # <class 'int'>
Strutture dati fondamentali
Liste
Le liste sono strutture dati fondamentali in Python, sequenze mutabili (modificabili) che possono contenere elementi di diversi tipi. Sono definite da parentesi quadre []
e gli elementi sono separati da virgole ,
.
# Creazione di liste
numeri = [1, 2, 3, 4, 5]
dati_misti = [1, "due", 3.0, [4, 5]]
# Accesso agli elementi (l'indice parte da 0)
primo = numeri[0] # 1
ultimo = numeri[-1] # 5
# Slicing (sottoliste)
primi_tre = numeri[0:3] # [1, 2, 3]
da_secondo = numeri[1:] # [2, 3, 4, 5]
fino_terzo = numeri[:3] # [1, 2, 3]
# Modifica
numeri[0] = 10 # ora numeri = [10, 2, 3, 4, 5]
# Metodi utili
numeri.append(6) # Aggiunge 6 alla fine: [10, 2, 3, 4, 5, 6]
numeri.insert(1, 15) # Inserisce 15 in posizione 1: [10, 15, 2, 3, 4, 5, 6]
numeri.remove(3) # Rimuove il valore 3: [10, 15, 2, 4, 5, 6]
elemento = numeri.pop() # Rimuove e restituisce l'ultimo elemento (6)
lunghezza = len(numeri) # 5
# Iterazione
for numero in numeri:
print(numero)
Tuple
Le tuple sono simili alle liste ma sono immutabili (non modificabili):
# Creazione di tuple
coordinate = (10, 20)
punto_3d = (10, 20, 30)
# Accesso (come per le liste)
x = coordinate[0] # 10
# Le tuple non possono essere modificate dopo la creazione
# coordinate[0] = 15 # Questo genererebbe un errore
# Tupla con un elemento (richiede una virgola)
singolo = (42,)
Dizionari
I dizionari sono collezioni di coppie chiave-valore, dove ogni chiave è unica e identifica un valore associato. In Python, i dizionari sono implementati come oggetti di tipo dict
e sono definiti utilizzando parentesi graffe {}
.
# Creazione di dizionari
studente = {
"nome": "Laura",
"età": 16,
"materie": ["Matematica", "Fisica", "Informatica"]
}
# Accesso ai valori
nome = studente["nome"] # Laura
materie = studente["materie"] # ["Matematica", "Fisica", "Informatica"]
# Modifica dei valori
studente["età"] = 17 # Aggiorna l'età
studente["classe"] = "4A" # Aggiunge una nuova coppia chiave-valore
# Verifica dell'esistenza di una chiave
if "voto" in studente:
print(studente["voto"])
else:
print("Voto non presente")
# Metodi utili
chiavi = studente.keys() # Oggetto view con le chiavi
valori = studente.values() # Oggetto view con i valori
coppie = studente.items() # Oggetto view con tutte le coppie (chiave, valore)
# Iterazione
for chiave in studente:
print(chiave, ":", studente[chiave])
for chiave, valore in studente.items():
print(chiave, ":", valore)
Set
I set sono collezioni non ordinate di elementi unici e mutabili che possono essere utilizzati per eseguire operazioni insiemistiche.
# Creazione di set
numeri_unici = {1, 2, 3, 4, 5}
altro_set = set([1, 2, 2, 3, 4]) # Crea {1, 2, 3, 4} (i duplicati vengono eliminati)
# Operazioni insiemistiche
unione = numeri_unici | {4, 5, 6} # {1, 2, 3, 4, 5, 6}
intersezione = numeri_unici & {4, 5, 6} # {4, 5}
differenza = numeri_unici - {4, 5} # {1, 2, 3}
# Aggiunta e rimozione di elementi
numeri_unici.add(6) # Aggiunge 6
numeri_unici.remove(1) # Rimuove 1 (genera errore se non presente)
numeri_unici.discard(10) # Prova a rimuovere 10 (non genera errore se non presente)
Conversione tra tipi di dati
Python permette di convertire facilmente tra vari tipi di dati:
# Conversioni di base
stringa_numero = "42"
numero = int(stringa_numero) # 42 (intero)
numero_float = float(stringa_numero) # 42.0 (float)
numero_a_stringa = str(42) # "42" (stringa)
lista_da_stringa = list("ciao") # ['c', 'i', 'a', 'o']
tupla_da_lista = tuple([1, 2, 3]) # (1, 2, 3)
Funzioni e modularità
Definizione e chiamata di funzioni
Le funzioni permettono di organizzare il codice in blocchi riutilizzabili. In Python, le funzioni sono definite utilizzando la parola chiave def
, possono accettare parametri e restituire valori.
# Definizione di una funzione semplice
def saluta():
print("Ciao, benvenuto!")
# Chiamata della funzione
saluta() # Output: Ciao, benvenuto!
# Funzione con parametri
def saluta_persona(nome):
print(f"Ciao {nome}, benvenuto!")
saluta_persona("Marco") # Output: Ciao Marco, benvenuto!
# Funzione con valore di ritorno
def area_rettangolo(base, altezza):
return base * altezza
superficie = area_rettangolo(5, 10) # superficie = 50
Parametri delle funzioni
Python offre diverse opzioni per i parametri:
# Parametri posizionali
def descrivi_persona(nome, età, città):
return f"{nome} ha {età} anni e vive a {città}"
# Parametri con valori predefiniti (default)
def saluto(nome, messaggio="Ciao"):
return f"{messaggio}, {nome}!"
print(saluto("Maria")) # "Ciao, Maria!"
print(saluto("Giovanni", "Buongiorno")) # "Buongiorno, Giovanni!"
# Numero variabile di parametri
def somma(*numeri):
risultato = 0
for n in numeri:
risultato += n
return risultato
print(somma(1, 2)) # 3
print(somma(1, 2, 3, 4)) # 10
# Parametri nominali variabili
def descrivi_studente(**dati):
descrizione = "Studente:\n"
for chiave, valore in dati.items():
descrizione += f"- {chiave}: {valore}\n"
return descrizione
print(descrivi_studente(nome="Alice", età=16, classe="4B"))
Scope delle variabili
In Python, lo scope (ambito di validità) delle variabili determina dove queste sono accessibili:
x = 10 # Variabile globale
def funzione():
y = 5 # Variabile locale
print(x) # Può accedere alla variabile globale x
print(y) # Può accedere alla variabile locale y
funzione()
print(x) # Funziona: x è globale
# print(y) # Errore: y è locale alla funzione
def modifica_globale():
global x # Dichiara che vogliamo usare la x globale
x = 20 # Modifica la x globale
modifica_globale()
print(x) # Output: 20
Importazione e utilizzo di moduli
I moduli sono file Python che contengono definizioni e istruzioni. Permettono di organizzare il codice in parti logiche riutilizzabili:
# Importare un intero modulo
import math
print(math.pi) # 3.141592653589793
print(math.sqrt(16)) # 4.0
# Importare specifiche funzioni/oggetti
from math import pi, sqrt
print(pi) # 3.141592653589793
print(sqrt(16)) # 4.0
# Importare con alias
import math as m
print(m.pi) # 3.141592653589793
# Importare tutte le definizioni (da usare con cautela)
from math import *
print(sin(pi/2)) # 1.0
Creare moduli personalizzati
Puoi creare i tuoi moduli salvando il codice in un file .py
:
# File: geometria.py
def area_rettangolo(base, altezza):
return base * altezza
def area_cerchio(raggio):
import math
return math.pi * raggio**2
Poi puoi usarlo in un altro file:
# Nel tuo script principale
import geometria
area1 = geometria.area_rettangolo(5, 10) # 50
area2 = geometria.area_cerchio(3) # circa 28.27
Concetti di programmazione applicati alla didattica
Algoritmi e pensiero algoritmico
Un algoritmo è una sequenza finita di istruzioni ben definite per risolvere un problema:
# Algoritmo per calcolare la media di una serie di voti
def calcola_media(voti):
if len(voti) == 0:
return 0
somma = 0
for voto in voti:
somma += voto
return somma / len(voti)
# Esempio di utilizzo in contesto didattico
voti_classe = [7, 8, 6, 9, 7, 8]
media = calcola_media(voti_classe)
print(f"La media della classe è {media}") # La media della classe è 7.5
Strutture di controllo
Le strutture di controllo determinano il flusso di esecuzione di un programma. Sono utilizzate per ripetere un blocco di codice, eseguire una parte di codice solo se una determinata condizione è vera, saltare tra diverse alternative.
Strutture condizionali (if-elif-else)
Strutture condizionali (if-elif-else)
Le strutture condizionali permettono di eseguire un blocco di codice solo se una determinata condizione è vera. Ad esempio, per valutare un voto:
# Valutazione di un voto
def valuta_voto(voto):
if voto >= 9:
return "Eccellente"
elif voto >= 8:
return "Ottimo"
elif voto >= 7:
return "Buono"
elif voto >= 6:
return "Sufficiente"
else:
return "Insufficiente"
# Esempio didattico per insegnare le leggi di Newton
def analizza_oggetto(massa, forza=None, accelerazione=None):
"""Utilizza la seconda legge di Newton: F = m * a"""
if forza is None and accelerazione is not None:
forza = massa * accelerazione
return f"Un oggetto di massa {massa} kg con accelerazione {accelerazione} m/s² subisce una forza di {forza} N"
elif accelerazione is None and forza is not None:
accelerazione = forza / massa
return f"Un oggetto di massa {massa} kg sottoposto a una forza di {forza} N acquisisce un'accelerazione di {accelerazione} m/s²"
else:
return "Fornire o la forza o l'accelerazione, ma non entrambe o nessuna"
Cicli (for e while)
Ciclo for
Il ciclo for si utilizza per ripetere un blocco di codice per ogni elemento di un elenco. Ad esempio, per stampare tutti gli elementi di una lista:
# Ciclo for per calcolare la somma dei primi n numeri
def somma_primi_n(n):
somma = 0
for i in range(1, n+1):
somma += i
return somma
# Calcolo del fattoriale
def fattoriale(n):
if n < 0:
return "Impossibile calcolare il fattoriale di un numero negativo"
risultato = 1
# Approccio iterativo
for i in range(1, n+1):
risultato *= i
return risultato
Ciclo while
Il ciclo while si utilizza per ripetere un blocco di codice finché non venga verificata una condizione. Ad esempio, per calcolare il massimo comun divisore (MCD) tra due numeri:
# Ciclo while per la ricerca del massimo comun divisore (algoritmo di Euclide)
def mcd(a, b):
while b:
a, b = b, a % b
return a
Risoluzione di problemi step-by-step con Python
La programmazione permette di affrontare problemi complessi scomponendoli in passaggi più semplici. In questo modo, il problema viene suddiviso in una serie di passaggi logici che possono essere facilmente compresi e risolti. I problemi più complessi possono essere suddivisi in sottoproblemi più semplici che possono essere risolti indipendentemente e successivamente combinati per ottenere la soluzione finale.
# Esempio: risoluzione di un'equazione di secondo grado
def risolvi_equazione_secondo_grado(a, b, c):
"""Risolve un'equazione nella forma ax² + bx + c = 0"""
# Calcolo del discriminante
delta = b**2 - 4*a*c
# Verifica solubilità e calcolo soluzioni
if delta < 0:
return "L'equazione non ha soluzioni reali"
elif delta == 0:
x = -b / (2*a)
return f"L'equazione ha un'unica soluzione: x = {x}"
else:
x1 = (-b + (delta)**0.5) / (2*a)
x2 = (-b - (delta)**0.5) / (2*a)
return f"L'equazione ha due soluzioni: x₁ = {x1} e x₂ = {x2}"
# Esempio di applicazione
print(risolvi_equazione_secondo_grado(1, -3, 2)) # x₁ = 2 e x₂ = 1
Relazione tra concetti di programmazione e insegnamento delle scienze
La programmazione fornisce strumenti potenti per l'insegnamento delle scienze, come ad esempio:
- La rappresentazione di concetti astratti come funzioni, classi e oggetti
- La simulazione di fenomeni reali come ad esempio il moto uniformemente accelerato
- L'analisi di dati sperimentali e la visualizzazione di risultati
# Esempio: simulazione del moto uniformemente accelerato
def posizione_moto_accelerato(pos_iniziale, vel_iniziale, accelerazione, tempo):
"""
Calcola la posizione di un oggetto in moto uniformemente accelerato
usando l'equazione: x = x₀ + v₀t + (1/2)at²
"""
return pos_iniziale + vel_iniziale * tempo + 0.5 * accelerazione * tempo**2
# Simulazione del movimento
def simula_caduta_libera(altezza_iniziale, durata=10, step=0.5):
"""Simula la caduta libera di un oggetto partendo da un'altezza data"""
g = 9.81 # accelerazione di gravità (m/s²)
print("Tempo (s) | Altezza (m) | Velocità (m/s)")
print("-" * 40)
for t in range(int(durata/step) + 1):
tempo = t * step
altezza = posizione_moto_accelerato(altezza_iniziale, 0, -g, tempo)
velocita = 0 + (-g) * tempo # v = v₀ + at
if altezza <= 0:
print(f"{tempo:.1f} | {0:.2f} | {velocita:.2f}")
print(f"L'oggetto ha toccato il suolo dopo {tempo:.1f} secondi")
break
print(f"{tempo:.1f} | {altezza:.2f} | {velocita:.2f}")
# Esempio di utilizzo
# simula_caduta_libera(100) # Simulazione di caduta da 100m
Generazione di valori casuali
Il modulo random
in Python è utilizzato per generare numeri casuali. In particolare, la funzione random.randint(a, b)
restituisce un numero intero casuale compreso tra a e b (estremi inclusi).
Ad esempio, se si vuole simulare il lancio di un dado a sei facce, si può utilizzare la seguente istruzione:
import random
dado = random.randint(1, 6)
print(dado)
In questo modo, la variabile dado conterrà un numero intero casuale compreso tra 1 e 6.
Il modulo random
utilizza un algoritmo di generazione di numeri casuali che è sufficientemente buono per la maggior parte delle applicazioni, ma non è adatto per applicazioni che richiedono una elevata sicurezza o precisione, come ad esempio la crittografia o la simulazione di eventi fisici.
Esercizi: Mini-progetti di coding
1. Esercizio guidato: Calcolatrice scientifica semplice
import math
def calcolatrice():
print("Calcolatrice Scientifica")
print("Operazioni disponibili:")
print("1. Addizione (+)")
print("2. Sottrazione (-)")
print("3. Moltiplicazione (*)")
print("4. Divisione (/)")
print("5. Potenza (^)")
print("6. Radice quadrata (sqrt)")
print("7. Seno (sin)")
print("8. Coseno (cos)")
print("9. Logaritmo naturale (ln)")
scelta = input("Scegli un'operazione (1-9): ")
if scelta in ['1', '2', '3', '4', '5']:
a = float(input("Inserisci il primo numero: "))
b = float(input("Inserisci il secondo numero: "))
if scelta == '1':
risultato = a + b
operazione = f"{a} + {b}"
elif scelta == '2':
risultato = a - b
operazione = f"{a} - {b}"
elif scelta == '3':
risultato = a * b
operazione = f"{a} * {b}"
elif scelta == '4':
if b == 0:
return "Errore: divisione per zero"
risultato = a / b
operazione = f"{a} / {b}"
elif scelta == '5':
risultato = a ** b
operazione = f"{a} ^ {b}"
elif scelta in ['6', '7', '8', '9']:
a = float(input("Inserisci un numero: "))
if scelta == '6':
if a < 0:
return "Errore: radice di numero negativo"
risultato = math.sqrt(a)
operazione = f"sqrt({a})"
elif scelta == '7':
# Converte in radianti se l'input è in gradi
angolo = math.radians(a)
risultato = math.sin(angolo)
operazione = f"sin({a}°)"
elif scelta == '8':
angolo = math.radians(a)
risultato = math.cos(angolo)
operazione = f"cos({a}°)"
elif scelta == '9':
if a <= 0:
return "Errore: logaritmo di numero non positivo"
risultato = math.log(a)
operazione = f"ln({a})"
else:
return "Scelta non valida"
return f"{operazione} = {risultato}"
# Per eseguire la calcolatrice:
# print(calcolatrice())
Soluzione passo-passo:
- Importiamo il modulo
math
per le funzioni matematiche - Definiamo una funzione
calcolatrice()
che mostra un menu di operazioni - Chiediamo all'utente di scegliere un'operazione numerica
- A seconda dell'operazione scelta, chiediamo uno o due operandi
- Eseguiamo l'operazione matematica selezionata
- Restituiamo il risultato formattato
2. Esercizio semi-guidato: Analisi statistica di una serie di dati
Problema: Crea un programma che calcoli media, mediana, moda, deviazione standard e range di un insieme di valori.
Suggerimenti:
- Usa le liste per memorizzare i dati
- Puoi calcolare la media come somma di tutti i valori diviso il numero di valori
- Per la mediana, ordina la lista e prendi il valore centrale (o la media dei due centrali se la lunghezza è pari)
- Per la moda, conta le occorrenze di ciascun valore e trova quello con conteggio maggiore
- La deviazione standard è la radice della media dei quadrati delle differenze dalla media
def analisi_statistica(dati):
# Controllo input
if not dati:
return "Errore: nessun dato fornito"
# Media
media = sum(dati) / len(dati)
# Mediana
dati_ordinati = sorted(dati)
n = len(dati)
if n % 2 == 0:
mediana = (dati_ordinati[n//2 - 1] + dati_ordinati[n//2]) / 2
else:
mediana = dati_ordinati[n//2]
# Moda (può esserci più di una moda)
conteggi = {}
for valore in dati:
if valore in conteggi:
conteggi[valore] += 1
else:
conteggi[valore] = 1
max_conteggio = max(conteggi.values())
moda = [k for k, v in conteggi.items() if v == max_conteggio]
# Deviazione standard
somma_scarti_quadrati = sum((x - media) ** 2 for x in dati)
deviazione_standard = (somma_scarti_quadrati / n) ** 0.5
# Range (differenza tra massimo e minimo)
range_dati = max(dati) - min(dati)
return {
"media": media,
"mediana": mediana,
"moda": moda if len(moda) < len(dati) else "Nessuna moda significativa",
"deviazione_standard": deviazione_standard,
"range": range_dati,
"minimo": min(dati),
"massimo": max(dati),
"conteggio": len(dati)
}
# Esempio di utilizzo:
# voti = [8, 7, 9, 6, 7, 8, 9, 8, 10, 7]
# risultati = analisi_statistica(voti)
# for chiave, valore in risultati.items():
# print(f"{chiave}: {valore}")
3. Esercizio aperto: Simulatore di lancio di dadi
Problema: Crea un simulatore che lanci un numero specificato di dadi con un numero specificato di facce e analizzi la distribuzione dei risultati.
import random
import matplotlib.pyplot as plt
def lancia_dadi(n_dadi, n_facce, n_lanci):
"""
Simula il lancio di n_dadi dadi con n_facce facce ciascuno per n_lanci volte.
Restituisce un dizionario con le statistiche dei lanci.
"""
# Implementa la tua soluzione qui
pass
# Esempio atteso:
# risultati = lancia_dadi(2, 6, 1000)
# Dovrebbe restituire statistiche su 1000 lanci di 2 dadi a 6 facce
4. Mini-progetto: Convertitore di unità di misura per fisica
Problema: Crea un programma che converta tra diverse unità di misura utili per la fisica (lunghezza, massa, tempo, temperatura, ecc.).
def converti_unita(valore, da_unita, a_unita):
"""
Converte un valore da un'unità di misura a un'altra.
Parametri:
valore -- il valore numerico da convertire
da_unita -- l'unità di misura di partenza (es. "m", "km", "kg", ecc.)
a_unita -- l'unità di misura di arrivo
Restituisce:
Il valore convertito nella nuova unità di misura
"""
# Implementa la tua soluzione qui
pass
# Esempio atteso:
# conversione = converti_unita(1, "km", "m")
# Dovrebbe restituire 1000.0
5. Mini-progetto: Programma per matematica finanziaria
Problema: Crea un semplice programma che calcoli l'interesse composto.
def calcola_interesse_composto(capitale_iniziale, tasso_interesse, anni, versamenti_annuali=0):
"""
Calcola il capitale finale con interesse composto
Parametri:
capitale_iniziale -- la somma iniziale investita
tasso_interesse -- il tasso di interesse annuale (espresso come decimale, es. 0.05 per 5%)
anni -- il numero di anni dell'investimento
versamenti_annuali -- versamenti aggiuntivi annuali (opzionale)
Restituisce:
Il capitale finale dopo gli anni specificati
"""
# Implementa la tua soluzione qui
pass
# Esempio atteso:
# capitale_finale = calcola_interesse_composto(1000, 0.05, 10)
# Dovrebbe restituire circa 1628.89 (1000 × 1.05^10)
Risorse aggiuntive
Documentazione online
Libri consigliati
- "Il Tutorial di Python" di Guido van Rossum
- "Python Crash Course" di Eric Matthes
- "Pensare in Python. Come pensare da informatico" di Allen Downey