Skip to content

Progetti

Progetti — Percorso di Apprendimento Python

Section titled “Progetti — Percorso di Apprendimento Python”

Corso: Junior Python Developer (14 settimane) Difficoltà: Principiante → Intermedio → Avanzato


Settimana 1 | Difficoltà: Principiante

  • Sintassi e struttura di Python
  • Variabili e tipi di dati base
  • Input e output utente
  • Operazioni aritmetiche base
  • Esecuzione di script Python
  • Come utente, voglio eseguire il programma e vedere un messaggio di benvenuto
  • Come utente, voglio inserire due numeri
  • Come utente, voglio scegliere un’operazione (addizione, sottrazione, moltiplicazione, divisione)
  • Come utente, voglio vedere il risultato del calcolo
  • Come utente, voglio poter fare più calcoli senza riavviare
  • Mostrare un menu con le scelte delle operazioni
  • Gestire input non validi (lettere invece di numeri)
  • Permettere all’utente di uscire dal programma
  • Mostrare i risultati con formattazione chiara
=== Calcolatrice Semplice ===
Inserisci il primo numero: 10
Inserisci il secondo numero: 5
Scegli l'operazione:
1. Addizione
2. Sottrazione
3. Moltiplicazione
4. Divisione
Scelta: 1
Risultato: 10 + 5 = 15
Vuoi continuare? (s/n): n
Arrivederci!
  • Aggiungere elevazione a potenza e radice quadrata
  • Mantenere una cronologia dei calcoli
  • Aggiungere validazione numeri (solo positivi)

Progetto 2 — Gestore Informazioni Personali

Section titled “Progetto 2 — Gestore Informazioni Personali”

Settimana 2 | Difficoltà: Principiante

  • Convenzioni di nomenclatura variabili
  • Manipolazione e formattazione stringhe
  • Conversione tra tipi
  • Metodi per stringhe
  • Scope variabili locali e globali
  • Come utente, voglio inserire i miei dati personali (nome, età, città, email)
  • Come utente, voglio vedere le mie informazioni in una scheda formattata
  • Come utente, voglio aggiornare un campo specifico
  • Come utente, voglio vedere quanti caratteri ha ogni campo
  • Come utente, voglio validare il formato della mia email
  • Usare f-string o .format() per l’output
  • Validare che l’email contenga @ e .
  • Mostrare il conteggio caratteri per ogni campo
  • Dimostrare variabili locali e globali
  • Permettere aggiornamenti parziali ai campi
=== Gestore Informazioni Personali ===
Inserisci il tuo nome: Marco Rossi
Inserisci la tua età: 17
Inserisci la tua città: Milano
Inserisci la tua email: marco@email.com
--- La Tua Scheda ---
Nome: Marco Rossi (11 caratteri)
Età: 17
Città: Milano (6 caratteri)
Email: marco@email.com (✓ valida)
Cosa vuoi aggiornare?
1. Nome 2. Età 3. Città 4. Email 5. Esci
Scelta: 5
Arrivederci!
  • Salvare le info in una stringa per esportazione
  • Aggiungere compleanno e calcolare segno zodiacale
  • Formattare output come struttura JSON

Settimana 3 | Difficoltà: Principiante

  • Istruzioni condizionali (if/elif/else)
  • Cicli while per loop di gioco
  • Cicli for con range
  • Operatori di confronto
  • Generazione di numeri casuali
  • Break e continue
  • Come utente, voglio giocare indovinando un numero tra 1 e 100
  • Come utente, voglio suggerimenti “troppo alto” o “troppo basso”
  • Come utente, voglio vedere quanti tentativi ho fatto
  • Come utente, voglio scegliere il livello di difficoltà (facile/medio/difficile)
  • Come utente, voglio vedere il mio record nella sessione
  • Usare while loop per il ciclo di gioco principale
  • Usare if/elif per i messaggi di feedback
  • Tenere traccia del numero di tentativi
  • Implementare 3 livelli di difficoltà (diversi intervalli o tentativi max)
  • Salvare e mostrare il miglior punteggio della sessione
=== Indovina il Numero ===
Seleziona difficoltà:
1. Facile (1-50, tentativi illimitati)
2. Medio (1-100, 10 tentativi)
3. Difficile (1-200, 7 tentativi)
Scelta: 2
Sto pensando a un numero tra 1 e 100...
Tentativo 1: 50 → Troppo alto!
Tentativo 2: 25 → Troppo basso!
Tentativo 3: 37 → Troppo basso!
Tentativo 4: 42 → Corretto! 🎉
Hai indovinato in 4 tentativi!
Vuoi giocare ancora? (s/n): n
Miglior punteggio: 4 tentativi (Medio)
Arrivederci!
  • Aggiungere timer con il modulo time
  • Aggiungere classifica dei punteggi
  • Dare indizi come “molto vicino!” quando si è a meno di 5 numeri

