Strutture composte 1

Scarica zip esercizi

Naviga file online

In questo foglio vedremo come gestire 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à.

Esercizio - la holding del lusso

ATTENZIONE

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

Una holding del lusso che raggruppa diverse società dispone di un database di managers in forma di lista di dizionari. Ogni manager è rappresentato da un dizionario:

{
    "nome":"Alessandro",
    "cognome": "Borgoloso",
    "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]:
managers_db = [
  {
    "nome":"Alessandro",
    "cognome": "Borgoloso",
    "età": 34,
    "azienda": {
                   "nome": "Aringhe Candite Spa",
                   "settore":"Alimentari"
               }
  },
  {
    "nome":"Matilda",
    "cognome": "Delle Sòle",
    "età": 25,
    "azienda": {
                    "nome": "Calzature Pitonate Srl",
                    "settore":"Abbigliamento"
               }
  },
  {
    "nome":"Alfred",
    "cognome": "Pennyworth",
    "età": 20,
    "azienda": {
                    "nome": "Batworks",
                    "settore":"Abbigliamento"
               }
  },
  {
    "nome":"Arianna",
    "cognome": "Schei",
    "età": 37,
    "azienda": {
                    "nome": "Diamantoni Unlimited",
                    "settore":"Pietre preziose"
               }
  },
  {
    "nome":"Antonione",
    "cognome": "Cannavacci",
    "età": 25,
    "azienda": {
                    "nome": "Aringhe Candite Spa",
                    "settore":"Alimentari"
               }
  },
]

Esercizio - estrai_manager

✪✪ RITORNA i nomi dei manager in una lista

Mostra soluzione
[2]:

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

assert estrai_manager([]) == []

# se non trova db_impiegati, ricordati di eseguire la cella sopra che lo definisce
assert estrai_manager(managers_db) == ['Alessandro', 'Matilda', 'Alfred', 'Arianna', 'Antonione']

Esercizio - 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(managers_db) == ["Aringhe Candite Spa","Calzature Pitonate Srl","Batworks","Diamantoni Unlimited","Aringhe Candite Spa"]

Esercizio - eta_media

✪✪ RITORNA l’età media dei manager di azienda

Mostra soluzione
[4]:

def eta_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(eta_media(managers_db), (34 + 25 + 20 + 37 + 25) / 5)

Esercizio - settori

✪✪ RITORNA i settori di azienda in una lista, SENZA duplicati e ordinati alfabeticamente.

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

assert settori([]) == []
assert settori(managers_db) == ["Abbigliamento", "Alimentari","Pietre preziose"]

Altri esercizi

Esercizio - 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
[6]:
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

Esercizio - 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

Esercizio - 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

Esercizio - sagra

✪✪✪ In occasione di una sagra di paese, le pasticcerie della zona decidono di donare ciascuna una certa quantità di dolci. Ogni pasticceria è rappresentata da un dizionario, contenente come chiavi i nomi dei dolci più la chiave speciale nome che rappresenta il nome della pasticceria stessa (possiamo assumere che tutte le pasticcerie producono gli stessi tipi di dolci):

pasticcerie = [{'babbà':3,
                'bignè':4,
                'zippole':2,
                'nome':'Da Gigi'},
               {'babbà':5,
                'bignè':3,
                'zippole':9,
                'nome':'La Delizia'},
               {'babbà':1,
                'bignè':2,
                'zippole':6,
                'nome':'Gnam gnam'},
               {'babbà':7,
                'bignè':8,
                'zippole':4,
                'nome':'Il Dessert'}]

Data una lista di questi dizionari e una lista di dolci dolci, si vuole produrre come output una NUOVA lista di liste strutturata così:

>>> sagra(pasticcerie, ['babbà', 'bignè', 'zippole'])

[['Nome',      'babbà', 'bignè', 'zippole' ],
 ['Da Gigi',      3,       4,        2     ],
 ['La Delizia',   5,       3,        9     ],
 ['Gnam gnam',    1,       2,        6     ],
 ['Il Dessert',   7,       8,        4     ],
 ['Totali',       16,      17,       21    ]]

avente quindi i totali di ciascuna tipologia di dolce.

Mostra soluzione
[9]:


def sagra(pasticcerie, dolci):
    raise Exception('TODO IMPLEMENT ME !')

from pprint import pprint

dolci1 = ['cornetti']
res1 = sagra([{'nome':'La Patisserie',
               'cornetti':2},
              {'cornetti':5,
                'nome':'La Casa Del Cioccolato'}], dolci1)
assert res1 == [['Nome',                  'cornetti' ],
                ['La Patisserie',              2     ],
                ['La Casa Del Cioccolato',     5     ],
                ['Totali',                     7     ]]
assert dolci1 == ['cornetti'] # verifica che l'input non cambi

pasticcerie2 = [{'babbà':3,
                 'bignè':4,
                 'zippole':2,
                 'nome':'Da Gigi'},
                {'babbà':5,
                 'bignè':3,
                 'zippole':9,
                 'nome':'La Delizia'},
                {'babbà':1,
                 'bignè':2,
                 'zippole':6,
                 'nome':'Gnam gnam'},
                {'babbà':7,
                 'bignè':8,
                 'zippole':4,
                 'nome':'Il Dessert'}]

res2 = sagra(pasticcerie2, ['bignè', 'babbà', 'zippole'])
#pprint(res2, width=43)

assert res2 == [['Nome',     'bignè',  'babbà', 'zippole'],
                ['Da Gigi',     4,        3,       2     ],
                ['La Delizia',  3,        5,       9     ],
                ['Gnam gnam',   2,        1,       6     ],
                ['Il Dessert',  8,        7,       4     ],
                ['Totali',      17,       16,      21    ]]

Esercizio - scambiattori

✪✪✪ Data una lista di film come lista di dizionari, RITORNA una NUOVA lista con NUOVI dizionari avente i nomi degli attori maschi scambiati con le femmine.

NOTA: dovi scambiare solo i nomi degli attori, e non puoi prevedere in anticipo come si chiameranno. Sai solo è che ogni dizionario ha esattamente tre chiavi di cui 2 note: titolo e anno.

Esempio:

lista = [
            {'titolo':'Jerry Maguire',
             'anno':1996,
             'Jerry':'Dorothy',},
            {'titolo':'Superman',
             'Kent':'Lois',
             'anno': 1978},
            {'titolo':'The Lord of the Rings',
             'anno': 2001,
             'Aragorn':'Arwen',},
            {'Ron Weasley':'Hermione',
             'titolo': 'Harry Potter and the Deathly Hallows, Part 2',
             'anno': 2011}
]

>>> scambiattori(lista)
[{'titolo': 'Jerry Maguire',
  'anno': 1996,
  'Dorothy': 'Jerry'},
 {'titolo': 'Superman',
 'anno': 1978,
 'Lois': 'Kent'},
 {'titolo': 'The Lord of the Rings',
 'anno': 2001,
 'Arwen': 'Aragorn'},
 {'titolo': 'Harry Potter and the Deathly Hallows, Part 2',
 'anno': 2011,
 'Hermione': 'Ron Weasley',
 }]
Mostra soluzione
[10]:

def scambiattori(films):
    raise Exception('TODO IMPLEMENT ME !')

# INIZIO TEST
l1 = []
assert scambiattori(l1) == []

l2 = [ {'titolo': 'Pretty Woman',
        'anno': 1990,
        'Edward':'Vivian'},
       {'titolo': 'Titanic',
        'anno': 1997,
        'Jack' : 'Rose'}
     ]
orig_film = l2[0]
res2 = scambiattori(l2)
assert res2 == [ {'titolo': 'Pretty Woman',
                   'anno': 1990,
                   'Vivian':'Edward'},
                 {'titolo': 'Titanic',
                  'anno': 1997,
                  'Rose' : 'Jack'}
               ]
assert id(l2) != id(res2)            # deve produrre NUOVA lista
assert id(orig_film) != id(res2[0])  # deve produrre NUOVO dizionario

l3 = [
        {'titolo':'Jerry Maguire',
         'anno':1996,
         'Jerry':'Dorothy',},
        {'titolo':'Superman',
         'Kent':'Lois',
         'anno': 1978},
        {'titolo':'The Lord of the Rings',
         'anno': 2001,
         'Aragorn':'Arwen',},
        {'Ron Weasley':'Hermione',
         'titolo': 'Harry Potter and the Deathly Hallows, Part 2',
         'anno': 2011}
]

assert scambiattori(l3) == [{'titolo': 'Jerry Maguire',
                             'anno': 1996,
                             'Dorothy': 'Jerry'},
                            {'titolo': 'Superman',
                             'anno': 1978,
                             'Lois': 'Kent'},
                            {'titolo': 'The Lord of the Rings',
                             'anno': 2001,
                             'Arwen': 'Aragorn'},
                            {'titolo': 'Harry Potter and the Deathly Hallows, Part 2',
                             'anno': 2011,
                             'Hermione': 'Ron Weasley',
                            }]

Prosegui

Continua con le challenges