5. Risoluzione dei tre problemi con ChatGPT
5.1. Introduzione
Ecco una prima schermata di una sessione ChatGPT:
![]() ![]() |
- In [1-3], i tre problemi posti in ChatGPT;
- In [4], il URL di ChatGPT;
- In [5], la versione di ChatGPT utilizzata;
ChatGPT è un prodotto derivato da OpenAI, disponibile in URL e [https://chatgpt.com/]. Per avere una cronologia delle vostre sessioni di domande e risposte come quella sopra riportata, è necessario creare un account. Inoltre, come tutte le altre versioni testate, IA limita il numero di domande e il numero di file scaricati. Una volta raggiunto tale limite, la sessione termina e viene proposto di riprenderla in un secondo momento. I limiti imposti da ChatGPT vengono raggiunti molto rapidamente. Per realizzare questo tutorial, ho dovuto sottoscrivere un abbonamento a pagamento di un mese.
L'interfaccia di ChatGPT è la seguente:
![]() |
- In [1], per allegare file alla domanda posta;
- In [2], la domanda posta;
- In [3], per avviare l’esecuzione di IA;
5.2. Il problema 1
La domanda in ChatGPT:
![]() |
ChatGPT risponde correttamente.
5.3. Problema 2
Si tratta del calcolo dell’imposta con il PDF. Ad essere onesti, useremo il PDF generato da Gemini, che corregge gli errori del PDF iniziale.
![]() |
- Nel [1] abbiamo inserito il PDF generato da Gemini;
- Nel file [2] è stato aggiunto il test unitario con cui Gemini ha dimostrato la propria superiorità:
Si avvia ChatGPT. Impiega circa 3 minuti per generare la risposta. A differenza di Gemini, fornisce effettivamente un link funzionante per recuperare lo script generato. Lo si carica in PyCharm:
![]() |
Lo script [chatGPT1] funziona al primo colpo. Non c’è proprio paragone: su questo problema, ChatGPT ha dato risultati migliori rispetto a Gemini.
Lo script [chatGPT1] fornito da ChatGPT è il seguente:
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
Ora chiediamo a ChatGPT di cercare su Internet le regole di calcolo dell’imposta:
![]() |
Questa volta non forniamo il PDF che indicava le regole di calcolo da seguire. Forniamo solo le nostre istruzioni nel file di testo. Ricordiamo che questo file di testo contiene ora 12 test unitari, dopo aver aggiunto a quelli iniziali (11) quello utilizzato da Gemini per dimostrare che il mio PDF iniziale era errato.
ChatGPT risponde in 8 minuti, fornendo un link per scaricare lo script generato. Una volta caricato in PyCharm, questo script supera tutti e 12 i test. Pertanto, alle due domande poste, ChatGPT ha risposto correttamente al primo tentativo, superando così Gemini.
ChatGPT fornisce i propri riferimenti nella risposta:
![]() |
Non c’è altro da dire, è un ottimo lavoro.
Ora possiamo chiedergli, come abbiamo fatto con Gemini, di generare un PDF per gli studenti.
![]() |
La risposta ChatGPT è stata ottenuta dopo diversi tentativi, poiché il PDF generato utilizzava un font che sostituiva i caratteri con un quadrato. Ma alla fine ha generato il PDF. Lo riporto perché fornisce regole diverse rispetto al PDF di Gemini e mi sono quindi chiesto chi avesse ragione. Approfondiremo la questione.
![]() |
![]() |
![]() | ![]() |
![]() |
La differenza rispetto al codice PDF di Gemini sta nel calcolo dello sconto. I due codici IA non seguono lo stesso approccio. Gemini aveva scritto:
![]() |
![]() |
![]() |
I due IA presentano due approcci diversi. Chi ha ragione?
5.5. Il problema 4
Chiederemo a ChatGPT di basarsi sul suo PDF per calcolare l’imposta:
![]() | ![]() |
Come nelle volte precedenti, genera uno script Python che funziona al primo colpo. Nelle istruzioni avevamo aggiunto un test supplementare:
Tutti e 13 i test sono stati superati con successo.
5.6. Ritorno su Gemini
Ora torniamo a Gemini, a cui presenteremo il PDF derivato da ChatGPT. Dato che le regole implementate in questo PDF sono diverse da quelle implementate nel PDF di Gemini, ci si può chiedere cosa succederà:
![]() |
Gemini ha inizialmente generato uno script Python che non superava i test. Le sono stati presentati i log:
Domanda 2
![]() |
Domanda 3
Ci sono ancora degli errori. Continuiamo.
![]() |
Domanda 4
Ci sono ancora degli errori durante l'esecuzione:
![]() |
Questa volta va bene.
Ci incuriosisce comunque il fatto che, pur avendo regole di calcolo piuttosto diverse, sia PDF che IA generino entrambi risultati corretti.
Poniamo la seguente domanda a Gemini:
![]() |
La domanda completa è la seguente:
La risposta di Gemini è categorica:
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
5.7. Cosa ne pensa ChatGPT
Poniamo a ChatGPT la stessa domanda posta a Gemini.
![]() |
La risposta di ChatGPT è la seguente:
![]() |
![]() |
Di conseguenza, ChatGPT ci propone un test unitario per distinguere i due metodi. Duplichiamo:
- Lo script [gemini3] generato da Gemini utilizzando come fonte il suo PDF; [Le problème selon Gemini] viene duplicato nello script [gemini4];
- Lo script [chatGPT3] generato da ChatGPT utilizzando come fonte i propri script PDF e [Le problème selon ChatGPT] viene duplicato nello script [chatGPT4];
![]() | ![]() |
Inoltre, in ciascuno degli script [gemini4, chatGPT4] viene aggiunto il test unitario proposto da ChatGPT per distinguere i due IA.
L'esecuzione di [gemini4] fornisce i seguenti risultati:
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
Pertanto, Gemini non supera il test aggiunto da ChatGPT.
L'esecuzione di [chatGPT4] fornisce i seguenti risultati:
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
Anche ChatGPT non supera il test aggiunto, ma non per gli stessi motivi di Gemini. ChatGPT ha trovato i risultati corretti, ma con uno scarto di 2 euro invece dell’1 euro richiesto.
Pertanto, d’ora in poi utilizzeremo il PDF generato da ChatGPT insieme ai successivi IA. Va notato che è proprio a causa della mancanza di test unitari nelle mie istruzioni che entrambi i IA hanno superato i primi test. Da qui, in questo specifico esempio, l’importanza di inserire test unitari per i casi limite del calcolo dell’imposta. Poiché è piuttosto difficile immaginare da soli questi test. Chiederemo ai IA di aggiungerne di propri.
5.8. Il problema 3 con i test unitari generati dai IA
I risultati ottenuti con Gemini e ChatGPT lasciano qualche dubbio. Le IA hanno trovato una soluzione generale che supera tutti i test immaginabili o hanno trovato una soluzione che supera solo i test imposti? Ripartiremo da una soluzione senza PDF per costringere le IA a cercare su Internet le informazioni di cui hanno bisogno. E modifichiamo le nostre istruzioni nel modo seguente:
![]() |
Il file di testo [instructionsSansPDF4.txt] contiene già 14 test obbligatori. A questi test aggiungiamo le seguenti istruzioni:
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.
# =========================
# Test unitari (tolleranza di ±1 €)
# =========================
TESTS = [
# (adulti, bambini, redditi) -> (imposta, sconto, riduzione)
((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()
- Righe 11-24: i 14 test predefiniti;
- Righe 5-55: questo codice proviene dallo script generato da ChatGPT. Imporremo a Gemini di utilizzare questo codice per facilitare i confronti tra i due script generati.
Si inizia con ChatGPT:
![]() |
La sua prima risposta è errata. Glielo segnalo fornendogli i log dell’esecuzione:
![]() | ![]() |
La sua seconda risposta è corretta. ChatGPT ha aggiunto i seguenti 11 test ai 14 test richiesti:
Ora ci sono 25 test unitari. Ho verificato manualmente gli 11 nuovi test con il simulatore ufficiale di DGIP e tutto è a posto.
Ora passiamo a Gemini. Sarà molto più complicato. Riuscirà a generare uno script che superi i 25 test di ChatGPT, ma solo dopo un lungo processo di debug.
![]() |
Di seguito, l’elenco del debug:
![]() |
Stranamente, la maggior parte dei test è fallita anche tra i 14 richiesti, mentre in passato Gemini aveva generato codice in grado di superarli tutti.
La seguente risposta di Gemini non è ancora corretta:
![]() |
E nemmeno la risposta seguente:
![]() |
E nemmeno la risposta seguente. A questo punto cambio strategia. Gli chiedo di superare i 25 test che ChatGPT ha superato, allegando i log di ChatGPT:
![]() |
Gemini fallisce. Ha comunque aggiunto i test di ChatGPT. Gli allego i log della sua esecuzione:
![]() |
Ancora niente:
![]() |
Ancora niente:
![]() |
Ancora niente:
![]() |
Ancora no, ma va meglio:
![]() |
Gemini commette nuovi errori:
![]() |
Sta migliorando di nuovo:
![]() |
Questa volta è tutto a posto:
![]() |
Indubbiamente, in questo specifico esempio di calcolo dell’imposta 2019 con i vincoli specificati nel file delle istruzioni, ChatGPT si è dimostrato più efficace di Gemini. Ma si tratta solo di un esempio.
Si può andare oltre. Si può chiedere a Gemini di rigenerare un PDF secondo le regole di calcolo che ha utilizzato per superare i 25 test. Vogliamo vedere se ha modificato il suo ragionamento iniziale sui calcoli dello sconto e della riduzione del 20%:
![]() | ![]() |
Questa volta, Gemini ha generato un file MarkDown che ho poi trasformato in PDF [Le problème selon Gemini version 2]. E Gemini ha effettivamente modificato il proprio ragionamento:
![]() |
![]() |
Si nota che non è più presente né il calcolo specifico dello sconto né la regola di ripescaggio. Gemini ha ora adottato il ragionamento di ChatGPT.






















































