Exercice 01 : Pipeline de Traitement de Données Fonctionnel
Objectif
Cet exercice a pour but de vous faire utiliser les outils de programmation fonctionnelle (map, filter, reduce) et la composition de fonctions pour créer un pipeline de traitement de données simple et lisible.
Contexte
Vous disposez d'une liste de dictionnaires représentant des transactions commerciales. Chaque dictionnaire contient l'ID de la transaction, le montant et le pays. Votre objectif est de calculer le revenu total des transactions provenant d'un pays spécifique (par exemple, "USA") et dont le montant est supérieur à un certain seuil.
Vous allez résoudre ce problème en créant une série de petites fonctions pures et en les combinant.
Énoncé
-
Créez un nouveau fichier Python nommé
functional_pipeline.py. -
Définissez les données de départ. Créez une liste de dictionnaires
transactionscomme celle-ci :transactions = [
{"id": 1, "country": "USA", "amount": 150.0},
{"id": 2, "country": "France", "amount": 200.0},
{"id": 3, "country": "USA", "amount": 75.0},
{"id": 4, "country": "UK", "amount": 300.0},
{"id": 5, "country": "USA", "amount": 225.0},
{"id": 6, "country": "France", "amount": 50.0},
] -
Créez des fonctions de filtrage.
- Créez une fonction
is_from_country(transaction, country)qui retourneTruesi la transaction vient du pays spécifié. - Créez une fonction
is_above_threshold(transaction, threshold)qui retourneTruesi le montant de la transaction est supérieur au seuil.
- Créez une fonction
-
Créez une fonction d'extraction.
- Créez une fonction
get_amount(transaction)qui retourne le montant de la transaction.
- Créez une fonction
-
Utilisez
functools.partialpour spécialiser vos fonctions.- Créez une fonction
is_from_usaen utilisantpartialsuris_from_country. - Créez une fonction
is_above_100en utilisantpartialsuris_above_threshold.
- Créez une fonction
-
Construisez le pipeline.
- Utilisez
filteretis_from_usapour ne garder que les transactions des USA. - Enchaînez avec un autre
filteretis_above_100pour filtrer par montant. - Utilisez
mapetget_amountpour extraire les montants des transactions restantes. - Utilisez
functools.reducepour sommer les montants et obtenir le total. Vous pouvez aussi utilisersum()qui est souvent plus simple. Pour cet exercice, essayez avecreduce.
- Utilisez
-
Affichez le résultat final.
Résultat Attendu
Le script doit calculer et afficher le revenu total des transactions des USA dont le montant est supérieur à 100.
Transactions initiales:
[{'id': 1, 'country': 'USA', 'amount': 150.0}, {'id': 2, 'country': 'France', 'amount': 200.0}, ...]
Transactions des USA:
<filter object at ...>
Transactions des USA > 100:
<filter object at ...>
Montants extraits:
<map object at ...>
Revenu total des transactions éligibles : 375.0
(Les transactions des USA > 100 sont celles avec les ID 1 (150.0) et 5 (225.0). La somme est 150.0 + 225.0 = 375.0)
Cliquez ici pour voir un exemple de code de solution
# functional_pipeline.py
from functools import partial, reduce
# 1. Données de départ
transactions = [
{"id": 1, "country": "USA", "amount": 150.0},
{"id": 2, "country": "France", "amount": 200.0},
{"id": 3, "country": "USA", "amount": 75.0},
{"id": 4, "country": "UK", "amount": 300.0},
{"id": 5, "country": "USA", "amount": 225.0},
{"id": 6, "country": "France", "amount": 50.0},
]
# 2. Fonctions pures et génériques
def is_from_country(transaction, country):
return transaction["country"] == country
def is_above_threshold(transaction, threshold):
return transaction["amount"] > threshold
def get_amount(transaction):
return transaction["amount"]
def add(x, y):
return x + y
# 3. Spécialisation des fonctions avec partial
is_from_usa = partial(is_from_country, country="USA")
is_above_100 = partial(is_above_threshold, threshold=100)
# 4. Construction du pipeline
print(f"Transactions initiales:\n{transactions}\n")
# Étape 1: Filtrer par pays
usa_transactions = filter(is_from_usa, transactions)
# Étape 2: Filtrer par montant
eligible_transactions = filter(is_above_100, usa_transactions)
# Étape 3: Extraire les montants
amounts = map(get_amount, eligible_transactions)
# Étape 4: Réduire (sommer) les montants
# Note: sum(amounts) serait plus simple et plus idiomatique en Python.
# Nous utilisons reduce ici pour l'exercice.
total_revenue = reduce(add, amounts, 0)
print(f"Revenu total des transactions éligibles : {total_revenue}")
# --- Version alternative en une seule ligne (moins lisible) ---
total_revenue_oneline = reduce(add, map(get_amount, filter(is_above_100, filter(is_from_usa, transactions))))
# print(f"Total en une ligne : {total_revenue_oneline}")