# Cas pratique pédagogique — données synthétiques. sapiteur-ia.fr. # Contrôle déterministe des conventions des cas A, B et C. Python 3, bibliothèque # standard seulement. Ne se connecte à aucun service, n'envoie aucun message et # n'utilise aucun modèle d'IA. Ce n'est pas un « benchmark IA ». from datetime import date from decimal import Decimal, ROUND_HALF_UP import json def selection_version(date_commande): return 'RETOUR-V2' if date_commande >= date(2026, 5, 1) else 'RETOUR-V1' def passage_initial(statut): return statut != 'refuse' def passage_corrige(statut): return statut == 'approuve' def passage_revision(statut, revision_approuvee, revision_courante): return (statut == 'approuve' and bool(revision_approuvee) and bool(revision_courante) and revision_approuvee == revision_courante) def economie(economie_annuelle, investissement='9000', recurrent='2400'): economie_annuelle = Decimal(economie_annuelle) investissement = Decimal(investissement) recurrent = Decimal(recurrent) if min(economie_annuelle, investissement, recurrent) < 0: raise ValueError('Entrees negatives hors du domaine de cet exercice') exploitation = economie_annuelle - recurrent premiere_annee = exploitation - investissement roi = premiere_annee / investissement * 100 if investissement > 0 else None mois = investissement / exploitation * 12 if investissement > 0 and exploitation > 0 else None def format_nombre(x): return str(x.quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)) if x is not None else None return { 'solde_exploitation': format_nombre(exploitation), 'solde_premiere_annee': format_nombre(premiere_annee), 'roi_net_pourcent': format_nombre(roi), 'recuperation_mois': format_nombre(mois) } def verification(): assert selection_version(date(2026, 4, 30)) == 'RETOUR-V1' assert selection_version(date(2026, 5, 1)) == 'RETOUR-V2' assert selection_version(date(2026, 5, 20)) == 'RETOUR-V2' etats = ['en_attente', 'approuve', 'refuse', None, 'inconnu'] assert [passage_initial(x) for x in etats] == [True, True, False, True, True] assert [passage_corrige(x) for x in etats] == [False, True, False, False, False] assert passage_revision('approuve', 'r1', 'r1') is True assert passage_revision('approuve', 'r1', 'r2') is False assert passage_revision('approuve', None, None) is False assert passage_revision('en_attente', 'r1', 'r1') is False avant = Decimal(1200) * 6 / 60 apres = Decimal(1200) * 3 / 60 + 15 heures = (avant - apres) * 12 assert heures == 540 and heures * 35 == 18900 assert economie('3000')['roi_net_pourcent'] == '-93.33' assert economie('3000')['recuperation_mois'] == '180.00' assert economie('0')['roi_net_pourcent'] == '-126.67' assert economie('0')['recuperation_mois'] is None assert economie('12000')['roi_net_pourcent'] == '6.67' assert economie('12000')['recuperation_mois'] == '11.25' assert economie('2400')['recuperation_mois'] is None assert economie('12000', investissement='0')['roi_net_pourcent'] is None try: economie('-1') except ValueError: pass else: raise AssertionError('Entree negative non rejetee') print(json.dumps({ 'statut': 'verifications_reussies', 'nature': 'simulation deterministe sur donnees synthetiques', 'cas_a_version': selection_version(date(2026, 5, 20)), 'cas_b_initial': [passage_initial(x) for x in etats], 'cas_b_corrige': [passage_corrige(x) for x in etats], 'cas_c': {x: economie(x) for x in ['0', '3000', '12000']} }, ensure_ascii=False, indent=2)) if __name__ == '__main__': verification()