Εργάζεσαι σε μια εταιρεία streaming μουσικής.
Σου έχει ανατεθεί να δημιουργήσεις μια δυνατότητα λίστας αναπαραγωγής για την εφαρμογή αναπαραγωγής μουσικής σου.
Γράψε ένα πρωτότυπο της εφαρμογής αναπαραγωγής μουσικής.
Για το πρωτότυπο, κάθε τραγούδι θα αναπαρίσταται απλά από έναν αριθμό. Δεδομένου ενός εύρους αριθμών (των αναγνωριστικών των τραγουδιών), δημιούργησε μια απλά συνδεδεμένη λίστα.
Δεδομένης μιας απλά συνδεδεμένης λίστας, θα πρέπει να μπορείς να αντιστρέψεις τη λίστα για να παίξεις τα τραγούδια με την αντίθετη σειρά.
Η συνδεδεμένη λίστα είναι μια θεμελιώδης δομή δεδομένων στην επιστήμη των υπολογιστών, που χρησιμοποιείται συχνά στην υλοποίηση άλλων δομών δεδομένων.
Το πιο απλό είδος συνδεδεμένης λίστας είναι η απλά συνδεδεμένη λίστα. Αυτό σημαίνει ότι κάθε στοιχείο (ή "κόμβος") περιέχει δεδομένα, μαζί με κάτι που δείχνει στον επόμενο κόμβο της λίστας.
Αν θέλεις να εμβαθύνεις στις συνδεδεμένες λίστες, ρίξε μια ματιά σε αυτό το άρθρο που τις εξηγεί με ωραία σχέδια.
Ενώ οι stacks και οι queues μπορούν να υλοποιηθούν χρησιμοποιώντας lists, collections.deque, queue.LifoQueue και multiprocessing.Queue, αυτή η άσκηση απαιτεί μια "Τελευταίο μέσα, πρώτο έξω" (LIFO) στοίβα που χρησιμοποιεί μια δικής σου κατασκευής απλά συνδεδεμένη λίστα:
Αυτό δεν πρέπει να το συγχέεις με μια LIFO στοίβα που χρησιμοποιεί δυναμικό πίνακα ή λίστα, η οποία μπορεί να χρησιμοποιεί από κάτω ένα list, queue ή array.
Οι stacks που βασίζονται σε δυναμικό πίνακα έχουν διαφορετική θέση του head και διαφορετική πολυπλοκότητα χρόνου (Big-O) και αποτύπωμα μνήμης.
Δες αυτές τις δύο ερωτήσεις στο Stack Overflow για μερικά πράγματα που αξίζει να σκεφτείς: Στοίβες και ουρές βασισμένες σε πίνακα έναντι βασισμένες σε λίστα και Διαφορές ανάμεσα σε στοίβα με πίνακα, στοίβα με συνδεδεμένη λίστα και στοίβα.
Για περισσότερες λεπτομέρειες σχετικά με τις συνδεδεμένες λίστες, τις στοίβες LIFO και άλλους αφηρημένους τύπους δεδομένων (ADT) στην Python:
ADT, όχι μόνο συνδεδεμένες λίστες)Η "κανονική" υλοποίηση μιας συνδεδεμένης λίστας στην Python απαιτεί συνήθως μία ή περισσότερες classes.
Για μια καλή εισαγωγή στις classes, δες το classes και τη συνοδευτική άσκηση ellens-alien-game, ή την ενότητα για τις κλάσεις του επίσημου οδηγού της Python.
Τα τεστ αυτής της άσκησης θα καλούν τη len() στο LinkedList σου.
Για να δουλέψει η len(), θα χρειαστεί να δημιουργήσεις μια ειδική μέθοδο __len__.
Για λεπτομέρειες σχετικά με την υλοποίηση ειδικών μεθόδων ή μεθόδων "dunder" στην Python, δες Python Docs: Προσαρμογή βασικών αντικειμένων και Python Docs: object.len(self).
Για να μπορείς να διατρέχεις ή να αντιστρέφεις το LinkedList σου, θα χρειαστεί να υλοποιήσεις την ειδική μέθοδο __iter__.
Δες την υλοποίηση ενός επαναλήπτη για μια κλάση για λεπτομέρειες υλοποίησης.
Μερικές φορές είναι απαραίτητο και να προσαρμόσεις και να raise εξαιρέσεις στον κώδικά σου.
Όταν το κάνεις αυτό, θα πρέπει πάντα να συμπεριλαμβάνεις ένα κατατοπιστικό μήνυμα σφάλματος που να δείχνει ποια είναι η πηγή του σφάλματος.
Αυτό κάνει τον κώδικά σου πιο ευανάγνωστο και βοηθάει σημαντικά στο debugging.
Οι προσαρμοσμένες εξαιρέσεις μπορούν να δημιουργηθούν μέσω νέων κλάσεων εξαιρέσεων (δες τις classes για περισσότερες λεπτομέρειες) που συνήθως είναι υποκλάσεις της Exception.
Σε περιπτώσεις όπου ξέρεις ότι η πηγή του σφάλματος θα είναι παράγωγο ενός συγκεκριμένου τύπου εξαίρεσης, μπορείς να επιλέξεις να κληρονομήσεις από έναν από τους built in error types κάτω από την κλάση Exception.
Όταν πετάς το σφάλμα, θα πρέπει και πάλι να συμπεριλαμβάνεις ένα κατατοπιστικό μήνυμα.
Αυτή η συγκεκριμένη άσκηση απαιτεί να δημιουργήσεις μια προσαρμοσμένη εξαίρεση που να πετιέται/"ρίχνεται" όταν η συνδεδεμένη λίστα σου είναι άδεια.
Τα τεστ θα περάσουν μόνο αν προσαρμόσεις τις κατάλληλες εξαιρέσεις, τις πετάξεις με raise και συμπεριλάβεις τα κατάλληλα μηνύματα σφάλματος.
Για να προσαρμόσεις μια γενική εξαίρεση, δημιούργησε μια class που κληρονομεί από την Exception.
Όταν πετάς την προσαρμοσμένη εξαίρεση με ένα μήνυμα, γράψε το μήνυμα ως όρισμα στον τύπο 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.")
Γράψου στο Exercism για να μάθεις και να κατακτήσεις Python με 17 έννοιες146 ασκήσεις και πραγματική καθοδήγηση από ανθρώπους, όλα δωρεάν.