Settimana 4 | Difficoltà: Intermedio

  • Liste e metodi delle liste
  • Dizionari per dati strutturati
  • Tuple per dati immutabili
  • Set per collezioni uniche
  • List comprehension
  • Strutture dati annidate
  • Come utente, voglio aggiungere studenti con materie e voti
  • Come utente, voglio vedere tutti gli studenti e la loro media
  • Come utente, voglio trovare lo studente con la media più alta
  • Come utente, voglio vedere quali materie sono seguite (set materie uniche)
  • Come utente, voglio filtrare gli studenti insufficienti (voto < 60)
  • Come utente, voglio aggiornare o eliminare un record studente
  • Usare dizionario con nomi studenti come chiavi e dict annidati come valori
  • Usare una lista di voti per ogni materia
  • Usare un set per tracciare le materie uniche
  • Usare list comprehension per filtrare studenti insufficienti
  • Usare tuple per record voto immutabili (materia, voto)
studenti = {
"Alice": {"Matematica": [85, 90], "Scienze": [78, 82], "Italiano": [92]},
"Bob": {"Matematica": [45, 55], "Scienze": [60]},
"Carlo": {"Matematica": [95], "Italiano": [88, 91]}
}
  • Calcolare medie ponderate
  • Esportare report come file di testo
  • Aggiungere tracciamento presenze come set di date

Progetto 5 — Libreria Strumenti Matematici

Section titled “Progetto 5 — Libreria Strumenti Matematici”

Settimana 5 | Difficoltà: Intermedio

  • Definire funzioni con parametri
  • Return con valori singoli e multipli
  • Funzioni lambda
  • Ricorsione
  • Pattern if __name__ == "__main__"
  • Documentazione funzioni (docstring)
  • Come utente, voglio calcolare il fattoriale di un numero (ricorsivo)
  • Come utente, voglio generare la sequenza di Fibonacci (ricorsivo)
  • Come utente, voglio verificare se un numero è primo
  • Come utente, voglio trovare il MCD di due numeri
  • Come utente, voglio ordinare numeri con un comparatore lambda
  • Come utente, voglio usare lambda per filtrare numeri pari/dispari
  • Come utente, voglio vedere la documentazione delle funzioni
  • Almeno 2 funzioni ricorsive (fattoriale, fibonacci)
  • Almeno 2 funzioni normali con docstring
  • Almeno 2 lambda expressions usate
  • Usare if __name__ == "__main__" come guardia
  • Creare un menu interattivo pulito
def fattoriale(n):
"""Calcola il fattoriale di n in modo ricorsivo."""
if n <= 1:
return 1
return n * fattoriale(n - 1)
def fibonacci(n):
"""Restituisce l'n-esimo numero di Fibonacci in modo ricorsivo."""
if n <= 1:
return n
return fibonacci(n-1) + fibonacci(n-2)
# Lambda esempi
è_pari = lambda x: x % 2 == 0
ordina_per_secondo = lambda items: sorted(items, key=lambda x: x[1])
  • Aggiungere memoizzazione per funzioni ricorsive
  • Calcolare costanti matematiche (approssimazione pi)
  • Aggiungere funzione grafico (testuale)

Progetto 6 — Mid-Term: Sistema Gestione Studenti

Section titled “Progetto 6 — Mid-Term: Sistema Gestione Studenti”

Settimana 6 | Difficoltà: Intermedio

  • Tutti i concetti delle settimane 1-5
  • Progettazione e modularizzazione programma
  • Persistenza dati (salvataggio/caricamento file)
  • Progettazione interfaccia utente
  • Come utente, voglio aggiungere nuovi studenti con nome, ID, classe e voti
  • Come utente, voglio vedere la lista di tutti gli studenti
  • Come utente, voglio cercare uno studente per nome o ID
  • Come utente, voglio aggiornare o eliminare record studenti
  • Come utente, voglio calcolare statistiche (media classe, miglior studente, insufficienti)
  • Come utente, voglio salvare tutti i dati su file e caricarli all’avvio
  • Come utente, voglio vedere una pagella formattata per ogni studente
  • Struttura modulare: funzioni separate per ogni funzionalità
  • Persistenza file (JSON o formato testo personalizzato)
  • Validazione input per tutti gli input utente
  • Funzionalità di ricerca (per nome o ID)
  • Dashboard statistiche
  • Menu interattivo pulito
  • Gestione errori per operazioni file
