Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Licence CC BY-NC-ND Thierry Parmentelat & Arnaud Legout Inria - UCA

Exercices

Cet exercice vient en deux versions, une de niveau basique et une de niveau intermédiaire.

La version basique est une application de la technique d’indexation que l’on a vue dans le complément “Gérer des enregistrements”. On peut très bien faire les deux versions dans l’ordre, une fois qu’on a fait la version basique on est en principe un peu plus avancé pour aborder la version intermédiaire.

Contexte

Nous allons commencer à utiliser des données un peu plus réalistes. Il s’agit de données obtenues auprès de MarineTraffic - et légèrement simplifiées pour les besoins de l’exercice. Ce site expose les coordonnées géographiques de bateaux observées en mer au travers d’un réseau de collecte de type crowdsourcing.

De manière à optimiser le volume de données à transférer, l’API de MarineTraffic offre deux modes pour obtenir les données :

En effet, chaque bateau possède un identifiant unique qui est un entier, que l’on note id.

Chargement des données

Commençons par charger les données de l’exercice :

from corrections.exo_marine_dict import extended, abbreviated

Format des données

Le format de ces données est relativement simple, il s’agit dans les deux cas d’une liste d’entrées - une par bateau.

Chaque entrée à son tour est une liste qui contient :

mode étendu: [id, latitude, longitude, date_heure, nom_bateau, code_pays, ...]
mode abrégé: [id, latitude, longitude, date_heure]

sachant que les entrées après le code pays dans le format étendu ne nous intéressent pas pour cet exercice.

# une entrée étendue est une liste qui ressemble à ceci
sample_extended_entry = extended[3]
print(sample_extended_entry)
[255801560, 49.3815, -4.412167, '2013-10-08T21:51:00', 'AUTOPRIDE', 'PT', '', 'ZEEBRUGGE']
# une entrée abrégée ressemble à ceci
sample_abbreviated_entry = abbreviated[0]
print(sample_abbreviated_entry)
[227254910, 49.91799, -5.315172, '2013-10-08T22:59:00']

On précise également que les deux listes extended et abbreviated :


Exercice - niveau basique

# chargement de l'exercice
from corrections.exo_marine_dict import exo_index

But de l’exercice

On vous demande d’écrire une fonction index qui calcule, à partir de la liste des données étendues, un dictionnaire qui est :

De manière plus imagée, si :

extended = [ bateau1, bateau2, ... ]

Et si :

bateau1 = [ id1, latitude, ... ]

On doit obtenir comme résultat de index un dictionnaire :

{
    id1 -> [ id_bateau1, latitude, ... ],
    id2 ...
}

Bref, on veut pouvoir retrouver les différents éléments de la liste extended par accès direct, en ne faisant qu’une seule recherche dans l’index.

# le résultat attendu
result_index = exo_index.resultat(extended)

# on en profite pour illustrer le module pprint
from pprint import pprint

# à quoi ressemble le résultat pour un bateau au hasard
for key, value in result_index.items():
    print("==== clé")
    pprint(key)
    print("==== valeur")
    pprint(value)
    break
The history saving thread hit an unexpected error (OperationalError('disk I/O error')).History will not be written to the database.==== clé
992271012
==== valeur
[992271012, 47.64744, -3.509282, '2013-10-08T21:50:00', 'PENMEN', 'FR', '', '']

Remarquez ci-dessus l’utilisation d’un utilitaire parfois pratique : le module pprint pour pretty-printer.

Votre code

def index(extended):
    "<votre_code>"

Validation

exo_index.correction(index, abbreviated)
Loading...

Vous remarquerez d’ailleurs que la seule chose que l’on utilise dans cet exercice, c’est que l’id des bateaux arrive en première position (dans la liste qui matérialise le bateau), aussi votre code doit marcher à l’identique avec les bateaux étendus :

exo_index.correction(index, extended)
Loading...

Exercice - niveau intermédiaire

# chargement de l'exercice
from corrections.exo_marine_dict import exo_merge

But de l’exercice

On vous demande d’écrire une fonction merge qui fasse une consolidation des données, de façon à obtenir en sortie un dictionnaire :

id -> [nom_bateau, code_pays, position_etendu, position_abrege]

dans lequel les deux objets position sont tous les deux des tuples de la forme :

(latitude, longitude, date_heure)

Voici par exemple un couple clé-valeur dans le résultat attendu :

# le résultat attendu
result_merge = exo_merge.resultat(extended, abbreviated)

# à quoi ressemble le résultat pour un bateau au hasard
from pprint import pprint
for key_value in result_merge.items():
    pprint(key_value)
    break
(992271012,
 ['PENMEN',
  'FR',
  (47.64744, -3.509282, '2013-10-08T21:50:00'),
  (47.64748, -3.509307, '2013-10-08T22:56:00')])

Votre code

def merge(extended, abbreviated):
    "votre code"

Validation

exo_merge.correction(merge, extended, abbreviated)
Loading...

Les fichiers de données complets

Signalons enfin pour ceux qui sont intéressés que les données chargées dans cet exercice sont disponibles au format JSON - qui est précisément celui exposé par marinetraffic.

Nous avons beaucoup simplifié les données d’entrée pour vous permettre une mise au point plus facile. Si vous voulez vous amuser à charger des données un peu plus significatives, sachez que :

# load data from files
import json

with open("data/marine-e1-ext.json", encoding="utf-8") as feed:
    extended_full = json.load(feed)

with open("data/marine-e1-abb.json", encoding="utf-8") as feed:
    abbreviated_full = json.load(feed)

Une fois que vous avez un code qui fonctionne vous pouvez le lancer sur ces données plus copieuses en faisant :

exo_merge.correction(merge, extended_full, abbreviated_full)
Loading...