5. Résolution des trois problèmes avec ChatGPT
5.1. Introduction
Voici une première copie d’écran d’une session ChatGPT :
![]() ![]() |
- En [1-3], les trois problèmes posés à ChatGPT ;
- En [4], l’URL de ChatGPT ;
- En [5], la version de ChatGPT utilisée ;
ChatGPT est un produit de OpenAI disponible à l’URL [https://chatgpt.com/]. Pour avoir un historique de vos sessions de questions / réponses comme ci-dessus, il vous faut créer un compte. Par ailleurs, comme toutes les autres IA testées, ChatGPT limite le nombre de vos questions et le nombre de fichiers téléchargés. Quand cette limite est atteinte, la session est terminée et on vous propose de la continuer plus tard dans le temps. Les limites imposées par ChatGPT sont atteintes très rapidement. Pour faire ce tutoriel, j’ai du prendre un abonnement payant d’un mois.
L’interface de ChatGPT est la suivante :
![]() |
- En [1], pour joindre des fichiers à la question posée ;
- En [2], la question posée ;
- En [3], pour lancer l’exécution de l’IA ;
5.2. Le problème 1
La question à ChatGPT :
![]() |
ChatGPT répond correctement.
5.3. Le problème 2
C’est le calcul de l’impôt avec le PDF. Pour être honnête, on va utiliser le PDF généré par Gemini qui corrige des erreurs du PDF initial.
![]() |
- En [1], on a donné le PDF généré par Gemini ;
- En [2], on a ajouté le test unitaire par lequel Gemini a démontré sa supériorité :
On lance ChatGPT. Il met environ 3 minutes pour générer sa réponse. Contrairement à Gemini, il livre bien un lien qui marche pour récupérer le script généré. On charge celui-ci dans PyCharm :
![]() |
Le script [chatGPT1] fonctionne du premier coup. Là il n’y a pas photo, sur ce problème ChatGPT a été plus performant que Gemini.
Le script [chatGPT1] fourni par ChatGPT est le suivant :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 | |
5.4. Le problème 3
Maintenant on demande à ChatGPT de chercher les règles de calcul de l’impôt sur internet :
![]() |
Cette fois-ci on ne fournit pas le PDF qui donnait les règles de calcul à observer. On donne seulement nos instructions dans le fichier texte. On rappelle que ce fichier texte contient maintenant 12 tests unitaires après avoir ajouté aux 11 tests initiaux, celui utilisé par Gemini pour démontrer que mon PDF initial était erroné.
ChatGPT répond en 8 minutes, donne un lien pour télécharger le script généré. Une fois chargé dans PyCharm, ce script passe les 12 tests. Donc aux deux problèmes posés, ChatGPT a répondu juste du premier coup, surpassant ainsi Gemini.
ChatGPT donne ses sources dans sa réponse :
![]() |
Il n’y a rien à dire, c’est du beau travail.
Maintenant, on peut lui demander, comme on l’a fait avec Gemini de générer un PDF pour des étudiants.
![]() |
La réponse de ChatGPT a été obtenue après plusieurs allers-retours car le PDF généré utilisait une police qui remplaçait des caractères par un carré. Mais finalement, il a généré le PDF. Je le donne car il donne des règles différentes du PDF de Gemini et je me suis demandé alors qui avait raison. On va enquêter.
![]() |
![]() |
![]() | ![]() |
![]() |
La différence avec le PDF de Gemini est dans le calcul de la décote. Les deux IA n’ont pas la même approche. Gemini avait écrit :
![]() |
![]() |
![]() |
Les deux IA ont deux approches différentes. Qui a raison ?
5.5. Le problème 4
On va demander à ChatGPT de s’appuyer sur son PDF pour faire le calcul de l’impôt :
![]() | ![]() |
Comme les fois précédentes, il génère un script Python qui marche du premier coup. On avait ajouté dans les instructions un test supplémentaire :
Les 13 tests ont été passés avec succès.
5.6. Retour sur Gemini
Maintenant, on revient dans Gemini à qui on va présenter le PDF de ChatGPT. Vu que les règles implémentées dans ce PDF sont différentes de celles implémentées dans le PDF de Gemini, on peut se demander ce qui va se passer :
![]() |
Gemini a tout d’abord généré un script Python qui ratait des tests. On lui a présenté les logs :
Question 2
![]() |
Question 3
Il y a encore des erreurs. On continue.
![]() |
Question 4
Toujours des erreurs à l’exécution :
![]() |
Cette fois-ci c’est bon.
On est quand même intrigués qu’avec des PDF ayant des règles de calcul assez différentes les IA génèrent toutes deux des résultats corrects.
On pose la question suivante à Gemini :
![]() |
La question complète est la suivante :
La réponse de Gemini est catégorique :
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
5.7. Qu’en pense ChatGPT
On pose à ChatGPT la même question posée à Gemini.
![]() |
La réponse de ChatGPT est la suivante :
![]() |
![]() |
Du coup, ChatGPT nous propose un test unitaire pour départager les deux méthodes. Nous dupliquons :
- Le script [gemini3] généré par Gemini en prenant comme source son PDF [Le problème selon Gemini] est dupliqué dans le script [gemini4] ;
- Le script [chatGPT3] généré par ChatGPT en prenant comme source son PDF [Le problème selon ChatGPT] est dupliqué dans le script [chatGPT4] ;
![]() | ![]() |
Par ailleurs, on ajoute dans chacun des scripts [gemini4, chatGPT4] le test unitaire proposé par ChatGPT pour départager les deux IA.
L’exécution de [gemini4] donne les résultats suivants :
C:\Data\st-2025\dev\python\code\python-flask-2025-cours\.venv\Scripts\python.exe "C:/Program Files/JetBrains/PyCharm 2025.2.1.1/plugins/python-ce/helpers/pycharm/_jb_unittest_runner.py" --path "C:\Data\st-2025\dev\python\code\python-flask-2025-cours\outils ia\gemini\gemini4.py"
Testing started at 17:45 ...
Launching unittests with arguments python -m unittest C:\Data\st-2025\dev\python\code\python-flask-2025-cours\outils ia\gemini\gemini4.py in C:\Data\st-2025\dev\python\code\python-flask-2025-cours
SubTest failure: Traceback (most recent call last):
File "C:\Program Files\Python313\Lib\unittest\case.py", line 58, in testPartExecutor
yield
File "C:\Program Files\Python313\Lib\unittest\case.py", line 556, in subTest
yield
File "C:\Data\st-2025\dev\python\code\python-flask-2025-cours\outils ia\gemini\gemini4.py", line 234, in test_cas_verifies_simulateur_officiel
self.assertAlmostEqual(calcul_impot, attendu_impot, delta=1, msg="Échec sur le montant de l'impôt")
~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: 2669 != 2270 within 1 delta (399 difference) : Échec sur le montant de l'impôt
Ran 1 test in 0.010s
FAILED (failures=1)
One or more subtests failed
Failed subtests list: [Test 'test12' avec entrée (2, 0, 43333)]
Process finished with exit code 1
Donc Gemini échoue au test rajouté par ChatGPT.
L’exécution de [chatGPT4] donne les résultats suivants :
C:\Data\st-2025\dev\python\code\python-flask-2025-cours\.venv\Scripts\python.exe "C:\Data\st-2025\dev\python\code\python-flask-2025-cours\outils ia\chatGPT\chatGPT4.py"
Test (2, 2, 55555) -> obtenu (impôt=2814, décote=0, réduction=0) | attendu (2815, 0, 0) | OK
Test (2, 2, 50000) -> obtenu (impôt=1384, décote=384, réduction=347) | attendu (1385, 384, 346) | OK
Test (2, 3, 50000) -> obtenu (impôt=0, décote=721, réduction=0) | attendu (0, 720, 0) | OK
Test (1, 2, 100000) -> obtenu (impôt=19884, décote=0, réduction=0) | attendu (19884, 0, 0) | OK
Test (1, 3, 100000) -> obtenu (impôt=16782, décote=0, réduction=0) | attendu (16782, 0, 0) | OK
Test (2, 3, 100000) -> obtenu (impôt=9200, décote=0, réduction=0) | attendu (9200, 0, 0) | OK
Test (2, 5, 100000) -> obtenu (impôt=4230, décote=0, réduction=0) | attendu (4230, 0, 0) | OK
Test (1, 0, 100000) -> obtenu (impôt=22986, décote=0, réduction=0) | attendu (22986, 0, 0) | OK
Test (2, 2, 30000) -> obtenu (impôt=0, décote=0, réduction=0) | attendu (0, 0, 0) | OK
Test (1, 0, 200000) -> obtenu (impôt=64210, décote=0, réduction=0) | attendu (64211, 0, 0) | OK
Test (2, 3, 200000) -> obtenu (impôt=42842, décote=0, réduction=0) | attendu (42843, 0, 0) | OK
Test (2, 2, 49500) -> obtenu (impôt=1296, décote=431, réduction=325) | attendu (1297, 431, 324) | OK
Test (1, 0, 18535) -> obtenu (impôt=359, décote=491, réduction=90) | attendu (359, 491, 90) | OK
Test (2, 0, 43333) -> obtenu (impôt=2268, décote=0, réduction=401) | attendu (2270, 0, 400) | ECHEC
Détails tolérance ±1€ : impôt ok? False, décote ok? True, réduction ok? True
Résultat global : AU MOINS UN TEST ÉCHOUE ❌
Process finished with exit code 0
ChatGPT échoue lui aussi sur le test rajouté mais pas pour les mêmes raisons que Gemini. ChatGPT a trouvé les bons résultats mais à 2 euros près au lieu des 1 euro imposés.
Donc désormais c’est le PDF généré par ChatGPT que nous utiliserons avec les IA suivantes. Il faut noter que c’est à cause du manque de tests unitaires proposés dans mes instructions que les deux IA ont toutes deux réussi les premiers tests. D’où dans cet exemple précis, l’importance de mettre des tests unitaires pour les cas limites du calcul de l’impôt. Comme c’est plutôt difficile d’imaginer soi-même ces tests. On va demander aux IA d’en rajouter eux-mêmes.
5.8. Le problème 3 avec des test unitaires générés par les IA
Les résultats obtenus avec Gemini et ChatGPT laissent un doute. Les IA ont-elles trouvé une solution générale qui valide tous les tests imaginables ou ont-elles trouvé une solution qui valide les seuls tests imposés. On va repartir sur une solution sans PDF pour obliger les IA à aller sur internet rechercher les informations dont elles ont besoin. Et on modifie nos instructions de la façon suivante :
![]() |
Le fichier texte [instructionsSansPDF4.txt] contient déjà 14 tests imposés. A ces tests, on rajoute les instructions suivantes :
7 - tu ajouteras autant de tests unitaires que nécessaires pour vérifier les cas limites du calcul de l'impôt.
Pour le code tu complèteras le script suivant auquel tu auras rajouté tes propres tests.
# =========================
# Tests unitaires (tolérance de ±1 €)
# =========================
TESTS = [
# (adultes, enfants, revenus) -> (impot, decote, reduction)
((2, 2, 55555), (2815, 0, 0)),
((2, 2, 50000), (1385, 384, 346)),
((2, 3, 50000), (0, 720, 0)),
((1, 2, 100000), (19884, 0, 0)),
((1, 3, 100000), (16782, 0, 0)),
((2, 3, 100000), (9200, 0, 0)),
((2, 5, 100000), (4230, 0, 0)),
((1, 0, 100000), (22986, 0, 0)),
((2, 2, 30000), (0, 0, 0)),
((1, 0, 200000), (64211, 0, 0)),
((2, 3, 200000), (42843, 0, 0)),
((2, 2, 49500), (1297, 431, 324)),
((1, 0, 18535), (359, 491, 90)),
((2, 0, 43333), (2270, 0, 400)),
]
def _ok(a, b, tol=1):
return abs(a - b) <= tol
def run_tests(verbose: bool = True) -> bool:
all_ok = True
for (params, expected) in TESTS:
a, e, r = params
exp_impot, exp_decote, exp_reduc = expected
res = calcul_impot_2019(a, e, r)
ok_impot = _ok(res.impot, exp_impot)
ok_decote = _ok(res.decote, exp_decote)
ok_reduc = _ok(res.reduction, exp_reduc)
test_ok = ok_impot and ok_decote and ok_reduc
if verbose:
print(
f"Test {params} -> obtenu (impôt={res.impot}, décote={res.decote}, réduction={res.reduction}) | attendu {expected} | {'OK' if test_ok else 'ECHEC'}")
if not test_ok:
print(
f" Détails tolérance ±1€ : impôt ok? {ok_impot}, décote ok? {ok_decote}, réduction ok? {ok_reduc}")
all_ok &= test_ok
if verbose:
print("\nRésultat global :", "TOUS LES TESTS PASSENT ✅" if all_ok else "AU MOINS UN TEST ÉCHOUE ❌")
return all_ok
if __name__ == "__main__":
run_tests()
- Lignes 11-24, les 14 tests imposés ;
- Lignes 5-55 : ce code vient du script généré par ChatGPT. On va imposer à Gemini d’utiliser ce code pour faciliter les comparaisons entre les deux scripts générés.
On commence par ChatGPT :
![]() |
Sa première réponse est incorrecte. Je le lui dis en lui donnant les logs de l’exécution :
![]() | ![]() |
Sa deuxième réponse est la bonne. ChatGPT a rajouté les 11 tests suivants aux 14 tests imposés :
Il y a maintenant 25 tests unitaires. J’ai vérifié manuellement les 11 nouveaux tests avec le simulateur officiel de la DGIP et c’est bon.
Maintenant, on passe à Gemini. Cela va être beaucoup plus compliqué. Il va réussir à générer un script qui passe les 25 tests de ChatGPT mais après un long débogage.
![]() |
Ci-dessous, la liste du débogage :
![]() |
Bizarrement, une majorité de tests a échoué même parmi les 14 imposés alors que par le passé Gemini avait généré du code qui les passait tous.
La réponse suivante de Gemini n’est toujours pas correcte :
![]() |
La réponse suivante non plus :
![]() |
La réponse suivante non plus. Du coup je change mon fusil d’épaule. Je lui demande de réussir les 25 tests qu’a réussis ChatGPT en lui joignant les logs de ChatGPT :
![]() |
Gemini échoue. Il a bien ajouté les tests de ChatGPT. Je lui joins les logs de son exécution :
![]() |
Toujours pas :
![]() |
Toujours pas :
![]() |
Toujours pas :
![]() |
Toujours pas mais c’est mieux :
![]() |
Gemini fait de nouvelles erreurs :
![]() |
Il s’améliore de nouveau :
![]() |
Cette fois, c’est bon :
![]() | ![]() |
Indiscutablement, sur cet exemple précis du calcul de l’impôt 2019 avec les contraintes placées dans le fichier des instructions, ChatGPT a été plus pertinent que Gemini. Mais ce n’est qu’un exemple.
On peut aller plus loin. On peut demander à Gemini de régénérer un PDF selon les règles de calcul qu’il a utilisées pour réussir les 25 tests. On veut voir s’il a changé son raisonnement premier sur les calculs de la décote et de la réduction de 20% :
![]() | ![]() |
Cette fois-ci, Gemini a généré un fichier MarkDown que j’ai ensuite transformé en PDF [Le problème selon Gemini version 2]. Et Gemini a effectivement changé son raisonnement :
![]() |
![]() |
On constate qu’il n’y a plus le calcul particulier de la décote ni la règle de repêchage. Gemini a désormais adopté le raisonnement de ChatGPT.























































