Skip to main content

Simulateur de trafic routier avec gestion d'exceptions et tests complets

Project description

🚦 **Simulateur de Trafic petit simulateur de trafic écrit en Python.

🧩 Dépendances

  • ✅ Aucune bibliothèque de tracé externe n'est requise. Le simulateur exporte les séries temporelles de positions en CSV (data/positions.csv).
  • 🖼️ Si vous souhaitez visualiser les résultats, installez une bibliothèque de tracé (par ex. matplotlib) séparément.

▶️ Exécution

Lancer la simulation depuis la racine du projet :

python main.py

📝 Notes Importantes

  • 📦 Le package local io a été renommé en io_pkg pour éviter les conflits avec le module standard io de Python.
  • ⚠️ Si vous rencontrez un ImportError lié à io, utilisez from io_pkg import ... au lieu de from io import ....

ℹ️ Fichiers Utiles

  • data/config_reseau.json — configuration d'exemple (routes et véhicules)
  • data/resultats.json — statistiques exportées après une simulation
  • data/positions.csv — positions temporelles exportées par Simulateur.tracer_positions()

💡 Astuce

Pour exécuter les tests :

python -m pytest -q

🏗️ Architecture du Projet

La structure réelle trouvée dans ce dépôt (raccourcie aux fichiers pertinents) est :

simulateur_trafic/
├─ .github/                     # workflows CI (optionnel)
├─ core/
│  ├─ __init__.py
│  ├─ analyseur.py
│  └─ simulateur.py
├─ data/
│  └─ config_reseau.json
├─ docs/
│  ├─ conf.py
│  ├─ index.rst
│  └─ modules.rst
├─ exceptions/                  # 🆕 Module d'exceptions personnalisées
│  ├─ __init__.py
│  ├─ base_exceptions.py
│  ├─ vehicule_exceptions.py
│  ├─ route_exceptions.py
│  ├─ simulateur_exceptions.py
│  ├─ analyseur_exceptions.py
│  └─ README.md
├─ io_pkg/
│  ├─ __init__.py
│  ├─ affichage.py
│  └─ export.py
├─ junit-tests/                 # Tests unittest/JUnit
│  └─ ...
├─ main.py
├─ models/
│  ├─ __init__.py
│  ├─ reseau.py
│  ├─ route.py
│  └─ vehicule.py
├─ README.md
├─ requirements.txt
├─ demo_exceptions.py           # 🆕 Démonstration des exceptions
├─ TP_RAPPORT_EXCEPTIONS.md     # 🆕 Rapport TP exceptions
└─ tests/
   ├─ conftest.py
   ├─ test_vehicule.py
   ├─ test_route.py
   ├─ test_reseau.py
   └─ test_exceptions.py        # 🆕 Tests des exceptions

🧭 Flux de Données

  • Le Simulateur charge data/config_reseau.json au démarrage.
  • Il instancie les Route et Vehicule dans models.
  • À chaque pas de simulation, le Simulateur met à jour chaque Route, qui appelle Vehicule.avancer(delta_t).
  • Les Analyseur calcule des statistiques (nombre de véhicules, vitesses, moyenne).
  • io_pkg.Affichage affiche l'état dans la console ; io_pkg.Export écrit resultats.json.
  • Optionnel: Simulateur.tracer_positions() exporte data/positions.csv pour visualisation.

🔌 Points d'Extension / Guide Développement

  • Ajouter des comportements de véhicules : modifier models/vehicule.py (accélération, freins, changement de vitesse).
  • Ajouter des stratégies de routage : étendre models/reseau.py et models/route.py.
  • Remplacer l'affichage : implémenter une nouvelle classe dans io_pkg (par ex. affichage_gui.py) et l'injecter dans Simulateur.
  • Ajouter de nouveaux analyseurs : créer des modules dans core/ et les appeler depuis Simulateur.

🧪 Tests et CI

Tests pytest (dossier tests/)

Exécuter les tests avec pytest :

python -m pytest -q

Tests des exceptions:

python -m pytest tests/test_exceptions.py -v

Tests unittest/JUnit (dossier junit-tests/)

Le projet inclut également des tests au format unittest (bibliothèque standard Python) qui génèrent des rapports compatibles JUnit XML.

Structure des tests JUnit

  • test_vehicule_unittest.py — Tests unitaires pour la classe Vehicule
  • test_route_unittest.py — Tests unitaires pour la classe Route
  • test_reseau_unittest.py — Tests unitaires pour la classe ReseauRoutier
  • test_simulateur_unittest.py — Tests d'intégration pour le Simulateur
  • run_junit_tests.py — Script pour exécuter tous les tests et générer les rapports XML
  • xml-reports/ — (généré) Rapports JUnit XML après exécution

Exécution des tests JUnit

Option 1: Avec génération de rapports JUnit XML (recommandé)

Installer d'abord le générateur de rapports XML :

pip install unittest-xml-reporting

Puis exécuter tous les tests :

python junit-tests/run_junit_tests.py

Les rapports XML seront générés dans junit-tests/xml-reports/.