studente = {
"id": "2024001",
"nome": "Alice Bianchi",
"classe": "3A INF",
"voti": {"Matematica": 85, "Scienze": 78, "Italiano": 92, "Storia": 88},
"assenze": 95.0 # percentuale
}
  • Ordinare studenti per media voto
  • Aggiungere tracciamento assenze
  • Generare pagella in formato PDF testuale

Settimana 7 | Difficoltà: Intermedio

  • Operazioni di lettura/scrittura file
  • Gestione eccezioni (try/except/finally)
  • Tipi di errore e loro gestione
  • Assert per validazione
  • Serializzazione dati
  • Come utente, voglio aggiungere un nuovo contatto (nome, telefono, email, indirizzo)
  • Come utente, voglio vedere tutti i contatti
  • Come utente, voglio cercare contatti per nome
  • Come utente, voglio aggiornare o eliminare un contatto
  • Come utente, voglio che i miei contatti siano salvati su file in modo persistente
  • Come utente, voglio messaggi di errore chiari se il file è mancante o corrotto
  • Come utente, non voglio poter aggiungere numeri o email non validi
  • Salvare contatti su file (JSON o CSV)
  • Caricare contatti dal file all’avvio
  • Gestire FileNotFoundError correttamente
  • Gestire errori di decodifica JSON (file corrotto)
  • Validare numero telefono (almeno 10 cifre)
  • Validare email (deve contenere @ e .)
  • Usare assert per validazione interna
  • Usare try/except/finally per operazioni file
def valida_email(email):
assert "@" in email, "L'email deve contenere @"
assert "." in email.split("@")[1], "L'email deve avere un dominio"
return True
def valida_telefono(telefono):
try:
tel_int = int(telefono.replace(" ", "").replace("-", ""))
assert len(str(tel_int)) >= 10
except (ValueError, AssertionError):
raise ValueError("Formato numero di telefono non valido")
  • Importare/esportare contatti come CSV
  • Aggiungere contatti preferiti
  • Aggiungere categorie (amici, famiglia, lavoro)

Progetto 8 — Sistema Gestione Biblioteca

Section titled “Progetto 8 — Sistema Gestione Biblioteca”

Settimana 8 | Difficoltà: Intermedio

  • Definizione classi e creazione oggetti
  • Attributi e metodi di istanza
  • Attributi e metodi di classe
  • Ereditarietà (classi base e derivate)
  • Metodi magici (__init__, __str__, __repr__, __eq__, __lt__)
  • Basi di incapsulamento
  • Come bibliotecario, voglio aggiungere nuovi libri (titolo, autore, ISBN, anno)
  • Come bibliotecario, voglio registrare nuovi membri
  • Come membro, voglio prendere in prestito un libro
  • Come membro, voglio restituire un libro
  • Come bibliotecario, voglio vedere quali libri sono disponibili
  • Come membro, voglio vedere i miei libri presi in prestito
  • Come bibliotecario, voglio cercare libri per titolo o autore
  • Come utente, voglio confrontare libri per anno usando metodi magici
class LibraryItem:
"""Classe base per tutti gli elementi della biblioteca."""
total_items = 0 # attributo di classe
def __init__(self, titolo, anno):
self.titolo = titolo
self.anno = anno
self._id = LibraryItem.total_items
LibraryItem.total_items += 1
def __str__(self):
return f"{self.titolo} ({self.anno})"
class Book(LibraryItem):
def __init__(self, titolo, autore, isbn, anno):
super().__init__(titolo, anno)
self.autore = autore
self.isbn = isbn
self.in_prestito = False
def __eq__(self, other):
return self.isbn == other.isbn
class Membro:
def __init__(self, nome, id_membro):
self.nome = nome
self.id_membro = id_membro
self.libri_in_prestito = []
def prendi_in_prestito(self, libro):
if not libro.in_prestito:
libro.in_prestito = True
self.libri_in_prestito.append(libro)
return True
return False
  • Almeno 3 classi con ereditarietà
  • Almeno 3 metodi magici implementati
  • Un programma principale che dimostri tutte le funzionalità
  • __str__ e __repr__ appropriati per tutte le classi
  • Aggiungere sottoclassi DVD e Rivista
  • Aggiungere calcolo penale per ritardo
  • Implementare lista d’attesa per libri popolari

