Dizionari - strutture composte

Scarica zip esercizi

Naviga file online

In questo foglio vedremo come gestire una struttura dati più complesse come una liste di dizionari e dizionari di liste, esaminando al contempo il significato di copia in superficie e copia in profondità.

ATTENZIONE: Gli esercizi seguenti richiedono di conoscere:

Se sei alle prime armi con la programmazione, ti conviene saltarli e ripassare in seguito

Che fare

  • scompatta lo zip in una cartella, dovresti ottenere qualcosa del genere:

dictionaries
    dictionaries1.ipynb
    dictionaries1-sol.ipynb
    dictionaries2.ipynb
    dictionaries2-sol.ipynb
    dictionaries3.ipynb
    dictionaries3-sol.ipynb
    dictionaries4.ipynb
    dictionaries4-sol.ipynb
    dictionaries5.ipynb
    dictionaries5-sol.ipynb
    jupman.py

ATTENZIONE: Per essere visualizzato correttamente, il file del notebook DEVE essere nella cartella szippata.

  • apri il Jupyter Notebook da quella cartella. Due cose dovrebbero aprirsi, prima una console e poi un browser. Il browser dovrebbe mostrare una lista di file: naviga la lista e apri il notebook dictionaries4.ipynb

  • Prosegui leggendo il file degli esercizi, ogni tanto al suo interno troverai delle scritte ESERCIZIO, che ti chiederanno di scrivere dei comandi Python nelle celle successive. Gli esercizi sono graduati per difficoltà, da una stellina ✪ a quattro ✪✪✪✪

Scorciatoie da tastiera:

  • Per eseguire il codice Python dentro una cella di Jupyter, premi Control+Invio

  • Per eseguire il codice Python dentro una cella di Jupyter E selezionare la cella seguente, premi Shift+Invio

  • Per eseguire il codice Python dentro una cella di Jupyter E creare una nuova cella subito dopo, premi Alt+Invio

  • Se per caso il Notebook sembra inchiodato, prova a selezionare Kernel -> Restart

Impiegati

ATTENZIONE

Gli esercizi che segueno contengono dei test con gli assert. Per capire come svolgerli, leggi prima Gestione errori e testing

Supponiamo di avere una lista di dizionari che rappresenta un database di impiegati. Ogni impiegato è rappresentato da un dizionario:

{
    "nome":"Mario",
    "cognome": "Rossi",
    "età": 34,
    "azienda": {
                    "nome": "Aringhe Candite Spa",
                    "settore":"Alimentari"
               }
}

