Lors de cette dernière mission, vous allez revenir une dernière fois vers votre logiciel de lecture multimédia. Une des fonctionnalités les plus demandées est la capacité de trier ses listes de lecture selon différents critères, comme la durée, l'ordre alphabétique de l'auteur, du média ou de l'album, etc. Dans cette mission vous allez implémenter cette fonctionnalité en utilisant une liste chaînée ordonnée (ordered linked list).
Vous trouverez sur INGInious une grande partie du code nécessaire, sauf la classe OrderedLinkedList que vous devez produire, ainsi qu'une nouvelle implémentation de ListeLecture nommée ListeLectureOrdonnee. Vous devez également écrire des fichiers de test détaillées (TestOrderedLinkedList.py et TestListeLectureOrdonnee.py) en utilisant des assert pour vérifier votre implémentation de ces classes. Des fichiers de test TestMedia.py et TestListeLecture.py pour tester, respectivement, l'implémentation des classes Media et ListeLecture, vous sont fournis comme exemple.
En plus de ces fichiers de tests et le code des classes Duree, Media et ListeLecture, vous aurez également accès à une implémentation complète de la classe LinkedList et son fichier de test TestLinkedList.py. Vous pouvez vous baser sur cette implémentation de la classe LinkedList pour implémenter la classe OrderedLinkedList.
Voici les étapes à suivre.
Pour commencer, vous avez à votre disposition les fichiers suivants:
Lisez bien le code fourni dans ces fichiers pour bien comprendre sa structure et son comportement.
Dans un premier temps, adaptez la classe ListeLecture afin qu'elle utilise une liste chainée LinkedList comme structure de données plutôt qu'une simple liste Python. Cette étape vous facilitera le travail pour après implémenter une classe ListeLectureOrdonnee qui utilse une liste chainée ordonnée OrderedLinkedList comme structure de données.
Une liste chaînée ordonnée fonctionne exactement comme une liste chaînée ordinaire, sauf qu'au lieu d'insérer les éléments au début, il faut les insérer de sorte qu'un certain ordre soit respecté.
Pour l'implémentation de votre OrderedLinkedList, basez-vous sur la classe LinkedList qui vous est fournie, et étendez-la si nécessaire de sorte qu'elle puisse répondre à tous vos besoins dans l'implémentation de ListeLectureOrdonnee. Il faudra donc au minimum les méthodes suivantes :
class OrderedLinkedList: def __init__(self, lst=[]): """ Initialises a new linked list object, with a given list of elements lst. @pre: - @post: A new ordered linked list object has been initialised. Its length is equal to the number of elements in lst. The data elements stored in the linked list's nodes correspond to those of the list lst, and appear in the same order as in that list. If no list lst is passed as argument, the newly created linked list will have 0 length, contain no nodes and its head will point to None. """ pass def size(self): """ Accessor method which returns the number of nodes contained in this ordered linked list. @pre: - @post: Returns the number of nodes (possibly zero) contained in this ordered linked list. """ pass def add(self, cargo): """ Adds a new Node with given cargo to the ordered linked list such that the order is maintained @pre: self is a (possibly empty) LinkedList. @post: A new Node object is created with the given cargo. This new Node is added to the ordered linked list in an ordered manner. The length counter has been incremented by 1. """ pass def remove(self, cargo): """ Removes the first node with a given cargo from the list. Leaves the list intact if already empty or if a node with that cargo doesn't exist. """ pass
Ensuite, créez un fichier de tests TestOrderedLinkedList.py afin de tester le bon fonctionnement de votre implémentation.
Cette classe est déjà presque complète, mais afin de pouvoir mettre des médias "dans l'ordre", il faut définir les critères selon lequel on établit cet ordre.
Vous devez choisir un critère au choix (durée, taille, titre, artiste, etc.) et ensuite implémenter la méthode magique __lt__ (pour 'less than') ou __gt__ (pour 'greater than') dans la classe Media afin de pouvoir comparer différentes instances de celle-ci à l'aide de l'opérateur usuel < (ou >). Tout comme la méthode __eq__ permet d'utiliser l'opérateur == sur des objets des classes créée par vous, les méthodes magiques __lt__ et __gt__ vous permettent d'utiliser < et > respectivement. L'implémentation se fait suivant le pseudo code suivant :
def __lt__(self, other) : if not isinstance(other, Media) : return False return [self plus petit que other]
Bien évidemment, ce que signifie "self plus petit (/plus grand) que other" est à vous de déterminer.
Il peut être utile de compléter le tests dans le fichier TestMedia.py afin de vérifier que l'implémentation de l'ordre est correcte.
Cette classe doit implémenter les mêmes méthodes que ListeLecture, mais en utilisant une liste chaînée ordonnée à la place d'une liste python classique. À savoir:
class ListeLectureOrdonnee: """ @pre: name est un string id est un entier @post: une instance de 'ListeLecture' ayant un identifiant unique. """ def __init__(self, name, id) : pass """ Ajoute 'media' à la liste de lecture @pre: media est une instance de 'Media' @post: la liste de lecture comprend maintenant 'media' """ def ajouter(self, media) : pass """ Retire 'media' la première occurence de 'media' à la liste de lecture @pre: media est une instance de 'Media' @post: la première instance de 'media' dans la liste de lecture a été supprimé """ def retirer(self, media) : pass """Renvoie le nombre de medias dans liste""" def nombre_de_medias(self) : pass """ Renvoie un string avec une description de la liste et tous ses éléments. """ def __str__(self) : pass
Ensuite, créez un fichier de tests TestListeLectureOrdonnee.py comme précédémment.
Vous remarquerez sans doute que dans le code final, certaines classes ont des méthodes très similaires à d'autres. (Par exemple les classes OrderedLinkedList et LinkedList, ou les classes ListeLectureOrdonnee et ListeLecture.) Pour entrainer votre intuition pour l'examen, nous vous proposons d'essayer de faire hériter certaines classes d'autres classes existantes. Votre implémentation sera bien évidemment corrigée par votre tuteur·trice. En particulier réfléchissez si les classes ListeLectureOrdonnee ou OrderedLinkedList peuvent être implémentées en utilisant l'héritage.