1. Introduzione agli operatori di appartenenza
# -----------------------------------------------
# -----------------------------------------------
# Verificare se un elemento è contenuto in una stringa
# Esempio: controllo se un carattere è presente in un testo
# Verificare se una parola è contenuta in una lista
# Esempio: lista della spesa, controllare presenza elemento
# Verificare se un valore NON è contenuto in una lista
# Esempio: controllo blacklist (not in)
# Membership su tuple
# Dimostrare che funziona anche su tuple (immutabili)
# Membership su dizionario (solo sulle chiavi!)
# Esempio: controllare se una chiave è presente in un inventario
# Membership su dizionario usando valori
# Usare: value in dict.values()
# -----------------------------------------------
# 2. Confronto di tipo con type()
# -----------------------------------------------
# Usare type() per verificare se una variabile è di tipo int
# Esempio: verificare input numerico
# Confronto errato da evitare:
# type(x) == float (accettabile ma meno consigliato)
# mostrare che type() NON considera le sottoclassi
# Esempio: bool è sottoclasse di int → type() è rigido
# -----------------------------------------------
# 3. Confronto di tipo con isinstance()
# -----------------------------------------------
# Usare isinstance(x, int) come metodo preferibile
# isinstance con più tipi contemporaneamente
# Esempio: isinstance(x, (int, float)) per numeri in generale
# isinstance con oggetti personalizzati
# Esempio con classi (base + derivata)
# -----------------------------------------------
# 4. Combina membership e type checking
# -----------------------------------------------
# Verifica che un elemento sia nella lista E che sia di tipo int
# Esempio: lista con input misti, filtrare solo numeri validi
# Verifica che una variabile sia stringa e contenga un carattere specifico
# Esempio: controllo validità username
# -----------------------------------------------
# 5. Not in + type checking
# -----------------------------------------------
# Verificare che un elemento NON appartenga a una lista
# E che sia del tipo corretto prima di aggiungerlo
# Esempio: aggiunta sicura a una rubrica o inventario
# -----------------------------------------------
# 6. Membership in strutture complesse
# -----------------------------------------------
# Membership in liste di tuple (controllo su elementi complessi)
# Membership in liste di dizionari (mostrare perché 'in' è diverso)
# Verificare appartenenza di una chiave dentro una lista di dizionari
# Esempio: prodotto 'id' presente nei record
# -----------------------------------------------
# 7. Controlli utili nella pratica
# -----------------------------------------------
# Input utente: verificare che sia una stringa e NON vuota
# Validazione di password:
# - verificare che sia stringa
# - verificare presenza di caratteri speciali con 'in'
# Validazione elenco:
# Verificare che tutti gli elementi siano numeri (isinstance)
# Utilizzare all() per controllo globale
# -----------------------------------------------
# 8. Errori comuni da mostrare
# -----------------------------------------------
# Usare `x in y` su un numero → errore concettuale
# Esempio: 3 in 5 → non funziona
# Controllo tipo errato:
# type(x) == "str" (sbagliato, confronta con la stringa)
# Confusione tra:
# elemento in dizionario → controlla SOLO le chiavi
# elemento in dizionario.values() → controlla valori