Chronos
Prérequis
- structures de contrôle ;
- boucles ;
- tableaux ;
- fonctions ;
- modules ;
- Programmation orientée objet.
Présentation
Vous allez réaliser un programme permettant de dessiner automatiquement une frise chronologique à partir d'une liste d'évènements. Nous allons commencer par une frise simple, puis nous ajouterons des dificultés au fur et à mesure.
Outils
SVG
Nous utiliserons le format SVG (Scalable Vector Graphics) qui permet de faire du dessin vectoriel. L'avantage du SVG est qu'il est au format texte. Il est donc relativement facile de créer un ficher SVG avec un programme : il suffit d'écrire dans un fichier ce que l'on veut dessiner.
Il existe déjà plusieurs bibliothèques pour créer des images SVG à partir de Python : svgwrite ou pysvg. Elles sont complètes mais manquent de simplicité. C'est pourquoi je vous propose d'utiliser svgnsi.py pour ce projet. Cette bibliothèque permet de tracer des lignes, des rectangles, des cercles et d'écrire du texte. Toutes les fonctionnalités sont expliquées dans le code source.
Chronos
Nous utiliserons la programmation orientée objet pour créer notre frise chronologique.
Voici une ébauche du progrmme chronos.py
que vous devrez compléter et améliorer :
from svgnsi import *
class Event:
"""
Évènement défini par un titre, un jour, un moi et une année.
"""
def __init__(self, title, day, month, year):
self.title = title
self.day = day
self.month = month
self.year = year
# Calcul grossier du nombre de jours depuis JC
# Permet de trier chronologiquement les évènements
self.timecode = year*366 + month*31 + day
def display(self):
"""
Renvoie la date et le titre d'un évènement dans une chaîne de caractère.
Exemple : "24 Novembre 2019 : La Fille de Vercingétorix"
"""
pass
class Period:
"""
Période définie par un titre et deux évènements (un pour le début et un pour la fin)
Le titre des évènement n'a pas d'importance.
"""
pass
class Timeline:
"""
Frise chronologique pouvant contenir des évènements et des périodes.
Seulement les énvènements sont traités actuellement.
"""
def __init__(self, name):
self.listEvent = []
self.name = name
def addEvent(self, event):
self.listEvent.append(event)
# On remet la lsite dans l'ordre chronologique
self.listEvent.sort(key=lambda event: event.timecode)
def display(self):
"""
Affiche la liste des évènements et des périodes dans le shell
"""
pass
def minMaxEvent(self):
"""
Renvoie les timecodes du premier et du dernier évènement.
"""
return self.listEvent[0].timecode, self.listEvent[-1].timecode
def toSVG(self):
"""
Dessine la frise en utilisant la bibliothèque svgnsi.
"""
pass
# Création de frise avec quelques BD d'Astérix
timeline = Timeline("asterix")
timeline.addEvent(Event("Astérix le Gaulois", 0, 0, 1961))
timeline.addEvent(Event("La serpe d'or", 0, 0, 1962))
timeline.addEvent(Event("Astérix chez les Pictes", 0, 0, 2013))
timeline.addEvent(Event("La Fille de Vercingétorix",24,10,2019))
timeline.addEvent(Event("Astérix en Corse",0,0,1973))
timeline.addEvent(Event("Le grand fossé",0,0,1980))
timeline.addEvent(Event("Astérix chez les Bretons",0,0,1966))
timeline.addEvent(Event("La galère d'Obélix",0,0,1996))
timeline.addEvent(Event("Le ciel lui tombe sur la tête",0,0,2005))
timeline.addEvent(Event("Astérix chez Rahàzade",0,0,1987))
timeline.addEvent(Event("Astérix gladiateur",0,0,1964))
Travail demandé
Création de Event.display
Créez la méthode display
de la classe Event
.
Cette méthode doit retourner une chaîne de caractères contenant toutes les informations de l'évènement.
Elle doit être lisible par un humain.
Création de Timeline.display
Créez la méthode display
de la classe Timeline
.
Cette méthode doit afficher la liste des évènements de la frise dans le shell.
Création de Timeline.toSVG
Créez la méthode toSVG
de la classe Timeline
.
Cette méthode doit créer une frise en SVG avec tous les évènements.
On pourra les afficher au dessus de la frise légèrement penchés.
Voici un exemple simple d'affichage :
Period
Créez la classe Period
.
Elle permet de définir une période.
Elle doit au moins posséder une méthode __init__
et une méthode display
.
Elle doit également avoir un attribut timecode
correspondant au début de la période pour pouvoir être triée.
Vous pourrez ajouter les périodes des différents scénaristes Goscinny, Uderzo et Ferri.
Création de Timeline.addPeriod
Créez la méthode addPeriod
de la classe Timeline
.
Cette méthode doit ajouter une période à la frise.
Il faudra certainement modifer d'autres méthodes pour prendre en compte cet ajout.
Compléter Timeline.display
Compléter la méthode display
de la classe Timeline
de façon à afficher les périodes.
Compléter Timeline.toSVG
Compléter la méthode toSVG
de la classe Timeline
de façon à afficher les périodes dans le SVG.
On pourra les afficher en dessous de la frise.
Années identiques
Ajouter l'évènement suivant à votre frise :
timeline.addEvent(Event("Le combat des chefs",0,0,1966))
Si cela pose un problème d'affichage sur la frise, trouvez une solution pour que l'affichage soit lisible.
Superposition des périodes
Gérez la superposition des périodes sur la frise en les décalant verticalement. Pour vos tests vous pourrez ajouter les périodes des dessinateurs Uderzo et Conrad.