Lavori per un'azienda di streaming musicale.
Il tuo compito è creare una funzionalità playlist per l'applicazione di riproduzione musicale.
Scrivi un prototipo dell'applicazione del lettore musicale.
Per il prototipo, ogni brano sarà semplicemente rappresentato da un numero. Dato un intervallo di numeri (gli ID dei brani), crea una lista concatenata semplice.
Data una lista concatenata semplice, dovresti poter invertire la lista per riprodurre i brani in ordine inverso.
La lista concatenata è una struttura dati fondamentale dell'informatica, spesso usata per implementare altre strutture dati.
La versione più elementare è la lista concatenata semplice. Questo significa che ogni elemento (o «nodo») contiene dei dati, insieme a qualcosa che punta al nodo successivo della lista.
Se vuoi approfondire le liste concatenate, dai un'occhiata a questo articolo che lo spiega con dei bei disegni.
Mentre stacks e queues possono essere implementati usando lists, collections.deque, queue.LifoQueue e multiprocessing.Queue, questo esercizio richiede uno stack «Last in, First Out» (LIFO) che usa una lista concatenata singola fatta su misura:
Non va confuso con uno stack LIFO che usa un array dinamico o una lista, che sotto può usare una list, una queue o un array.
Gli stacks basati su array dinamici hanno una posizione di head diversa, una diversa complessità temporale (Big-O) e un diverso consumo di memoria.
Dai un'occhiata a queste due domande su Stack Overflow per alcune considerazioni: Array-Based vs List-Based Stacks and Queues e Differences between Array Stack, Linked Stack, and Stack.
Per maggiori dettagli sulle liste concatenate, sugli stack LIFO e su altri tipi di dati astratti (ADT) in Python:
ADT, non solo le liste concatenate)L'implementazione «canonica» di una lista concatenata in Python di solito richiede una o più classes.
Per una buona introduzione alle classes, vedi classes e l'esercizio abbinato ellens-alien-game, oppure Class section of the Official Python Tutorial.
I test di questo esercizio chiameranno len() sulla LinkedList.
Perché len() funzioni, dovrai creare un metodo speciale __len__.
Per i dettagli su come implementare i metodi speciali o "dunder" in Python, vedi Python Docs: Basic Object Customization e Python Docs: object.len(self).
Per poter scorrere o invertire la LinkedList, dovrai implementare il metodo speciale __iter__.
Vedi implementing an iterator for a class per i dettagli di implementazione.
A volte è necessario sia personalizzare sia raise le eccezioni nel codice.
Quando lo fai, includi sempre un messaggio di errore significativo che indichi qual è l'origine dell'errore.
Questo rende il codice più leggibile e aiuta molto nel debug.
Le eccezioni personalizzate si possono creare tramite nuove classi di eccezione (vedi classes per maggiori dettagli) che sono in genere sottoclassi di Exception.
Nei casi in cui sai che l'origine dell'errore sarà una derivazione di un certo tipo di eccezione, puoi scegliere di ereditare da uno dei built in error types sotto la classe Exception.
Quando sollevi l'errore, includi comunque un messaggio significativo.
Questo particolare esercizio richiede di creare un'eccezione personalizzata da sollevare/«lanciare» quando la lista concatenata è vuota.
I test passeranno solo se personalizzi le eccezioni appropriate, raise quelle eccezioni e includi messaggi di errore appropriati.
Per personalizzare un'eccezione generica, crea una class che eredita da Exception.
Quando sollevi l'eccezione personalizzata con un messaggio, scrivi il messaggio come argomento del tipo exception:
# subclassing Exception to create EmptyListException
class EmptyListException(Exception):
"""Exception raised when the linked list is empty.
message: explanation of the error.
"""
def __init__(self, message):
self.message = message
# raising an EmptyListException
raise EmptyListException("The list is empty.")
Iscriviti a Exercism per imparare e padroneggiare Python con 17 concetti146 esercizi e il mentoring di persone reali, tutto gratis.