Settimana 9 | Difficoltà: Intermedio

  • Modificatori public, private e protected
  • Property decorator (@property)
  • Getter e setter
  • Metodi di classe (@classmethod)
  • Metodi statici (@staticmethod)
  • Incapsulamento in pratica
  • Come utente, voglio creare un conto bancario con saldo iniziale
  • Come utente, voglio depositare denaro (con validazione)
  • Come utente, voglio prelevare denaro (con controllo saldo)
  • Come utente, voglio controllare il mio saldo (ma non modificarlo direttamente)
  • Come utente, voglio vedere il mio numero conto (sola lettura)
  • Come amministratore banca, voglio impostare il tasso d’interesse globale (class method)
  • Come utente, voglio vedere gli interessi maturati sul mio conto
  • Come utente, il mio numero conto è generato automaticamente
class ContoBancario:
_nome_banca = "Python National Bank" # protected attributo di classe
__ultimo_conto = 1000 # private attributo di classe
def __init__(self, intestatario, saldo_iniziale=0):
self.intestatario = intestatario
self.__saldo = saldo_iniziale # attributo privato
self.__numero_conto = ContoBancario.__genera_numero_conto()
@property
def saldo(self):
"""Property saldo in sola lettura."""
return self.__saldo
@property
def numero_conto(self):
"""Property numero conto in sola lettura."""
return self.__numero_conto
@saldo.setter
def saldo(self, valore):
"""Setter protetto con validazione."""
if valore < 0:
raise ValueError("Il saldo non può essere negativo")
self.__saldo = valore
@classmethod
def imposta_tasso_interesse(cls, tasso):
cls._tasso_interesse = tasso
@staticmethod
def __genera_numero_conto():
ContoBancario.__ultimo_conto += 1
return f"PY-{ContoBancario.__ultimo_conto}"
@staticmethod
def valida_nome_intestatario(nome):
return len(nome) >= 2 and nome.replace(" ", "").isalpha()
  • Almeno 1 attributo privato con property
  • Almeno 1 metodo di classe (classmethod)
  • Almeno 1 metodo statico (staticmethod)
  • Dimostrare il name mangling
  • Validazione input per tutte le operazioni
  • Storico transazioni
  • Aggiungere sottoclasse ContoRisparmio con saldo minimo
  • Aggiungere storico transazioni
  • Aggiungere trasferimento denaro tra conti

Settimana 10 | Difficoltà: Intermedio

  • Creare e importare moduli personalizzati
  • Attributi modulo e __name__
  • Organizzare codice in pacchetti
  • Usare moduli built-in (math, random, statistics)
  • Usare pip (concettualmente)
  • Come utente, voglio generare un dataset casuale di N numeri
  • Come utente, voglio calcolare media, mediana e moda
  • Come utente, voglio calcolare deviazione standard e varianza
  • Come utente, voglio visualizzare dati come istogramma testuale
  • Come utente, voglio salvare dataset e risultati su file
  • Come utente, voglio caricare un dataset da file
calcolatrice_statistiche/
├── __init__.py
├── main.py # Programma principale
├── generatore_dati.py # Generazione dati casuali
├── calcolatore_stats.py # Calcoli statistici
└── gestore_file.py # Salvataggio/caricamento file
  • Almeno 3 moduli personalizzati
  • if __name__ == "__main__" corretto in ogni modulo
  • Usare modulo math per calcoli avanzati
  • Usare modulo statistics per misure standard
  • Usare modulo random per generazione dati
  • Struttura pacchetto pulita con __init__.py
  • Aggiungere distribuzioni di probabilità (normale, binomiale)
  • Aggiungere coefficiente di correlazione
  • Aggiungere visualizzazione dati con matplotlib (se installato)

Settimana 11 | Difficoltà: Avanzato

  • Decoratori (decoratori personalizzati)
  • Funzioni generatrici con yield
  • Espressioni regolari (modulo re)
  • Modulo collections (Counter, defaultdict, namedtuple)
  • Come utente, voglio caricare un file di log del server
  • Come utente, voglio vedere quante richieste per tipo (GET, POST, ecc.)
  • Come utente, voglio trovare tutti gli IP unici
  • Come utente, voglio vedere i codici di errore più frequenti
  • Come utente, voglio filtrare i log per intervallo di date
  • Come utente, voglio che il decorator registri i tempi di esecuzione delle funzioni
  • Come utente, voglio processare file grandi in modo efficiente (generatori)