Il dizionario ha diversi attributi semplici quali nome, cognome, età. L’attributo azienda è più complesso, perchè è rappresentato come un altro dizionario: `

"azienda": {
        "nome": "Aringhe Candite Spa",
        "settore":"Alimentari"
    }
[1]:
db_impiegati = [
  {
    "nome":"Mario",
    "cognome": "Rossi",
    "età": 34,
    "azienda": {
                   "nome": "Aringhe Candite Spa",
                   "settore":"Alimentari"
               }
  },
  {
    "nome":"Pippo",
    "cognome": "Rossi",
    "età": 20,
    "azienda": {
                    "nome": "Batworks",
                    "settore":"Abbigliamento"
               }
  },
  {
    "nome":"Paolo",
    "cognome": "Bianchi",
    "età": 25,
    "azienda": {
                    "nome": "Aringhe Candite Spa",
                    "settore":"Alimentari"
               }
  }

]

estrai_impiegati

✪✪ RITORNA i nomi degli impiegati in una lista

Mostra soluzione
[2]:

def estrai_impiegati(lista):
    raise Exception('TODO IMPLEMENT ME !')

assert estrai_impiegati([]) == []

# se non trova db_impiegati, ricordati di eseguire la cella sopra che lo definisce
assert estrai_impiegati(db_impiegati) == ['Mario', 'Pippo', 'Paolo']

estrai_aziende

✪✪ RITORNA i nomi di azienda in una lista (i duplicati sono ammessi)

Mostra soluzione
[3]:
def estrai_aziende(lista):
    """RITORNA i nomi di azienda in una lista (i duplicati sono ammessi)
    """
    raise Exception('TODO IMPLEMENT ME !')


assert estrai_aziende([]) == []
# se non trova db_impiegati, ricordati di eseguire la cella sopra che lo definisce
assert estrai_aziende(db_impiegati) == ["Aringhe Candite Spa","Batworks","Aringhe Candite Spa"]

età_media

✪✪ RITORNA l’età media degli impiegati di azienda

Mostra soluzione
[4]:

def età_media(lista):
    raise Exception('TODO IMPLEMENT ME !')


# visto che la funzione ritorna float non si può comparare per numeri esatti ma per numeri vicini
# con funzione math.isclose
import math
assert math.isclose(età_media(db_impiegati), (34 + 20 + 25) / 3)

tipi_aziende

✪✪ RITORNA i tipi (settori) di azienda in una lista, SENZA duplicati !!

Mostra soluzione
[5]:
def tipi_aziende(lista):
    raise Exception('TODO IMPLEMENT ME !')

assert tipi_aziende([]) == []
assert tipi_aziende(db_impiegati) == ["Alimentari", "Abbigliamento"]

Altri esercizi

medie

✪✪ Dato un dizionario strutturato ad albero riguardante i voti di uno studente in classe V e VI, RESTITUIRE un array contente la media di ogni materia

Esempio:

medie([
  {'id' : 1, 'subject' : 'math', 'V' : 70, 'VI' : 82},
  {'id' : 1, 'subject' : 'italian', 'V' : 73, 'VI' : 74},
  {'id' : 1, 'subject' : 'german', 'V' : 75, 'VI' : 86}
])

ritorna

[ (70+82)/2 , (73+74)/2, (75+86)/2 ]

ovvero

[ 76.0 , 73.5, 80.5 ]
Mostra soluzione
[10]:
def medie(lista):
    raise Exception('TODO IMPLEMENT ME !')

# INIZIO TEST - NON TOCCARE !
import math


'''
Verifica che i numeri float in lista1 siano simili a quelli di lista2
'''
def is_list_close(lista1, lista2):
    if len(lista1) != len(lista2):
        return False

    for i in range(len(lista1)):
        if not math.isclose(lista1[i], lista2[i]):
            return False

    return True

assert is_list_close(medie([
                            {'id' : 1, 'subject' : 'math', 'V' : 70, 'VI' : 82},
                            {'id' : 1, 'subject' : 'italian', 'V' : 73, 'VI' : 74},
                            {'id' : 1, 'subject' : 'german', 'V' : 75, 'VI' : 86}
                          ]),
                     [ 76.0 , 73.5, 80.5 ])
# FINE TEST

ha_pref

✪✪ Uno grande magazzino ha un database dei clienti modellato come un dizionario che associa ai nomi dei clienti le loro preferenze riguardo le categorie di articoli che comprano di solito:

{
    'aldo':['cinema', 'musica', 'sport'],
    'giovanni':['musica'],
    'giacomo':['cinema', 'videogiochi']
}

Dato il dizionario, il nome di un cliente e una categoria, scrivere una funzione ha_pref che RITORNA True se quel cliente ha la preferenza indicata, False altrimenti.

Esempio:

ha_pref({
            'aldo':['cinema', 'musica', 'sport'],
            'giovanni':['musica'],
            'giacomo':['cinema', 'videogiochi']

        }, 'aldo', 'musica')

deve ritornare True perchè ad aldo piace la musica, invece

ha_pref({'aldo':['cinema', 'musica', 'sport'],
         'giovanni':['musica'],
         'giacomo':['cinema', 'videogiochi']

        }, 'giacomo', 'sport')

Deve ritornare False perchè a giacomo non piace lo sport

Mostra soluzione
[7]:

def ha_pref(diz, nome, pref):
    raise Exception('TODO IMPLEMENT ME !')

assert ha_pref({}, 'a', 'x') == False
assert ha_pref({'a':[]}, 'a',  'x') == False
assert ha_pref({'a':['x']}, 'a',  'x') == True
assert ha_pref({'a':['x']}, 'b',  'x') == False
assert ha_pref({'a':['x','y']}, 'a',  'y') == True
assert ha_pref({'a':['x','y'],
                   'b':['y','x','z']}, 'b',  'y') == True
assert ha_pref({'aldo':['cinema', 'musica', 'sport'],
                'giovanni':['musica'],
                'giacomo':['cinema', 'videogiochi']
               }, 'aldo', 'musica') == True
assert ha_pref({'aldo':['cinema', 'musica', 'sport'],
                'giovanni':['musica'],
                'giacomo':['cinema', 'videogiochi']
               }, 'giacomo', 'sport') == False

onomat

✪✪ Proviamo ad aggiungere delle espressioni onomatopeiche a delle frasi

INPUT: - frase da arricchire - Il sentimento da usare, che è codificato come un valore numerico. - un dizionario di sentimenti, in cui si associa al codice numerico di ogni sentimento un dizionario contenente un espressione onomatopeica tipica per quel sentimento, e la posizione in cui deve figurare all’interno di una frase. Le posizioni sono indicate come ‘i’ per inizio e ‘f’ per fine.

OUTPUT

  • La frase arricchita con l’espressione onomatopeica scelta in base al sentimento. L’espressione va aggiunta sempre prima o dopo la frase, e sempre separata da uno spazio.

Per esempio

sentimenti = {
                1:  {
                        "espressione": "Gulp!",
                        "posizione": "i"
                    }
                2:  {
                        "espressione": "Sgaragulp !",
                        "posizione": "i"
                    }
                3:  {
                        "espressione": "Uff..",
                        "posizione": "f"
                    }
}


onomat("Ma quelli sono i bassotti!", 1, sentimenti)

Deve tornare

"Gulp! Ma quelli sono i bassotti!"

Mentre

onomat("Non voglio alzarmi dall'amaca.", 3, sentimenti)

Deve tornare

"Non voglio alzarmi dall'amaca. Uff.."

NOTA: Ricordarsi lo spazio tra espressione e frase!

Mostra soluzione
[8]:
def onomat(frase, sentimento, sentimenti):
    raise Exception('TODO IMPLEMENT ME !')


# INIZIO TEST - NON TOCCARE !!!


sentimenti = {
                1:  {
                        "espressione": "Gulp!",
                        "posizione": "i"
                    },
                2:  {
                        "espressione": "Sgaragulp!",
                        "posizione": "i"
                    },
                3:  {
                        "espressione": "Uff..",
                        "posizione": "f"
                    },
                4:  {
                        "espressione": "Yuk yuk!",
                        "posizione": "f"
                    },
                5:  {
                        "espressione": "Sgrunt!",
                        "posizione": "i"
                    },
                6:  {
                        "espressione": "Gasp!",
                        "posizione" : "i"
                    }
            }


assert onomat("Mi chiamo Pippo.", 4, sentimenti) == "Mi chiamo Pippo. Yuk yuk!"
assert onomat("Quel topastro mi ha rovinato un'altra rapina!", 5, sentimenti) == "Sgrunt! Quel topastro mi ha rovinato un'altra rapina!"
assert onomat("Non voglio alzarmi dall'amaca.", 3, sentimenti) == "Non voglio alzarmi dall'amaca. Uff.."

# FINE TEST
[ ]: