5. Resolución de los tres problemas con ChatGPT
5.1. Introducción
Aquí hay una primera captura de pantalla de una sesión de ChatGPT:
![]() ![]() |
- En [1-3], los tres problemas planteados a ChatGPT;
- En [4], la URL de ChatGPT;
- En [5], la versión de ChatGPT utilizada;
ChatGPT es un producto de OpenAI disponible en la URL [https://chatgpt.com/]. Para ver un historial de tus sesiones de preguntas y respuestas como la anterior, debes crear una cuenta. Además, al igual que todas las demás IA probadas, ChatGPT limita el número de preguntas que puedes hacer y el número de archivos que puedes subir. Cuando se alcanza este límite, la sesión finaliza y se te ofrece la opción de continuar más tarde. Los límites impuestos por ChatGPT se alcanzan muy rápidamente. Para crear este tutorial, tuve que adquirir una suscripción de pago de un mes.
La interfaz de ChatGPT es la siguiente:
![]() |
- En [1], para adjuntar archivos a la pregunta formulada;
- En [2], la pregunta formulada;
- En [3], para ejecutar la IA;
5.2. Problema 1
La pregunta para ChatGPT:
![]() |
ChatGPT responde correctamente.
5.3. Problema 2
Esto implica calcular el impuesto utilizando el PDF. Para ser sinceros, utilizaremos el PDF generado por Gemini, que corrige los errores del PDF original.
![]() |
- En [1], proporcionamos el PDF generado por Gemini;
- En [2], añadimos la prueba unitaria mediante la cual Gemini demostró su superioridad:
Ejecutamos ChatGPT. Tarda unos 3 minutos en generar su respuesta. A diferencia de Gemini, sí proporciona un enlace válido para recuperar el script generado. Lo cargamos en PyCharm:
![]() |
El script [chatGPT1] funciona a la primera. No hay duda: en este problema, ChatGPT ha superado a Gemini.
El script [chatGPT1] proporcionado por ChatGPT es el siguiente:
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. Problema 3
Ahora le pedimos a ChatGPT que busque en Internet las reglas de cálculo de impuestos:
![]() |
Esta vez, no proporcionamos el PDF que contenía las reglas de cálculo a seguir. Solo proporcionamos nuestras instrucciones en el archivo de texto. Tenga en cuenta que este archivo de texto contiene ahora 12 pruebas unitarias tras añadir, a las 11 pruebas iniciales, la que utilizó Gemini para demostrar que mi PDF inicial era incorrecto.
ChatGPT responde en 8 minutos, proporcionando un enlace para descargar el script generado. Una vez cargado en PyCharm, este script supera las 12 pruebas. Así pues, en ambos problemas planteados, ChatGPT acertó las respuestas a la primera, superando así a Gemini.
ChatGPT proporciona sus fuentes en su respuesta:
![]() |
No hay nada más que decir: es un trabajo bien hecho.
Ahora podemos pedirle, igual que hicimos con Gemini, que genere un PDF para los alumnos.
![]() |
La respuesta de ChatGPT llegó tras varios intercambios de mensajes, ya que el PDF generado utilizaba una fuente que sustituía los caracteres por cuadrados. Pero, finalmente, generó el PDF. Lo comparto porque ofrece reglas diferentes a las del PDF de Gemini, y me preguntaba cuál de los dos era el correcto. Vamos a investigarlo.
![]() |
![]() |
![]() | ![]() |
![]() |
La diferencia con respecto al PDF de Gemini radica en cómo se calcula el descuento. Las dos IA adoptan enfoques diferentes. Gemini había escrito:
![]() |
![]() |
![]() |
Las dos IA tienen dos enfoques diferentes. ¿Cuál es el correcto?
5.5. Problema 4
Le pediremos a ChatGPT que utilice su PDF para calcular el impuesto:
![]() | ![]() |
Al igual que en ocasiones anteriores, genera un script de Python que funciona a la primera. Habíamos añadido una prueba adicional a las instrucciones:
Las 13 pruebas se superaron con éxito.
5.6. Volver a Gemini
Ahora volvemos a Gemini, donde le presentaremos el PDF de ChatGPT. Dado que las reglas aplicadas en este PDF difieren de las del PDF de Gemini, nos preguntamos qué sucederá:
![]() |
Gemini generó primero un script en Python que falló en algunas pruebas. Le presentamos los registros:
Pregunta 2
![]() |
Pregunta 3
Todavía hay errores. Sigamos.
![]() |
Pregunta 4
Sigue habiendo errores durante la ejecución:
![]() |
Esta vez es correcto.
Nos sigue intrigando que, incluso con archivos PDF que tienen reglas de cálculo bastante diferentes, ambas IA generen resultados correctos.
Le hacemos la siguiente pregunta a Gemini:
![]() |
La pregunta completa es la siguiente:
La respuesta de Gemini es inequívoca:
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
5.7. ¿Qué opina ChatGPT?
Le hacemos a ChatGPT la misma pregunta que le hicimos a Gemini.
![]() |
La respuesta de ChatGPT es la siguiente:
![]() |
![]() |
Así pues, ChatGPT sugiere una prueba unitaria para decidir entre los dos métodos. Duplicamos:
- El script [gemini3] generado por Gemini utilizando su PDF [El problema según Gemini] como fuente se duplica en el script [gemini4];
- El script [chatGPT3] generado por ChatGPT utilizando su PDF [El problema según ChatGPT] como fuente se duplica en el script [chatGPT4];
![]() | ![]() |
Además, añadimos la prueba unitaria propuesta por ChatGPT a cada uno de los scripts [gemini4, chatGPT4] para distinguir entre las dos IA.
Al ejecutar [gemini4] se obtienen los siguientes resultados:
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
Así pues, Gemini no supera la prueba añadida por ChatGPT.
Al ejecutar [chatGPT4] se obtienen los siguientes resultados:
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 también suspende la prueba añadida, pero no por las mismas razones que Gemini. ChatGPT encontró los resultados correctos, pero se desvió en 2 euros en lugar del 1 euro requerido.
Así que, a partir de ahora, utilizaremos el PDF generado por ChatGPT con las siguientes IA. Cabe señalar que es debido a la falta de pruebas unitarias en mis instrucciones que ambas IA superaron las primeras pruebas. De ahí, en este ejemplo concreto, la importancia de incluir pruebas unitarias para casos extremos en el cálculo de impuestos. Dado que es bastante difícil idear estas pruebas por uno mismo, pediremos a las IA que las añadan ellas mismas.
5.8. Problema 3 con pruebas unitarias generadas por las IA
Los resultados obtenidos con Gemini y ChatGPT dejan lugar a dudas. ¿Encontraron las IA una solución general que supera todas las pruebas imaginables, o encontraron una solución que solo supera las pruebas requeridas? Empezaremos de nuevo con una solución sin PDF para obligar a las IA a conectarse a Internet y buscar la información que necesitan. Y modificaremos nuestras instrucciones de la siguiente manera:
![]() |
El archivo de texto [instructionsSansPDF4.txt] ya contiene 14 pruebas obligatorias. A estas pruebas añadimos las siguientes instrucciones:
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()
- Líneas 11-24: las 14 pruebas requeridas;
- Líneas 5-55: este código procede del script generado por ChatGPT. Le pediremos a Gemini que utilice este código para facilitar las comparaciones entre los dos scripts generados.
Empezaremos con ChatGPT:
![]() |
Su primera respuesta es incorrecta. Se lo indico proporcionándole los registros de ejecución:
![]() | ![]() |
Su segunda respuesta es correcta. ChatGPT añadió las siguientes 11 pruebas a las 14 pruebas requeridas:
Ahora hay 25 pruebas unitarias. He verificado manualmente las 11 pruebas nuevas utilizando el simulador oficial de DGIP, y han superado las pruebas.
Ahora pasamos a Gemini. Esto va a ser mucho más complicado. Conseguirá generar un script que supere las 25 pruebas de ChatGPT, pero solo tras un largo proceso de depuración.
![]() |
A continuación se muestra el registro de depuración:
![]() |
Curiosamente, la mayoría de las pruebas fallaron, incluso entre las 14 obligatorias, mientras que en el pasado Gemini había generado código que las superaba todas.
La siguiente respuesta de Gemini sigue siendo incorrecta:
![]() |
Tampoco lo es la siguiente respuesta:
![]() |
Tampoco lo es la siguiente respuesta. Así que voy a cambiar de estrategia. Le voy a pedir que supere las 25 pruebas que superó ChatGPT, adjuntando los registros de ChatGPT:
![]() |
Gemini falla. Sí que añadió las pruebas de ChatGPT. Adjunto los registros de su ejecución:
![]() |
Sigue sin funcionar:
![]() |
Todavía no:
![]() |
Todavía no:
![]() |
Todavía no, pero está mejor:
![]() |
Gemini está cometiendo nuevos errores:
![]() |
Vuelve a mejorar:
![]() |
Esta vez está bien:
![]() |
Sin duda, en este ejemplo concreto de cálculo del impuesto de 2019 con las restricciones especificadas en el archivo de instrucciones, ChatGPT fue más preciso que Gemini. Pero esto es solo un ejemplo.
Podemos ir más allá. Podemos pedirle a Gemini que vuelva a generar un PDF basándose en las reglas de cálculo que utilizó para superar las 25 pruebas. Queremos ver si ha cambiado su razonamiento inicial con respecto a los cálculos del descuento y la reducción del 20 %:
![]() | ![]() |
Esta vez, Gemini generó un archivo Markdown que luego convertí a PDF [El problema según Gemini, versión 2]. Y, efectivamente, Gemini ha cambiado su razonamiento:
![]() |
![]() |
Podemos ver que el cálculo específico del descuento y la regla de transferencia ya no están presentes. Gemini ha adoptado ahora el razonamiento de ChatGPT.






















































