276 lines
No EOL
9.7 KiB
Python
276 lines
No EOL
9.7 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
Démonstration des fonctions utilitaires AASQA avancées
|
||
===================================================
|
||
|
||
Ce script illustre l'utilisation des nouvelles fonctions utilitaires
|
||
avancées pour analyser et rechercher dans les données AASQA.
|
||
|
||
Fonctionnalités:
|
||
- Recherche par nom d'organisme ou région
|
||
- Statistiques détaillées sur la couverture
|
||
- Validation de l'intégrité des données
|
||
- Analyses comparatives
|
||
"""
|
||
|
||
import sys
|
||
import os
|
||
|
||
# Ajouter le répertoire parent au PYTHONPATH pour importer le package local
|
||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||
|
||
from atmo_data_wrapper import (
|
||
search_aasqa_by_name,
|
||
get_departments_count,
|
||
validate_department_coverage,
|
||
get_aasqa_statistics,
|
||
get_aasqa_info
|
||
)
|
||
|
||
def demo_search_functionality():
|
||
"""Démonstration de la recherche par nom"""
|
||
print("🔍 RECHERCHE PAR NOM D'ORGANISME OU RÉGION")
|
||
print("=" * 55)
|
||
|
||
search_terms = ['Atmo', 'Air', 'France', 'Sud', 'Grand']
|
||
|
||
for term in search_terms:
|
||
results = search_aasqa_by_name(term)
|
||
print(f"🔎 Recherche '{term}' → {len(results)} résultat(s)")
|
||
|
||
for result in results[:3]: # Limiter à 3 résultats pour la démo
|
||
print(f" • {result['organisme']} ({result['region']})")
|
||
|
||
if len(results) > 3:
|
||
print(f" ... et {len(results) - 3} autre(s)")
|
||
print()
|
||
|
||
def demo_department_statistics():
|
||
"""Démonstration des statistiques départementales"""
|
||
print("📊 STATISTIQUES DÉPARTEMENTALES")
|
||
print("=" * 55)
|
||
|
||
dept_counts = get_departments_count()
|
||
|
||
# Tri par nombre de départements (décroissant)
|
||
sorted_counts = sorted(dept_counts.items(), key=lambda x: x[1], reverse=True)
|
||
|
||
print("Classement par nombre de départements couverts:")
|
||
print()
|
||
|
||
for i, (aasqa_code, count) in enumerate(sorted_counts, 1):
|
||
aasqa_info = get_aasqa_info(aasqa_code)
|
||
organisme = aasqa_info['organisme']
|
||
region = aasqa_info['region']
|
||
|
||
if i <= 5: # Top 5
|
||
print(f"{i:2d}. {organisme:<30} : {count:2d} département(s) ({region})")
|
||
elif i == 6:
|
||
print(" ...")
|
||
elif i >= len(sorted_counts) - 2: # Bottom 3
|
||
print(f"{i:2d}. {organisme:<30} : {count:2d} département(s) ({region})")
|
||
|
||
print()
|
||
|
||
def demo_validation_report():
|
||
"""Démonstration du rapport de validation"""
|
||
print("✅ RAPPORT DE VALIDATION")
|
||
print("=" * 55)
|
||
|
||
validation = validate_department_coverage()
|
||
|
||
print("Intégrité des données AASQA:")
|
||
print()
|
||
print(f"📊 Total d'entrées départements: {validation['total_departments']}")
|
||
print(f"📊 Départements uniques: {validation['unique_departments']}")
|
||
print(f"📊 Couverture complète: {'✅ Oui' if validation['coverage_complete'] else '❌ Non'}")
|
||
print(f"📊 Doublons détectés: {'❌ Oui' if validation['has_duplicates'] else '✅ Non'}")
|
||
|
||
if validation['duplicates']:
|
||
print(f"⚠️ Départements en doublon: {', '.join(validation['duplicates'])}")
|
||
|
||
print()
|
||
|
||
def demo_comprehensive_statistics():
|
||
"""Démonstration des statistiques complètes"""
|
||
print("📈 STATISTIQUES COMPLÈTES")
|
||
print("=" * 55)
|
||
|
||
stats = get_aasqa_statistics()
|
||
|
||
print("Vue d'ensemble:")
|
||
print(f" • Nombre total d'AASQA: {stats['total_aasqa']}")
|
||
print(f" • Départements couverts: {stats['total_departments_covered']}")
|
||
print(f" • Départements uniques: {stats['unique_departments']}")
|
||
print(f" • Couverture moyenne: {stats['average_coverage']:.1f} départements/AASQA")
|
||
print()
|
||
|
||
print("Couverture maximale:")
|
||
max_info = stats['max_coverage']
|
||
print(f" • {max_info['count']} départements")
|
||
print(f" • Organisme(s): {', '.join(max_info['aasqa_names'])}")
|
||
print()
|
||
|
||
print("Couverture minimale:")
|
||
min_info = stats['min_coverage']
|
||
print(f" • {min_info['count']} département(s)")
|
||
print(f" • Organisme(s): {', '.join(min_info['aasqa_names'])}")
|
||
print()
|
||
|
||
print(f"Anomalies: {'❌ Détectées' if stats['has_anomalies'] else '✅ Aucune'}")
|
||
print()
|
||
|
||
def demo_practical_analysis():
|
||
"""Démonstration d'analyses pratiques"""
|
||
print("🎯 ANALYSES PRATIQUES")
|
||
print("=" * 55)
|
||
|
||
# Analyse 1: Organismes DOM-TOM
|
||
print("1️⃣ Analyse DOM-TOM:")
|
||
dom_tom_codes = ['971', '972', '973', '974', '976']
|
||
|
||
from atmo_data_wrapper import get_aasqa_by_department
|
||
|
||
for code in dom_tom_codes:
|
||
aasqa_code = get_aasqa_by_department(code)
|
||
if aasqa_code:
|
||
aasqa_info = get_aasqa_info(aasqa_code)
|
||
print(f" • {code}: {aasqa_info['region']} → {aasqa_info['organisme']}")
|
||
print()
|
||
|
||
# Analyse 2: Régions métropolitaines les plus étendues
|
||
print("2️⃣ Grandes régions métropolitaines:")
|
||
dept_counts = get_departments_count()
|
||
metro_counts = {}
|
||
|
||
for aasqa_code, count in dept_counts.items():
|
||
aasqa_info = get_aasqa_info(aasqa_code)
|
||
# Exclure DOM-TOM (codes postaux 97x)
|
||
if not any(dept.startswith('97') for dept in aasqa_info['departements']):
|
||
metro_counts[aasqa_code] = count
|
||
|
||
top_metro = sorted(metro_counts.items(), key=lambda x: x[1], reverse=True)[:3]
|
||
|
||
for i, (aasqa_code, count) in enumerate(top_metro, 1):
|
||
aasqa_info = get_aasqa_info(aasqa_code)
|
||
print(f" {i}. {aasqa_info['region']}: {count} départements ({aasqa_info['organisme']})")
|
||
print()
|
||
|
||
# Analyse 3: Organismes avec URL atmo vs autres
|
||
print("3️⃣ Analyse des noms d'organismes:")
|
||
|
||
from atmo_data_wrapper import AASQA_CODES
|
||
|
||
atmo_orgs = []
|
||
other_orgs = []
|
||
|
||
for aasqa_code, aasqa_data in AASQA_CODES.items():
|
||
if 'atmo' in aasqa_data['organisme'].lower():
|
||
atmo_orgs.append(aasqa_data['organisme'])
|
||
else:
|
||
other_orgs.append(aasqa_data['organisme'])
|
||
|
||
print(f" • Organismes 'Atmo': {len(atmo_orgs)} ({len(atmo_orgs)/len(AASQA_CODES)*100:.0f}%)")
|
||
print(f" • Autres noms: {len(other_orgs)} ({len(other_orgs)/len(AASQA_CODES)*100:.0f}%)")
|
||
print(f" • Noms alternatifs: {', '.join(other_orgs[:3])}{'...' if len(other_orgs) > 3 else ''}")
|
||
print()
|
||
|
||
def demo_data_quality_checks():
|
||
"""Démonstration des vérifications de qualité"""
|
||
print("🔬 VÉRIFICATIONS DE QUALITÉ DES DONNÉES")
|
||
print("=" * 55)
|
||
|
||
from atmo_data_wrapper import AASQA_CODES
|
||
|
||
print("1️⃣ Vérification des URLs:")
|
||
urls_https = 0
|
||
urls_http = 0
|
||
|
||
for aasqa_data in AASQA_CODES.values():
|
||
url = aasqa_data['site_web']
|
||
if url.startswith('https://'):
|
||
urls_https += 1
|
||
elif url.startswith('http://'):
|
||
urls_http += 1
|
||
|
||
print(f" • URLs HTTPS: {urls_https}/{len(AASQA_CODES)} ({urls_https/len(AASQA_CODES)*100:.0f}%)")
|
||
if urls_http > 0:
|
||
print(f" ⚠️ URLs HTTP: {urls_http}")
|
||
else:
|
||
print(f" ✅ Toutes les URLs sont sécurisées (HTTPS)")
|
||
print()
|
||
|
||
print("2️⃣ Vérification des codes départementaux:")
|
||
|
||
valid_formats = 0
|
||
invalid_formats = []
|
||
|
||
for aasqa_code, aasqa_data in AASQA_CODES.items():
|
||
for dept in aasqa_data['departements']:
|
||
# Vérifier le format (2 chiffres, 3 chiffres pour DOM-TOM, ou 2A/2B pour Corse)
|
||
if (dept.isdigit() and len(dept) in [2, 3]) or dept in ['2A', '2B']:
|
||
valid_formats += 1
|
||
else:
|
||
invalid_formats.append(dept)
|
||
|
||
print(f" • Codes valides: {valid_formats}")
|
||
if invalid_formats:
|
||
print(f" ⚠️ Codes invalides: {invalid_formats}")
|
||
else:
|
||
print(f" ✅ Tous les codes départementaux sont valides")
|
||
print()
|
||
|
||
print("3️⃣ Cohérence des descriptions:")
|
||
consistent = 0
|
||
inconsistent = []
|
||
|
||
for aasqa_code, aasqa_data in AASQA_CODES.items():
|
||
expected_desc = f"{aasqa_data['region']} | {aasqa_data['organisme']}"
|
||
if aasqa_data['description'] == expected_desc:
|
||
consistent += 1
|
||
else:
|
||
inconsistent.append(aasqa_code)
|
||
|
||
print(f" • Descriptions cohérentes: {consistent}/{len(AASQA_CODES)}")
|
||
if inconsistent:
|
||
print(f" ⚠️ Incohérences: {inconsistent}")
|
||
else:
|
||
print(f" ✅ Toutes les descriptions sont cohérentes")
|
||
|
||
def main():
|
||
"""Fonction principale"""
|
||
print("DÉMONSTRATION DES FONCTIONS UTILITAIRES AASQA AVANCÉES")
|
||
print("=" * 65)
|
||
print("Nouvelles analyses et vérifications de qualité des données")
|
||
print()
|
||
|
||
try:
|
||
demo_search_functionality()
|
||
demo_department_statistics()
|
||
demo_validation_report()
|
||
demo_comprehensive_statistics()
|
||
demo_practical_analysis()
|
||
demo_data_quality_checks()
|
||
|
||
print("=" * 65)
|
||
print("✅ TOUTES LES ANALYSES TERMINÉES AVEC SUCCÈS")
|
||
print()
|
||
print("🎯 Fonctions utilitaires démontrées:")
|
||
print(" • search_aasqa_by_name(): Recherche textuelle")
|
||
print(" • get_departments_count(): Comptage par AASQA")
|
||
print(" • validate_department_coverage(): Validation intégrité")
|
||
print(" • get_aasqa_statistics(): Statistiques complètes")
|
||
print(" • Analyses qualité et cohérence des données")
|
||
print()
|
||
print("📁 Fichiers concernés:")
|
||
print(" • constants.py: Données pures (sites web, départements)")
|
||
print(" • utils.py: Fonctions utilitaires (nouvelle architecture)")
|
||
|
||
except Exception as e:
|
||
print(f"❌ Erreur lors de l'exécution: {e}")
|
||
import traceback
|
||
print("\nDétails de l'erreur:")
|
||
print(traceback.format_exc())
|
||
|
||
if __name__ == "__main__":
|
||
main() |