L'idée m'est venue pendant que nous mations Alien avec ma compagne. Nous nous sommes demandés quel âge pouvait avoir Hélène Ripley et sur quelle période pouvait bien se passer la saga dans son ensemble.
Je n'ai rien trouvé de pertinent donc je m'y suis attelé et voici un petit script sans prétention pour générer une frise chronologique des sagas de films.
Requiert Python 3.6+ et, éventuellement, le module Figlet pour afficher de joli titres.
Le code peut-être amélioré, si cela vous tente → frise sur GitHub.
# frise.py
from typing import Dict, Tuple, List, Union
try:
from pyfiglet import figlet_format
except ImportError:
figlet_format = None
__version__ = '0.0.1'
def frise(
events: Dict[int, Union[str, List[str]]],
title: str='',
length: int=30,
padding: int=0,
style: Tuple[str, str, str]=('|', '•', ' '),
figlet: Dict[str, str]=None,
) -> str:
"""
La frise.
:param dict events: Events, ie: {date1: name1, date2: name2, ...}
:param str title: Title of the time line
:param int length:
:param int padding: Left padding of the time line
:param list style: Characters of the time line:
- the first where there is no event
- the second where there is an event
- the third is used for left padding
:param dict figlet: Figlet options to use on the title
"""
# Title
if all((title, figlet, figlet_format)):
title = figlet_format(title, **figlet)
# Create the intermediary time line
first, *indexes, last = sorted(events)
event_len = len(max(str(first), str(last), key=len)) + 1
timeline = [''] * length
timeline[0] = first, events[first]
timeline[-1] = last, events[last]
# Calculate each and every event position in the time line
for event in indexes:
idx = (float(event) - first) / (last - first) * length + 1
while timeline[int(idx)]:
idx += 1
timeline[int(idx)] = event, events[event]
# The final time line
out = title.splitlines()
for event in timeline:
if not isinstance(event, tuple):
# Separator
out += [f'{style[2]:<{padding}} {style[0]:>{event_len}}']
continue
# This is an event!
date, names = event
if not isinstance(names, tuple):
# Single event
line = (f'{style[2]:<{padding}}{date:>{event_len - 1}}'
f' {style[1]} {names}')
out += [line]
continue
# There are several events for a given date
line = (f'{style[2]:<{padding}}{date:>{event_len - 1}}'
f' {style[1]} {names[0]}')
out += [line]
idx = line.index(names[0]) - padding - 2
for name in names[1:]:
out += [f'{style[2]:<{padding}} {style[1]:>{idx}} {name}']
return out
Son utilisation est simple, je vous mets quelques exemples d'utilisation juste en dessous. Les événements sont un dict
où chaque clef est une année et la valeur associée un titre de film. S'il y a plusieurs films pour une même date, on peut fournir un tuple
de films :
events = {
2122: 'Alien',
2179: ('Aliens', 'Alien³'),
...
}
Alien
Voici un exemple avec la saga Alien :
def alien():
""" Example: Alien. """
events = {
2122: 'Alien',
2179: ('Aliens', 'Alien³'),
2379: 'Alien: Resurrection',
2093: 'Prometheus',
2104: 'Alien: Covenant',
}
args = {
'title': 'Alien',
'padding': 6,
'figlet': {'font': 'cyberlarge'},
}
out = frise(events, **args)
print('\n'.join(out))
_______ _____ _______ __ _
|_____| | | |______ | \ |
| | |_____ __|__ |______ | \_|
2093 • Prometheus
|
2104 • Alien: Covenant
|
2122 • Alien
|
|
|
|
|
2179 • Aliens
• Alien³
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2379 • Alien: Resurrection
X-Men
Un autre exemple qui enregistre la frise dans le fichier x-men.txt :
import codecs
def xmen():
"""
Example: X-Men.
Save the output to the "x-men.txt" file.
"""
events = {
2005: ('X-Men', 'X2'),
2006: 'X-Men: The Last Stand',
1990: 'X-Men Origins: Wolverine',
1962: 'X-Men: First Class',
2013: 'The Wolverine',
2023: 'X-Men: Days of Future Past',
1983: 'X-Men: Apocalypse',
2029: 'Logan',
}
args = {
'padding': 3,
}
out = frise(events, **args)
with codecs.open('x-men.txt', 'w', encoding='utf-8') as handler:
handler.write('\n'.join(out) + '\n')
1962 • X-Men: First Class
|
|
|
|
|
|
|
|
|
1983 • X-Men: Apocalypse
|
|
1990 • X-Men Origins: Wolverine
|
|
|
|
|
|
2005 • X-Men
• X2
2006 • X-Men: The Last Stand
|
2013 • The Wolverine
|
|
|
|
2023 • X-Men: Days of Future Past
2029 • Logan
Star Wars
Et enfin, un exemple moins précis qui traite de la saga Star Wars (les dates ne sont pas bonnes, aide bienvenue ☺) :
def star_wars():
""" Example: Star Wars. """
events = {
0: ('Rogue One', 'Episode IV: A New Hope'),
3: 'Episode V: The Empire Strikes Back',
4: 'Episode VI: Return of the Jedi',
-32: 'Episode I: The Phantom Menace',
-22: 'Episode II: Attack of the Clones',
-19: 'Episode III: Revenge of the Sith',
34: 'Episode VII: The Force Awakens',
55: 'Episode VIII: The Last Jedi',
}
args = {
'title': 'Star Wars',
'padding': 6,
'figlet': {'font': 'starwars'},
}
return frise(events, **args)
_______.___________. ___ .______
/ | | / \ | _ \
| (----`---| |----` / ^ \ | |_) |
\ \ | | / /_\ \ | /
.----) | | | / _____ \ | |\ \----.
|_______/ |__| /__/ \__\ | _| `._____|
____ __ ____ ___ .______ _______.
\ \ / \ / / / \ | _ \ / |
\ \/ \/ / / ^ \ | |_) | | (----`
\ / / /_\ \ | / \ \
\ /\ / / _____ \ | |\ \----.----) |
\__/ \__/ /__/ \__\ | _| `._____|_______/
-32 • Episode I: The Phantom Menace
|
|
|
-22 • Episode II: Attack of the Clones
-19 • Episode III: Revenge of the Sith
|
|
|
|
|
|
0 • Rogue One
• Episode IV: A New Hope
3 • Episode V: The Empire Strikes Back
4 • Episode VI: Return of the Jedi
|
|
|
|
|
|
|
|
34 • Episode VII: The Force Awakens
|
|
|
|
|
55 • Episode VIII: The Last Jedi
Historique
- 2018-03-23 : Ajout des exemples de sortie pour X-Men et Star Wars, ainsi que d'un paragraphe d'introduction sur le pourquoi du comment (important).