import time
from functools import wraps
def logga_tempo_esecuzione(func):
@wraps(func)
def wrapper(*args, **kwargs):
inizio = time.time()
risultato = func(*args, **kwargs)
fine = time.time()
print(f"{func.__name__} eseguito in {fine-inizio:.4f}s")
return risultato
return wrapper
def leggi_righe_log(filepath):
"""Generatore che produce righe di log una alla volta (efficiente in memoria)."""
with open(filepath, 'r') as f:
for riga in f:
yield riga.strip()
import re
pattern_log = r'(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+-\s+\[(.+?)\]\s+"(\w+)\s+(\S+)\s+\S+"\s+(\d{3})\s+(\d+)'
# Gruppi: IP, timestamp, metodo, percorso, status_code, dimensione
  • Almeno 1 decoratore personalizzato
  • Almeno 1 funzione generatrice
  • Almeno 2 pattern regex
  • Usare collections.Counter per analisi frequenze
  • Usare collections.namedtuple per strutture log
  • Processare file di log di esempio in modo efficiente

Generare un file di log fittizio programmaticamente per testare l’analizzatore.

  • Rilevare attività sospette (login falliti multipli)
  • Generare report come file di testo formattato
  • Visualizzare distribuzione richieste come grafico a barre

Progetto 12 — App Note con GUI e Database

Section titled “Progetto 12 — App Note con GUI e Database”

Settimana 12 | Difficoltà: Avanzato

  • Operazioni database SQLite (CRUD)
  • GUI Tkinter base
  • Programmazione event-driven
  • Modulo os per percorsi file
  • Combinare GUI con backend database
  • Come utente, voglio creare una nuova nota con titolo e contenuto
  • Come utente, voglio vedere una lista di tutte le mie note
  • Come utente, voglio cliccare su una nota per visualizzarla/modificarla
  • Come utente, voglio eliminare una nota
  • Come utente, voglio cercare note per titolo o contenuto
  • Come utente, voglio che le mie note siano salvate automaticamente su database
  • Come utente, voglio vedere data di creazione e ultima modifica
  • Database SQLite con almeno una tabella
  • GUI Tkinter con:
    • Listbox o Treeview per lista note
    • Widget Text per contenuto nota
    • Widget Entry per titolo
    • Barra di ricerca
    • Pulsanti: Nuovo, Salva, Elimina
  • Operazioni CRUD sul database
  • Auto-salvataggio alla chiusura
  • Modulo os per percorso file database