Option 2: Exécution unittest standard (sans XML)

Exécuter tous les tests :

python -m unittest discover junit-tests -p "test_*_unittest.py" -v

Exécuter un fichier de test spécifique :

python junit-tests/test_vehicule_unittest.py

Format des rapports JUnit

Les rapports XML générés sont au format JUnit et peuvent être utilisés avec :

  • Jenkins
  • GitLab CI
  • GitHub Actions
  • Azure DevOps
  • SonarQube
  • Autres outils CI/CD

Note importante

Les tests pytest originaux sont conservés dans le dossier tests/ et restent inchangés. Les deux formats de tests coexistent.

CI/CD

Un workflow GitHub Actions (si présent) installe les dépendances, exécute les tests et construit la documentation Sphinx.

🚨 Module d'Exceptions Personnalisées

Ce dossier contient toutes les exceptions personnalisées du simulateur de trafic, organisées par domaine fonctionnel.

📋 Structure

exceptions/
├── __init__.py                    # Point d'entrée, exporte toutes les exceptions
├── base_exceptions.py             # Exception de base SimulateurException
├── vehicule_exceptions.py         # Exceptions liées aux véhicules
├── route_exceptions.py            # Exceptions liées aux routes
├── simulateur_exceptions.py       # Exceptions du simulateur principal
└── analyseur_exceptions.py        # Exceptions de l'analyseur statistique

🎯 Types d'Exceptions

Exception de Base

  • SimulateurException - Classe parente de toutes les exceptions du projet

Exceptions Véhicule (vehicule_exceptions.py)

Exception Code Description
VehiculeException - Classe de base pour les erreurs véhicule
VitesseNegativeException VEH001 Vitesse négative détectée
PositionInvalideException VEH002 Position hors limites

Exceptions Route (route_exceptions.py)

Exception Code Description
RouteException - Classe de base pour les erreurs route
RoutePleineException RTE001 Capacité maximale atteinte
VehiculeDejaPresent RTE002 Véhicule déjà sur la route
RouteInexistanteException RTE003 Route non trouvée dans le réseau
LongueurRouteInvalideException RTE004 Longueur de route <= 0

Exceptions Simulateur (simulateur_exceptions.py)

Exception Code Description
ConfigurationException - Classe de base pour erreurs config
FichierConfigurationException SIM001 Fichier config manquant/invalide
IterationsInvalidesException SIM002 Nombre d'itérations invalide

Exceptions Analyseur (analyseur_exceptions.py)

Exception Code Description
AnalyseurException - Classe de base pour erreurs analyse
DivisionParZeroException ANA001 Division par zéro dans les calculs
DonneesMaquantesException ANA002 Données manquantes pour l'analyse
RouteVideException ANA003 Calcul sur route sans véhicule

💡 Utilisation

Import des exceptions

# Import individuel
from exceptions import VitesseNegativeException, RoutePleineException

# Import de toutes les exceptions
from exceptions import *

# Import par catégorie
from exceptions.vehicule_exceptions import VitesseNegativeException
from exceptions.route_exceptions import RoutePleineException

Exemple 1: Validation dans Vehicule

from exceptions import VitesseNegativeException, PositionInvalideException

class Vehicule:
    def __init__(self, identifiant, route, position=0.0, vitesse=0.0):
        # Validation de la vitesse
        if vitesse < 0:
            raise VitesseNegativeException(vitesse, str(identifiant))

        # Validation de la position
        if position < 0:
            raise PositionInvalideException(position, vehicule_id=str(identifiant))

        self.id = identifiant
        self.vitesse = vitesse
        self.position = position

Exemple 2: Gestion dans Route

from exceptions import RoutePleineException, VehiculeDejaPresent

class Route:
    def ajouter_vehicule(self, vehicule):
        # Vérifier capacité
        if len(self.vehicules) >= self.capacite_max:
            raise RoutePleineException(self.nom, self.capacite_max)

        # Vérifier doublon
        if vehicule.id in [v.id for v in self.vehicules]:
            raise VehiculeDejaPresent(str(vehicule.id), self.nom)

        self.vehicules.append(vehicule)

Exemple 3: Try/Except dans le code appelant

from exceptions import (
    SimulateurException,
    VitesseNegativeException,
    FichierConfigurationException
)

try:
    # Charger la configuration
    sim = Simulateur("data/config_reseau.json")

    # Lancer la simulation
    sim.lancer_simulation(n_tours=100, delta_t=1.0)

except FichierConfigurationException as e:
    print(f"❌ Erreur de configuration: {e}")
    print(f"   Code d'erreur: {e.code}")

except VitesseNegativeException as e:
    print(f"❌ Erreur de vitesse: {e}")
    print(f"   Véhicule: {e.vehicule_id}, Vitesse: {e.vitesse}")

except SimulateurException as e:
    # Capturer toutes les exceptions du simulateur
    print(f"❌ Erreur du simulateur [{e.code}]: {e}")

except Exception as e:
    print(f"❌ Erreur inattendue: {e}")

🔍 Codes d'Erreur

