Mission 9 : Héritage

Mission 9 : Héritage

1   Description

Suite au succès de votre logiciel de lecture de musique (Mission 8), vous avez décidé d'étendre sa fonctionnalité pour pouvoir lire d'autres types de médias que les chansons (vidéos, livres audio, ...).

Vous disposez pour commencer d'un fichier mission9.py comportant 3 classes:

  1. Duree: représente une durée dans le temps dans le format hh:mm:ss. Usage similaire à la classe du même nom de la Mission 8.
  2. Media: représente un média générique, comme une chanson, un livre audio ou une vidéo qui peut être "joué" pour être écouté, lu ou regardé.
  3. ListeLecture: représente une compilation nommée de médias.

Un fichier de test initial test.py est également fourni. Exécuter ce fichier test affichera l'exemple de liste de lecture suivant:

[#1] Minecraft (4 medias)
01: (00:10:01, Média) 'Tuto installation Minecraft (100% gratuit!!)' par LeCrafteur
02: (00:03:36, Média) 'Sweden' par C418
03: (00:04:24, Média) 'Revenge' par CaptainSparklez
04: (02:36:21, Média) 'Journal d'un noob (tome 1)' par Cube Kid

Vous remarquerez le [#1] au début de l'affichage. Ceci représente l'identifiant unique d'une liste de lecture.

L'objectif est d'étendre la fonctionnalité des Media en créant de nouvelles classes, plus spécialisées, qui en héritent tout en restant utilisables par la classe ListeLecture. L'avantage de cette approche est qu'elle nous permet d'implémenter de nouvelles fonctionnalités pour des cas particuliers de Media, sans pour autant devoir modifier le code de la classe ListeLecture pour supporter celles-ci. C'est un des avantages principaux de la programmation orientée objet.

Votre programme final devrait être capable de générer la playliste suivante:

[#3] Minecraft (4 medias)
01: (00:10:01, Vidéo) 'Tuto installation Minecraft (100% gratuit!!)' par LeCrafteur (720p)
02: (00:03:36, Chanson) 'Sweden' par C418 [Album: Minecraft OST]
03: (00:04:24, Chanson) 'Revenge' par CaptainSparklez (feat. Villageois, Herobrine) [Album: Fallen Kingdoms]
04: (02:36:21, Livre Audio) 'Journal d'un noob (tome 1)' par Cube Kid, édité par 404 Éditions

et l'analyse de tailles de fichiers suivant:

TOTAL : 238.01MB
[120.20MB] Tuto installation Minecraft (100% gratuit!!)
[10.80MB] Sweden
[13.20MB] Revenge
[93.81MB] Journal d'un noob (tome 1)
TOTAL : 238.01MB

2   Étapes

Voici les étapes à suivre.

2.1   Fichiers

Chargez les fichiers mission9.py et test.py et étudiez leurs contenus. Vous disposez des classes et fonctions suivantes:

  • Duree: cette classe représente une durée dans le temps. Elle contient les composantes en heures, minutes et secondes de la durée, une méthode qui calcule cette durée en secondes, ainsi qu'une méthode pour ajouter une durée à une autre.
  • Media: cette classe représente un média générique, ayant un titre, un auteur et une durée. Elle contient également la méthode taille() qui renvoie la taille en méga-octets du média, ainsi qu'une méthode taille_par_seconde(), utilisée par la précédente, qui renvoie la taille en méga-octets par seconde de durée. Cette méthode lève une erreur NotImplementedError par défaut, car elle dépend du type de média et donc devra être réécrite par les classes-filles. Pour finir, elle contient la méthode type_media() qui renvoie un string décrivant le type de média de l'objet. Par défaut ce type sera "Média".
  • ListeLecture: cette classe représente une compilation de Media. Elle a un identifiant unique, un nom, une méthode ajouter(media) pour ajouter un média à la liste de lecture, et une méthode __str__ qui imprime les informations de la playliste de manière formattée.
  • afficher_playliste: une fonction de test de la classe ListeLecture qui imprime la liste de lecture de l'exemple repris ci-dessus.

Vous devrez vous-mêmes créer au moins les deux classes Video et Chanson qui héritent de la classe Media, ainsi que des tests supplémentaires pour tester le bon fonctionnement des nouvelles fonctionnalités. Une classe LivreAudio est fournie pour servir d'exemple.

2.2   La classe LivreAudio

Cette classe représente un livre audio, et est une classe-fille de Media. Dans la méthode __init__, elle prend un argument en plus que celle de Media: editeur représente l'éditeur du livre associé.

La méthode taille_par_seconde() est remplacée par une nouvelle version qui renvoie 0.01, qui est la taille de lecture d'un livre audio par défaut en MB/sec. Observez comment la méthode taille() dans Media fera appel à cette version de la méthode taille_par_seconde(), et non à celle définie au départ dans Media [1]. De même, la méthode type_media() renvoie ici "Livre Audio" au lieu de "Média", et ce changement prend effet quand la méthode __str__() d'un média est appelé.

class LivreAudio(Media):
    """
    Représente un livre audio. En plus des attributs présents dans 'Media',
    'LivreAudio' inclu aussi un attribut représentant l'éditeur du livre.
    """

    def __init__(self, titre, auteur, duree, editeur):
        """
        @pre:  titre est un string
               auteur est un string
               duree est une instance de 'Duree'
               editeur est un string
        @post: un livre audio ayant les propriétés demandées
        """
        super().__init__(titre, auteur, duree)
        self.editeur = editeur

    def taille_par_seconde(self):
        """
        Renvoie la taille de lecture par défaut d'un livre audio
        en méga-octets par seconde
        """
        return 0.01

    def type_media(self):
        """
        Renvoie un string indiquant le type de média
        """
        return "Livre Audio"

    def __str__(self):
        s = super().__str__() + ", édité par " + self.editeur
        return s

Pour une playliste qui ne contient qu'un seul média de type LivreAudio, votre programme pourrait afficher un output comme:

[#2] Livres audio Minecraft (1 medias)
01: (02:36:21, Livre Audio) 'Journal d'un noob (tome 1)' par Cube Kid, édité par 404 Éditions

2.3   La classe Video

  • Au fichier mission9.py, ajoutez une nouvelle classe Video qui hérite de la classe Media. Cette nouvelle classe représente une vidéo que l'on pourrait visionner sur notre logiciel de lecture multimédia.

  • Définissez une méthode d'initialisation avec le titre, l'auteur, la durée et la résolution en paramètre. La résolution est un string qui ne peut prendre que quelques valeurs spécifiques, à savoir '720p', '1080p' ou '4K' (dans l'ordre de fidélité croissant). Une valeur non valable pour la résolution doit lever une ValueError.

  • Re-définissez la méthode taille_par_seconde() afin que chaque seconde de vidéo pèse 0.1 Mo, multiplié par 2, 5 ou 10 selon la résolution choisie.

  • Re-définissez la méthode __str__ afin d'ajouter des informations sur la résolution de la vidéo, en plus des informations déjà fournies dans la même méthode de classe-mère.

  • Dans le fichier test.py, ajoutez des tests pour tester cette nouvelle classe et son utilisation dans une playliste. Par exemple, vérifiez que la ligne correspondant à une vidéo soit affichée comme:

    01: (00:10:01, Vidéo) 'Tuto installation Minecraft (100% gratuit!!)' par LeCrafteur (720p)
    

2.4   La classe Chanson

  • Créez également une nouvelle classe Chanson qui hérite de la classe Media. Cette nouvelle classe représente une chanson, qui peut appartenir à un album et peut avoir d'autres artistes que l'auteur en featuring.

  • Définissez une méthode d'initialisation avec le titre, l'auteur, la durée, l'album (string) et les autres artistes featuring avec l'auteur (liste de strings). L'album a une valeur par défaut de None, et les featuring une liste vide.

  • Re-définissez la méthode taille_par_seconde() afin que chaque seconde pèse 0.05 Mo.

  • Re-définissez la méthode __str__ afin d'ajouter des informations sur l'album et les featurings de la chanson s'il y en a.

  • Dans le fichier test.py, ajoutez des tests pour tester cette nouvelle classe et son utilisation dans une liste de lecture. Par exemple, vérifiez que la ligne correspondant à une vidéo soit affichée comme:

    02: (00:03:36, Chanson) 'Sweden' par C418 [Album: Minecraft OST]
    03: (00:04:24, Chanson) 'Revenge' par CaptainSparklez (feat. Villageois, Herobrine) [Album: Fallen Kingdoms]
    

2.5   Identifiant des listes de lecture

Puisque l'identifiant d'une liste de lecture doit être unique, assurez bien lors de la création d'une instance de ListeLecture que l'identifiant est incrémenté à chaque fois par rapport à la dernière instance créée, ce qui veut dire que la toute première instance de ListeLecture aura comme valeur pour l'attribut id 1, la deuxième 2, la troisième 3 et ainsi de suite, de sorte que chaque instance ait un identifiant unique.

3   Remise de votre solution

Pour cette mission, vous devez soumettre toutes les classes de votre programme dans un seul fichier mission9.py, vos classes tests dans un fichier test.py, ainsi que votre fichier README.txt qui décrit comment on peut tester votre code.

Votre fichier mission9.py doit contenir les classes Duree, ListeLecture, Media, Video et Chanson.

Votre fichier test.py doit contenir des tests pour chacune des classes et étappes de cette mission, ainsi qu'une série d'instructions à la fin pour lancer tous les tests automatiquement lors de l'exécution du fichier.

L'exécution de votre programme mission9.py doit imprimer une liste de lecture et une analyse de tailles de fichier comme illustré plus haut dans ce document.

You cannot see this exercise because you are currently not logged in. Click here to log in or get a direct access to the exercice on INGInious by following this link.

Footnotes

[1]Ce mécanisme où une méthode définie dans une classe mère peut appeler une méthode implémentée par une classe fille, sera vu plus en détail plus tard.

Page précédente Page suivante