CREATE TABLE note (
id INTEGER PRIMARY KEY AUTOINCREMENT,
titolo TEXT NOT NULL,
contenuto TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
+------------------------------------------+
| App Note [_][□][X] |
+------------------------------------------+
| [🔍 Cerca... ] [Nuova] |
+----------------------+-------------------+
| Lista Note | Contenuto Nota |
| | |
| • Lista Spesa | Titolo: [______] |
| • Idee Python | |
| • Piano Progetto | Contenuto: |
| • Appunti Riunione | [ ]|
| | [ ]|
| | [ ]|
| | |
| | [Salva] [Elimina] |
+----------------------+-------------------+
  • Aggiungere tag/categorie alle note
  • Aggiungere formattazione rich text
  • Aggiungere esportazione PDF o file di testo
  • Aggiungere scorciatoie da tastiera

Settimana 13 | Difficoltà: Avanzato

  • Modulo os (walk, listdir, rename, mkdir)
  • Modulo sys (argv per argomenti CLI)
  • Manipolazione percorsi
  • Metadati file (dimensione, data modifica)
  • Parsing argomenti da riga di comando
  • Best practice struttura progetto
  • Come utente, voglio eseguire il tool con una directory target
  • Come utente, voglio organizzare file per estensione (Documenti, Immagini, Codice, ecc.)
  • Come utente, voglio vedere un’anteprima prima di confermare lo spostamento
  • Come utente, voglio usare flag come --dry-run per vedere le modifiche
  • Come utente, voglio usare --reverse per annullare l’organizzazione
  • Come utente, voglio vedere statistiche (file organizzati, dimensione spostata)
  • Come utente, voglio personalizzare le regole di categorizzazione
usage: organizzatore.py [-h] [--dry-run] [--reverse] [--rules RULES] directory
Organizza i file in una directory per categoria.
positional arguments:
directory Directory target da organizzare
optional arguments:
-h, --help Mostra questo messaggio di aiuto
--dry-run Mostra cosa verrebbe spostato senza modificare
--reverse Annulla l'ultima organizzazione (usa file di log)
--rules RULES File JSON con regole personalizzate
CATEGORIE = {
"Immagini": [".jpg", ".jpeg", ".png", ".gif", ".svg", ".bmp"],
"Documenti": [".pdf", ".docx", ".txt", ".md", ".xlsx", ".pptx"],
"Codice": [".py", ".js", ".html", ".css", ".ts", ".java", ".cpp"],
"Archivi": [".zip", ".tar", ".gz", ".rar", ".7z"],
"Audio": [".mp3", ".wav", ".flac", ".aac"],
"Video": [".mp4", ".avi", ".mkv", ".mov"],
"Altri": [] # categoria generica
}
  • Usare sys.argv per parsing argomenti CLI (o argparse)
  • Usare modulo os per operazioni file
  • Implementare modalità --dry-run
  • Implementare undo/reverse con file di log
  • Mostrare progresso durante l’organizzazione
  • Gestire errori (permessi, file mancanti)
  • Aggiungere modalità --watch che monitora una directory
  • Aggiungere deduplicazione file (trovare e rimuovere duplicati)
  • Aggiungere ordinamento per data invece che per tipo

Progetto 14 — Capstone Finale: Portale Voti Scolastico

Section titled “Progetto 14 — Capstone Finale: Portale Voti Scolastico”

Settimana 14 | Difficoltà: Avanzato

  • Tutti i concetti delle settimane 1-13
  • Progettazione e architettura applicazione completa
  • Struttura progetto multi-modulo
  • Gestione errori completa
  • Documentazione utente

Come amministratore (professore):

  • Posso aggiungere, modificare ed eliminare studenti
  • Posso creare classi e assegnare studenti
  • Posso aggiungere compiti ed esami con punteggio massimo
  • Posso valutare studenti e aggiungere commenti
  • Posso vedere statistiche classe (media, distribuzione, migliori/peggiori)
  • Posso generare un report della classe

Come studente:

  • Posso vedere il mio profilo e la mia classe
  • Posso vedere i miei voti per ogni compito/esame
  • Posso vedere la mia media e il voto in lettere
  • Posso vedere la mia posizione in classifica
portale_scolastico/
├── __init__.py
├── main.py # Punto di ingresso
├── modelli/
│ ├── __init__.py
│ ├── persona.py # Classi Persona, Studente, Professore
│ ├── corso.py # Classi Corso, Classe
│ └── voto.py # Classi Compito, Esame, Voto
├── controller/
│ ├── __init__.py
│ ├── controller_studente.py
│ ├── controller_professore.py
│ └── controller_voti.py
├── utils/
│ ├── __init__.py
│ ├── validatori.py # Validazione input (staticmethod)
│ ├── decoratori.py # Decoratori logging, timing
│ └── helper.py # Formattazione, calcoli
├── dati/
│ └── (database o file JSON)
├── requirements.txt
└── README.md
class Persona:
"""Classe base con nome, email, __id."""
class Studente(Persona):
"""Studente con corsi frequentati, voti, calcolo media."""
class Professore(Persona):
"""Professore con corsi assegnati."""
class Corso:
"""Corso con nome, codice, professore, studenti iscritti."""
class Compito:
"""Compito con punteggio max, scadenza, consegne."""
class Voto:
"""Voto con punteggio, commenti, conversione in lettera."""
  • OOP: Almeno 5 classi con ereditarietà e incapsulamento
  • Persistenza dati: Salvare/caricare da JSON o SQLite
  • File I/O: Esportare report come file di testo
  • Gestione eccezioni: Coprire tutti i casi limite
  • Struttura modulare: Almeno 3 pacchetti con __init__.py
  • Funzioni: Ben organizzate con docstring
  • Strutture dati: Liste, dict, set usati appropriatamente
  • Interfaccia CLI: Menu pulito e navigabile
  • README.md: Istruzioni installazione e uso
  • requirements.txt: Dipendenze progetto
CriterioPunti
Organizzazione codice e struttura progetto20
Design OOP (classi, ereditarietà, incapsulamento)20
Funzionalità (tutte le feature funzionano)25
Gestione errori e validazione input15
Qualità codice (docstring, nomi, commenti)10
README e documentazione10
Totale100
  • Aggiungere GUI Tkinter
  • Aggiungere visualizzazione voti (grafici testuali)
  • Aggiungere categorie di voto specifiche per materia
  • Aggiungere sistema di notifiche per nuovi voti
  • Supportare più periodi di valutazione (quadrimestri)