Les exceptions incluent un code d'erreur pour faciliter le débogage :

  • VEH0xx : Erreurs véhicule
  • RTE0xx : Erreurs route/réseau
  • SIM0xx : Erreurs simulateur
  • ANA0xx : Erreurs analyseur

🎨 Attributs Personnalisés

Chaque exception fournit des attributs spécifiques pour faciliter le traitement :

try:
    vehicule = Vehicule("V1", route, position=-10, vitesse=50)
except PositionInvalideException as e:
    print(f"Position invalide: {e.position}")
    print(f"Position max: {e.position_max}")
    print(f"Véhicule: {e.vehicule_id}")
    print(f"Message: {e.message}")
    print(f"Code: {e.code}")

🧪 Tests des Exceptions

Les tests unitaires doivent vérifier que les exceptions sont levées correctement :

import pytest
from exceptions import VitesseNegativeException
from models import Vehicule, Route

def test_vitesse_negative_leve_exception():
    route = Route("R1", longueur=1000, limite_vitesse=50)

    with pytest.raises(VitesseNegativeException) as exc_info:
        vehicule = Vehicule("V1", route, position=0, vitesse=-10)

    assert exc_info.value.vitesse == -10
    assert exc_info.value.code == "VEH001"

📊 Hiérarchie des Exceptions

Exception (Python built-in)
    └── SimulateurException (base)
        ├── VehiculeException
        │   ├── VitesseNegativeException
        │   └── PositionInvalideException
        ├── RouteException
        │   ├── RoutePleineException
        │   ├── VehiculeDejaPresent
        │   ├── RouteInexistanteException
        │   └── LongueurRouteInvalideException
        ├── ConfigurationException
        │   ├── FichierConfigurationException
        │   └── IterationsInvalidesException
        └── AnalyseurException
            ├── DivisionParZeroException
            ├── DonneesMaquantesException
            └── RouteVideException

✅ Bonnes Pratiques

  1. Lever des exceptions spécifiques plutôt que génériques
  2. Inclure du contexte (IDs, valeurs, limites) dans les exceptions
  3. Capturer et re-lever les exceptions avec raise ... from e pour préserver la trace
  4. Documenter les exceptions dans les docstrings avec Raises:
  5. Logger les erreurs avant de les lever si nécessaire
  6. Utiliser try/except aux bons endroits (frontières de l'application)

🔗 Intégration

Ces exceptions sont intégrées dans :

  • models/vehicule.py - Validation vitesse/position
  • models/route.py - Validation capacité/doublons
  • models/reseau.py - Validation existence routes
  • core/simulateur.py - Validation configuration/itérations
  • core/analyseur.py - Validation données/calculs

📚 Génération de Documentation (Sphinx)

  1. Installer Sphinx :
python -m pip install -U sphinx sphinx-rtd-theme
  1. Construire la doc :
python -m sphinx -b html docs docs/_build/html

Si la construction échoue car Sphinx ne peut pas importer des modules, vérifiez que vous exécutez la commande depuis la racine du projet et que toutes les dépendances d'import sont installées.

📦 Installation du package (préparation PyPI/TestPyPI)

Le projet est maintenant préparé pour être distribué sur PyPI/TestPyPI. Vous trouverez les fichiers de packaging (pyproject.toml, setup.cfg, setup.py, MANIFEST.in) à la racine du dépôt.

Pour construire et tester l'installation localement (recommandé via TestPyPI) :

# Installer les outils de build et twine
python -m pip install --upgrade build twine

# Construire les distributions
python -m build

# (Optionnel) Publier sur TestPyPI pour tester
python -m twine upload --repository testpypi dist/*

# Installer depuis TestPyPI pour vérifier
python -m pip install --index-url https://test.pypi.org/simple/ --no-deps simulateur-trafic==0.1.0

Consultez PUBLISH.md pour des instructions détaillées et un exemple de .pypirc.


Auteur : Moatez Tilouche

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

simulateur_trafic_moatez-1.0.0.tar.gz (38.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

simulateur_trafic_moatez-1.0.0-py3-none-any.whl (38.2 kB view details)

Uploaded Python 3

File details

Details for the file simulateur_trafic_moatez-1.0.0.tar.gz.

File metadata

File hashes

Hashes for simulateur_trafic_moatez-1.0.0.tar.gz
Algorithm Hash digest
SHA256 1f7a9cc6b8dfbac7f68bd9d499565821d2b7d971730668ab6bf049035e3fcfba
MD5 e0a57405667ee9ffa48903206a097db6
BLAKE2b-256 e9d0d3fa4a19369d634fa2470a790a1b252c2356c2b9c6245fea4fcdb22aa1dd

See more details on using hashes here.

File details

Details for the file simulateur_trafic_moatez-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for simulateur_trafic_moatez-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e89da023d1cf7549e1adf416f97d746d494e9ebfafa8010966ff6a09aae75ce2
MD5 1e4e082107d921298afa845d1c04318e
BLAKE2b-256 e235d2214303420e472561bf1805f7e6737334bd3816c8de27624fcbaa3a3e51

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page