Skip to content

4. Lösung der drei Probleme mit Google Gemini

Wir werden Screenshots von drei Gemini-Sitzungen geben, in denen die drei gestellten Probleme gelöst wurden. Wir werden ziemlich ins Detail gehen. Nachdem dies geschehen ist, werden wir den Vorgang für die anderen getesteten IA nicht wiederholen. Sie funktionieren auf ähnliche Weise. Wir werden nur auf die auffälligen Details eingehen.

4.1. Einführung

Wir erinnern an den ersten Screenshot von Gemini, der zuvor gegeben wurde:

 
  • In [1] wurde der URL von Gemini ;
  • In [2] wurde die verwendete Version von Gemini ;
  • In [3-5] werden die drei Probleme, die Gemini gestellt wurden ;

Gemini ist ein Produkt von Google, das unter URL [https://gemini.google.com/] erhältlich ist. Um einen Verlauf Ihrer Frage-/Antwort-Sitzungen wie oben beschrieben zu erhalten, müssen Sie ein Konto einrichten. Außerdem begrenzt Gemini, wie alle anderen getesteten IA, die Anzahl Ihrer Fragen und die Anzahl der hochgeladenen Dateien. Wenn dieses Limit erreicht ist, ist die Sitzung beendet und Ihnen wird angeboten, sie zu einem späteren Zeitpunkt fortzusetzen. Da es ziemlich frustrierend ist, mitten in einer Sitzung aufzuhören, habe ich ai ein Abonnement abgeschlossen. Der erste Monat des Gemini-Abonnements ist glücklicherweise kostenlos. Ich ai tat das Gleiche mit den anderen IA, die diese Einschränkungen hatten, nämlich ChatGPT, MistralAI, ClaudeAI. Ich ai nahm ein Abonnement für einen Monat, aber dort war der erste Monat kostenpflichtig. Ich ai bei Grok nicht auf Grenzen gestoßen. DeepSeek kündigt keine Limits an, antwortet aber manchmal [Server busy] und bricht die Sitzung ab. Das läuft auf das Setzen von Limits hinaus, ohne es anzukündigen.

Im Folgenden werde ich von einer Frage-/Antwort-Sitzung sprechen, die auf eine einfache Sitzung verkürzt wird. Die IA verwenden am häufigsten den englischen Begriff katze (Diskussion) oder Konversation.

Die Schnittstelle von Gemini, um eine Frage zu stellen, sieht folgendermaßen aus:

  • In [1] ist Ihre Frage ;
  • In [2] das Symbol, das den IA zur Berechnung der Antwort startet ;
  • In [3-4] können Sie Dateien anhängen ;

4.2. Das Problem 1

Die Sitzung für Problem 1 lautet wie folgt:

 
  • In [1] wurde die Frage ;
  • In [2] der Anfang von Geminis Antwort ;

Der Rest der Antwort lautet wie folgt:

 
 
 
 

Die Antwort ist richtig. Auch die anderen fünf IA geben die richtige Antwort in ähnlicher Form.

4.3. Das Problem 2

4.3.1. Einführung

Wir erinnern ici an das ursprüngliche Problem aus dem Kurs [python3-flask-2020]. Dies ist ein Text, der in TD an Studenten gegeben wurde.

 

Die obige Tabelle ermöglicht die Berechnung der Steuer im vereinfachten Fall eines Steuerpflichtigen, der nur sein einziges Gehalt zu versteuern hat. Wie aus Anmerkung (1) hervorgeht, ist die so berechnete Steuer die Steuer vor drei Mechanismen:

  • Die Obergrenze des Familienquotienten, die bei hohen Einkommen greift ;
  • Der Abschlag und die Steuerermäßigung, die bei niedrigen Einkommen greifen ;

So umfasst die Berechnung der Steuer folgende Schritte [http://impotsurlerevenu.org/comprendre-le-calcul-de-l-impot/1217-calcul-de-l-impot-2019.php] :

 

Es soll ein Programm geschrieben werden, mit dem die Steuer eines Steuerpflichtigen im Jahr 2019 im vereinfachten Fall eines Steuerpflichtigen berechnet werden kann, der nur sein einziges Gehalt zu versteuern hat.

4.3.1.1. Berechnung der Bruttosteuer

Die Bruttosteuer kann wie folgt berechnet werden:

Zunächst wird die Anzahl der Anteile des Steuerzahlers berechnet:

  • Jeder Elternteil bringt 1 Teil mit;
  • Die ersten beiden Kinder bringen jeweils 1/2 Anteil mit;
  • Die folgenden Kinder bringen jeweils einen Anteil mit:

Die Anzahl der Anteile ist also :

  • nbParts=1+nbEnfants*0,5+(nbEnfants-2)*0,5 wenn der Arbeitnehmer nicht verheiratet ist ;
  • nbParts=2+nbEnfants*0,5+(nbEnfants-2)*0,5 s'il est marié ;
  • wobei nbEnfants ist ihre Anzahl an Kindern ;
  • Man berechnet das zu versteuernde Einkommen R=0.9*S wobei S ist das Jahresgehalt ;
  • Man berechnet den Familienquotienten QF=R/nbParts ;
  • Man berechnet die Bruttosteuer I nach den folgenden Daten (2019) :
9964
0
0
27519
0.14
1394.96
73779
0.3
5798
156244
0.4
13913.69
0
0.45
20163.45

Jede Zeile hat drei Felder: feld1, feld2, feld3. Um die Steuer I zu berechnen, wird die erste Zeile gesucht, in der QF<=champ1 und nehmen die Werte aus dieser Zeile. Zum Beispiel für einen verheirateten Arbeitnehmer mit zwei Kindern und einem Jahresgehalt S von 50000 euro:

Steuerpflichtiges Einkommen : R=0,9*S=45000

Anzahl der Anteile : nbParts=2+2*0,5=3

Familienquotient : QF=45000/3=15000

Die 1re zeile, in der QF<=Feld1 ist, ist die folgende:

    27519    0.14    1394.96

Die Steuer I ist dann gleich 0.14*R - 1394,96*nbParts=[0,14*45000-1394,96*3]=2115. Die Steuer wird auf den nächsten vollen Euro abgerundet.

Wenn die Beziehung QF<=champ1 ab der 1re zeile, dann ist die Steuer null.

Wenn QF so beschaffen ist, dass die Beziehung QF<=champ1 nie überprüft wird, dann werden die Koeffizienten aus der letzten Zeile verwendet. Ici :

    0    0.45    20163.45

was die Bruttosteuer I= ergibt 0.45*R - 20163,45*nbParts.

4.3.1.2. Begrenzung des Familienquotienten

 

Um herauszufinden, ob die Obergrenze für den Familienquotienten QF gilt, wird die Bruttosteuerberechnung ohne Kinder erneut durchgeführt. Immer noch für den verheirateten Arbeitnehmer mit zwei Kindern und einem Jahresgehalt S von 50000 euro:

Steuerpflichtiges Einkommen : R=0,9*S=45000

Anzahl der Anteile : nbParts=2 (die Kinder werden nicht mehr gezählt)

Familienquotient : QF=45000/2=22500

Die 1re zeile, in der QF<=Feld1 ist, ist die folgende:

    27519    0.14    1394.96

Die Steuer I ist dann gleich 0.14*R - 1394,96*nbParts=[0,14*45000-1394,96*2]=3510.

Maximaler kinderbezogener Gewinn: 1551 * 2 = 3102 Euro

Mindeststeuer: 3510-3102 = 408 Euro

Die bereits im vorherigen Absatz berechnete Bruttosteuer mit zwei Anteilen 2115 Euro ist höher als die Mindeststeuer 408 Euro, daher wird die Familienobergrenze nicht angewendet ici.

Im Allgemeinen ist die Bruttosteuer sup(steuer1, steuer2) wobei :

  • [Steuer1] : ist die mit den Kindern berechnete Bruttosteuer ;
  • [Steuer2] : ist die Bruttosteuer, die ohne Kinder berechnet und um den maximalen Gewinn (ici 1551 Euro pro halben Anteil) durch die Kinder verringert wird ;

4.3.1.3. Berechnung des Abschlags

 

Immer für den verheirateten Arbeitnehmer mit zwei Kindern und einem Jahresgehalt S von 50000 euro:

Die Bruttosteuer (2115 Euro) aus dem vorherigen Schritt ist für ein Paar niedriger als 2627 Euro (1595 Euro für einen Alleinstehenden): Der Freibetrag kommt also zur Anwendung. Sie ergibt sich aus der folgenden Berechnung:

décote= seuil (couple=1970/célibataire=1196)-0,75* Impôt brut

décote=1970-0,75*2115=383,75 arrondi à 384 euros.

Neue Brutto-Steuer= 2115-384= 1731 euro

Bei der Berechnung des Abschlags sind zwei Regeln zu beachten (einige IA-Tools sind an dieser Frage gescheitert):

  • Der Abschlag kann nicht negativ sein ;
  • Der Abschlag darf nicht höher sein als die bereits berechnete Steuer ;

4.3.1.4. Berechnung der Steuersenkung

 

Unterhalb eines bestimmten Schwellenwerts wird eine Ermäßigung von 20 % auf die aus den vorherigen Berechnungen hervorgegangene Bruttosteuer vorgenommen. Im Jahr 2019 lauten die Schwellenwerte wie folgt:

  • ledig: 21037 Euro ;
  • paar: 42074 Euro; (die im obigen Beispiel verwendete Zahl 37968 scheint falsch zu sein) ;

Dieser Schwellenwert wird um den Wert: 3797 * (Anzahl der von den Kindern mitgebrachten halben Anteile) erhöht.

Immer für den verheirateten Arbeitnehmer mit zwei Kindern und einem Jahresgehalt S von 50000 euro:

  • Sein zu versteuerndes Einkommen (45000 Euro) liegt unter dem Schwellenwert (42074+2*3797)=49668 Euro ;
  • Er hat also Anspruch auf eine Steuersenkung von 20 %: 1731 * 0,2= 346,2 Euro abgerundet auf 347 Euro ;
  • Die Bruttosteuer des Steuerzahlers wird zu: 1731-347= 1384 euro;

4.3.1.5. Steuerberechnung net

Unsere Berechnung endet hier: Die zu zahlende Steuer net beträgt 1384 euro in Anspruch nehmen. In der Realität kann der Steuerzahler von weiteren Ermäßigungen profitieren, insbesondere für Spenden an Organisationen von öffentlichem oder allgemeinem Interesse.

4.3.1.6. Fall von hohem Einkommen

Unser vorheriges Beispiel entspricht den meisten Fällen von Arbeitnehmern. Bei hohen Einkommen ist die Steuerberechnung jedoch anders.

4.3.1.6.1.

4.3.1.6.2. Obergrenze für die 10%ige Ermäßigung auf das Jahreseinkommen

In den meisten Fällen ergibt sich das zu versteuernde Einkommen aus der Formel: R=0,9*S, wobei S das Jahresgehalt ist. Dies wird als 10 %-Ermäßigung bezeichnet. Für diese Ermäßigung gibt es eine Obergrenze. Im Jahr 2019 :

  • Sie darf nicht mehr als 12502 Euro betragen ;
  • Sie darf nicht weniger als 437 Euro betragen ;

Nehmen wir den Fall eines unverheirateten Arbeitnehmers ohne Kinder und einem Jahresgehalt von 200.000 Euro an:

  • Die 10 %ige Ermäßigung beträgt 20000 Euro > 12502 Euro. Sie wird also auf 12502 Euro gesenkt ;
4.3.1.6.3.

4.3.1.6.4. Begrenzung des Familienquotienten

Nehmen wir einen Fall an, in dem die in Absatz || dargestellte FamilienobergrenzeBegrenzung des Familienquotienten|, greift ein. Nehmen wir den Fall eines Paares mit drei Kindern und einem Jahreseinkommen von 100.000 Euro an. Gehen wir die Rechenschritte noch einmal durch:

  • Der Freibetrag von 10 % beträgt 100000 Euro < 12502 Euro. Das zu versteuernde Einkommen R ist also 100000-10000=90000 Euro;
  • Das Paar hat nbParts=2+0,5*2+1=4 anteile ;
  • Ihr Familienquotient ist also QF= R/nbParts=90000/4=22500 euro;
  • Seine Bruttosteuer I1 mit kinder ist I1=0,14*90000-1394,96*4= 7020 Euro;
  • Seine Bruttosteuer I2 ohne kinder :
    • QF=90000/2=45000 euros ;
    • I2=0,3*90000-5798*2=15404 euros ;
  • Die Regel zur Begrenzung des Familienquotienten besagt, dass der durch die Kinder erzielte Gewinn nicht mehr als (1551*4 halbe Anteile)=6204 Euro betragen darf. In ici beträgt er jedoch I2-I1=15404-7020= 8384 Euro, also mehr als 6204 Euro;
  • Die Bruttosteuer wird also neu berechnet als I3=I2-6204=15404-6204= 9200 euro;
  • Da I3>I1 ist, wird die Steuer I3 einbehalten;

Dieses Paar hat weder einen Abschlag noch eine Ermäßigung und seine endgültige Steuer beträgt 9200 euro.

4.3.1.7. Offizielle Zahlen

Die Berechnung der Steuer ist komplex. Im gesamten Dokument werden Tests mit den folgenden Beispielen durchgeführt. Die Ergebnisse stammen aus dem Simulator der Steuerbehörde |https://www3.impots.gouv.fr/simulateur/calcul_impot/2019/simplifie/index.htm| :

Steuerzahler
Offizielle Ergebnisse
Ergebnisse des Dokumentalgorithmus
Paar mit 2 Kindern und einem Jahreseinkommen von 55555 Euro
Impôt=2815 euros
Steuersatz=14%
Impôt=2814 euros
Steuersatz=14%
Paar mit 2 Kindern und einem Jahreseinkommen von 50000 Euro
Impôt=1385 euros
Décote=384 euros
Réduction=346 euros
Steuersatz=14%
Impôt=1384 euros
Décote=384 euros
Réduction=347 euros
Steuersatz=14%
Paar mit 3 Kindern und einem Jahreseinkommen von 50000 Euro
Impôt=0 euro
décote=720 euros
Réduction=0 euro
Steuersatz=14%
Impôt=0 euro
décote=720 euros
Réduction=0 euro
Steuersatz=14%
Ledig mit 2 Kindern und einem Jahreseinkommen von 100000 Euro
Impôt=19884 euros
décote=0 euro
Réduction=0 euro
Steuersatz=41%
Impôt=19884 euros
Surcote=4480 euros
décote=0 euro
Réduction=0 euro
Steuersatz=41%
Alleinstehend mit drei Kindern und einem Jahreseinkommen von 100000 Euro
Impôt=16782 euros
décote=0 euro
Réduction=0 euro
Steuersatz=41%
Impôt=16782 euros
Surcote=7176 euros
décote=0 euro
Réduction=0 euro
Steuersatz=41%
Paar mit drei Kindern und einem Jahreseinkommen von 100000 Euro
Impôt=9200 euros
décote=0 euro
Réduction=0 euro
Steuersatz=30%
Impôt=9200 euros
Surcote=2180 euros
décote=0 euro
Réduction=0 euro
Steuersatz=30%
Paar mit 5 Kindern und einem Jahreseinkommen von 100000 Euro
Impôt=4230 euros
décote=0 euro
Réduction=0 euro
Steuersatz=14%
Impôt=4230 euros
décote=0 euro
Réduction=0 euro
Steuersatz=14%
Ledig ohne Kinder und einem Jahreseinkommen von 100000 Euro
Impôt=22986 euros
décote=0 euro
Réduction=0 euro
Steuersatz=41%
Impôt= 22986 euros
Surcote=0 euro
décote=0 euro
Réduction=0 euro
Steuersatz=41%
Paar mit 2 Kindern und einem Jahreseinkommen von 30000 Euro
Impôt=0 euro
décote=0 euro
Réduction=0 euro
Steuersatz=0%
Impôt=0 euro
décote=0 euro
Réduction=0 euro
Steuersatz=0%
Ledig ohne Kinder und einem Jahreseinkommen von 200000 Euro
Impôt=64211 euro
décote=0 euro
Réduction=0 euro
Steuersatz=45%
Impôt= 64210 euros
Surcote=7498 euros
décote=0 euro
Réduction=0 euro
Steuersatz=45%
Paar mit 3 Kindern und einem Jahreseinkommen von 200000 Euro
Impôt=42843 euro
décote=0 euro
Réduction=0 euro
Steuersatz=41%
Impôt=42842 euros
Surcote=17283 euros
décote=0 euro
Réduction=0 euro
Steuersatz=41%

Oben wird als Surcote bezeichnet, was hohe Einkommen aufgrund von zwei Phänomenen zusätzlich zahlen:

  • Die Deckelung des 10%igen Abschlags auf das Jahreseinkommen ;
  • Die Obergrenze des Familienquotienten ;

Dieser Indikator konnte nicht überprüft werden, da der Simulator der Steuerverwaltung ihn nicht ausweist.

Wir sehen, dass der Algorithmus in dem Dokument jedes Mal eine richtige Steuer liefert, allerdings mit einer Fehlerspanne von 1 Euro. Diese Fehlerspanne ergibt sich aus den Rundungen. Alle Geldbeträge werden manchmal auf den nächsten Euro aufgerundet, manchmal auf den nächsten Euro abgerundet. Da ich die offiziellen Regeln nicht kannte, wurden die Geldbeträge im Algorithmus des Dokuments gerundet :

  • Auf den nächsthöheren Euro für Abschläge und Kürzungen ;
  • Auf den nächstniedrigeren Euro für Aufschläge und Abschlusssteuer ;

Wir werden den IA bitten, diese Steuerberechnung durchzuführen.

4.3.2. Einrichten der Gemini-Sitzung

Die an Gemini gestellte Frage wird von zwei Dateien begleitet:

 
  • In [1] wurde die soeben detailliert beschriebene Berechnung in eine PDF gepackt, die Gemini gegeben wird. Gemini wird dort die genauen Regeln für die vereinfachte Berechnung der Steuer 2019 auf das Einkommen 2018 finden ;
  • In [2] unsere Anweisungen ;
  • In [3], um den IA zu starten;

Unsere Anweisungen in der Textdatei [instructionsAvecPDF.txt] lauten wie folgt:

    1. 1 – Äußere dich auf Französisch.
    2.
    3. 2 – Kannst du ein Python-Skript erstellen, mit dem sich die Steuern berechnen lassen, die Familien im Jahr 2019 auf ihre Einkünfte aus dem Jahr 2018 gezahlt haben?
    4. 
    5. 3 - Du kannst dich an dem PDF-Dokument orientieren, das ich angehängt habe und in dem die durchzuführenden Berechnungen erklärt werden.
    6. 
    7. 4 - Du musst auf folgende Punkte achten:
    8. 
    9. - Begrenzung des Familienquotienten. Es sind Schwellenwerte zu überprüfen.
    10. - Berechnung des Abschlags in bestimmten Fällen. Es sind Schwellenwerte zu prüfen.
    11. - Berechnung der 20-prozentigen Ermäßigung in bestimmten Fällen. Es sind Schwellenwerte zu prüfen.
    12. - Begrenzung des Freibetrags von 10 % auf das Jahreseinkommen in bestimmten Fällen.
    13. - Du gehst davon aus, dass alle Einkünfte für den Steuerpflichtigen 1 anzugeben sind, auch wenn das Paar verheiratet ist.
    14. 
    15. 5 - Du fügst dem generierten Skript Unit-Tests für die folgenden Fälle hinzu.
    16. 
    17. In diesen Tests werden folgende Variablen verwendet:
    18. 
    19. adults: Anzahl der Erwachsenen im Steuerhaushalt
    20. children: Anzahl der Kinder im Steuerhaushalt
    21. income: jährliches Nettoeinkommen vor Steuern, d. h. vor der ersten Berechnung des Freibetrags.
    22. Steuer: die zu zahlende Steuer
    23. Abschlag: der eventuelle Abschlag für den Steuerhaushalt
    24. Ermäßigung: die Ermäßigung von 20 % für Geringverdiener
    25. 
    26. Hier sind die 11 zu überprüfenden Tests. Sie wurden alle manuell im offiziellen Simulator
    27. zur Steuerberechnung 2019 [https://www3.impots.gouv.fr/simulateur/calcul_impot/2019/simplifie/index.html].
    28. Wenn du diesen Simulator verwendest, müssen die Einkünfte im Falle eines Paares ausschließlich dem ersten Steuerpflichtigen (Deklarant 1) zugeordnet werden, wobei der zweite Steuerpflichtige (Deklarant 2) ignoriert wird. Wenn man die Einkünfte
    29. auf zwei Steuerpflichtige aufteilt, erhält man nicht das gleiche Ergebnis.
    30. 
    31. Man verwendet die Syntax (Erwachsene, Kinder, Einkünfte) -> (Steuer, Abschlag, Ermäßigung), um anzugeben, dass das Skript die Eingaben
    32. (Erwachsene, Kinder, Einkommen) und die Ergebnisse (Steuer, Abschlag, Ermäßigung) ausgibt;
    33. 
    34. test1: (2,2,55555) -> (2815, 0, 0)
    35. test2: (2, 2, 50000) -> (1385, 384, 346)
    36. test3: (2, 3, 50000) -> (0, 720, 0)
    37. test4: (1,2,100000) -> (19884, 0, 0)
    38. test5: (1,3,100000) -> (16782, 0, 0)
    39. test6: (2, 3, 100000) -> (9200, 0, 0)
    40. test7: (2, 5, 100000) -> (4230, 0, 0)
    41. test8: (1, 0, 100000) -> (22986, 0, 0)
    42. test9: (2, 2, 30000) -> (0, 0, 0)
    43. test10: (1, 0, 200000) -> (64211, 0, 0)
    44. test11: (2, 3, 200000) -> (42843, 0, 0)
    45.
    46. 6 – Es können Rundungsprobleme auftreten. Du gehst wie folgt vor:
    47. – Die zu zahlende Steuer wird auf den nächsten ganzen Euro abgerundet,
    48. – der Abschlag wird auf den nächsten ganzen Euro aufgerundet,
    49. - der Abschlag von 20 % wird auf den nächsten höheren Euro aufgerundet.
    50. - der Freibetrag von 10 % wird auf den nächsten höheren Euro aufgerundet
    51. 
    52. Führe alle Unit-Tests auf den nächsten Euro genau durch, da diese möglichen Rundungsfehler auftreten können.
    53. Versuche nicht, die oben genannten exakten Werte zu erhalten, sondern diese Werte auf 1 Euro genau.
    54.
    55. 7 – Vermeide es, im Internet zu suchen. Das PDF, das ich dir gebe, ist korrekt.
    56. Gib dein Ergebnis erst an, wenn du alle 11 Unit-Tests erfolgreich bestanden hast.
    57.
    58. 8 - Wenn einer der Tests fehlschlägt und du nicht weiterkommst, zeige deine Überlegungen zu diesem Test an,
    59. damit ich dir helfen kann.
    60.
    61. 9- Füge detaillierte Kommentare in das Skript ein, das du erstellst.
    62. Speichere die progressive Bewertungsskala in einer Liste oder einem Wörterbuch und verwende diese Liste oder dieses Wörterbuch
    63. Füge die fest codierten Zahlen (magische Zahlen), die du verwendest, als Konstanten ein.
    64. Verwende Funktionen, um die Rechenschritte voneinander zu trennen.
    65. Schreibe alles auf Französisch.
    66. 
    67. 9 – Zeige den generierten Code nicht auf dem Bildschirm an. Gib mir einfach einen Link, über den ich ihn abrufen kann.
    68. Wenn die Unit-Tests fehlschlagen, gebe ich dir die Logs der Skriptausführung, damit du deine Fehler sehen kannst.
    69.
    70.
    71. 10 – Wenn möglich, gib die Zeit in Minuten und Sekunden an, die du für die Erstellung des angeforderten Skripts benötigt hast.

Diese Anweisungen sind das Ergebnis von sehr vielen Fragen, die Gemini gestellt wurden. Ziemlich schnell wurde klar, dass IA sehr eng gefasst sein muss, wenn man erreichen will, was man will. All dieses Herumprobieren war der Grund dafür, dass die Gemini-Sitzung schließlich wegen Überschreitung der Grenzen abgebrochen wurde. Betrachten wir die weiteren Anweisungen:

  • Zeile 1: Es wird darum gebeten, dass das Gespräch auf Französisch geführt wird. Diese Angabe ist für DeepSeek, der dazu neigte, Englisch zu sprechen ;
  • Zeile 3: Was wir wollen ;
  • Zeile 5: Dem IA wird gesagt, er solle den PDF benutzen, den man ihm gegeben hat;
  • Zeilen 7-14: Eine Reihe von nützlichen Tipps vor allem für Aufgabe 3 ohne PDF. Mehrere IA haben sich bei der Steuerberechnung verlaufen;
  • Zeilen 15-44: die 11 Unit-Tests, die wir in dem generierten script enthalten sehen wollen. Wenn der script generiert ist, führen wir ihn in PyCharm aus und sehen, ob die 11 Tests durchlaufen ;
  • Zeilen 46-53: Ohne diese Anweisungen erzeugten die IA Unit-Tests, die nach genauen Ergebnissen suchten und fehlschlugen;
  • Zeilen 55-56: Ich sage dem IA, dass er nicht ins Internet gehen soll. Die einfachste Lösung ist, den PDF zu verwenden;
  • Zeilen 58-59: Diese Anweisung wurde von den IA nicht befolgt. Ich ai war gezwungen, sie explizit in eine Frage zu schreiben, wenn ich feststellte, dass ein Test fehlgeschlagen war;
  • Zeilen 61-65: Ich gebe an, welche Art von script Python ich möchte ;
  • Zeilen 67-69: Ich hätte einen Link zum Abrufen des erzeugten script bevorzugt, da es einige Zeit dauert, den Code auf dem Bildschirm anzuzeigen. Es stellte sich heraus, dass die meisten IA das nicht können. Die angegebenen Links funktionierten nicht ;
  • Zeilen 71-72: Ich hätte gerne gewusst, wie viel Zeit der IA für die Beantwortung der Frage aufgewendet hat. Nur Gemini konnte mir diese Information geben. Die anderen IA antworteten entweder nicht auf diese Anweisung oder gaben Phantasiezahlen an, die zeigten, dass sie diese Anweisung nicht verstanden;

4.3.3. Geminis Antwort

Geminis erste Antwort lautet wie folgt:

 
  • In [1-4] stellt Gemini Links zu dem Teil des PDF oder der Textdatei mit den Anweisungen bereit, den er zu einem bestimmten Zeitpunkt verwendet ;

Die Fortsetzung lautet wie folgt:

 
  • In [1] behauptet Gemini, dass er alle 11 Unit-Tests erfolgreich durchgeführt hat. Die meisten IA behaupteten dies sowohl bei Problem 2 als auch bei Problem 3, und oftmals funktionierte es nicht, wenn man den generierten script lud. Diese Behauptung ist also mit Vorsicht zu genießen. Für Gemini wird sich dies als wahr erweisen;
  • In [2] ein Link, der sich als nicht funktionierend herausstellen wird;
  • In [3 allein Gemini gab eine realistische Ausführungszeit ;

Der Link [2] funktioniert also nicht. Wir sagen es Gemini :

 

Geminis Antwort :

 
  • In [1] wird der von Gemini erzeugte script Python ;

Wir laden diesen script in PyCharm und führen ihn aus :

 
  • In [1] ist [gemini1] der von Gemini erzeugte script ;

Bei der Ausführung von script treten Compilerfehler auf :


"C:\Program Files\Python313\python.exe" "C:/Program Files/JetBrains/PyCharm 2025.2.0.1/plugins/python-ce/helpers/pycharm/_jb_unittest_runner.py" --path "C:\Data\st-2025\dev\python\code\python-flask-2025-cours\outils ia\chatGPT\chatGPT1.py" 
Testing started at 17:12 ...
Launching unittests with arguments python -m unittest C:\Data\st-2025\dev\python\code\python-flask-2025-cours\outils ia\chatGPT\chatGPT1.py in C:\Data\st-2025\dev\python\code\python-flask-2025-cours

Traceback (most recent call last):
  File "C:\Program Files\JetBrains\PyCharm 2025.2.0.1\plugins\python-ce\helpers\pycharm\_jb_unittest_runner.py", line 38, in <module>
    sys.exit(main(argv=args, module=None, testRunner=unittestpy.TeamcityTestRunner,
             ~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                  buffer=not JB_DISABLE_BUFFERING))
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Program Files\Python313\Lib\unittest\main.py", line 103, in __init__
    self.parseArgs(argv)
    ~~~~~~~~~~~~~~^^^^^^
  File "C:\Program Files\Python313\Lib\unittest\main.py", line 142, in parseArgs
    self.createTests()
    ~~~~~~~~~~~~~~~~^^
  File "C:\Program Files\Python313\Lib\unittest\main.py", line 153, in createTests
    self.test = self.testLoader.loadTestsFromNames(self.testNames,
                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^
                                                   self.module)
                                                   ^^^^^^^^^^^^
  File "C:\Program Files\Python313\Lib\unittest\loader.py", line 207, in loadTestsFromNames
    suites = [self.loadTestsFromName(name, module) for name in names]
              ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^
  File "C:\Program Files\Python313\Lib\unittest\loader.py", line 137, in loadTestsFromName
    module = __import__(module_name)
  File "C:\Data\st-2025\dev\python\code\python-flask-2025-cours\outils ia\chatGPT\chatGPT1.py", line 28, in <module>
    [cite_start]
     ^^^^^^^^^^
NameError: name 'cite_start' is not defined

Process finished with exit code 1

Empty suite
  • Zeile 30, der Kompilierungsfehler. [cite_start] ist eine Markierung, um eine bestimmte Form von Text zu erzeugen ;

Wir packen die obigen Logs in eine Datei [logs gemini1.txt] und geben diese an Gemini :

 

Die Antwort von Gemini lautet dann wie folgt:

 

In PyCharm geladen, erzeugt die Ausführung des neuen script genau denselben Fehler. Wir teilen dies Gemini mit, indem wir ihm erneut die Logs der Ausführung zur Verfügung stellen :

 

Geminis Antwort lautet wie folgt:

 

Dieses Mal ist es gut. Alle elf Unit-Tests sind bestanden. Wir sagen es Gemini :

 

Wer antwortet:

 

Der von Gemini erzeugte script folgte den Anweisungen in der Textdatei [instructionsAvecPDF.txt] :

# -*- Codierung: utf-8 -*-
"""
Skript zur Berechnung der Steuer für 2019 auf Einkünfte aus dem Jahr 2018 in Frankreich,
basierend auf den vereinfachten Regeln, die im PDF-Dokument aufgeführt sind.
"""

import math
import unittest

# --- BERECHNUNGSGRUNDLAGEN FÜR DIE STEUER 2019 ---
# Alle Werte sind dem mitgelieferten Dokument PDF entnommen.

# Obergrenzen für den 10%igen Abschlag auf das Jahreseinkommen
PLAFOND_ABATTEMENT_10_POURCENT = 12502.0
MINIMUM_ABATTEMENT_10_POURCENT = 437.0

# Einkommensteuertabelle 2019
# Struktur: (Höchstgrenze der Steuerklasse, Steuersatz, Abzugsbetrag pro Anteil)
BAREME_IMPOT_2019 = [
    {"seuil": 9964, "taux": 0.0, "deduction_par_part": 0},
    {"seuil": 27519, "taux": 0.14, "deduction_par_part": 1394.96},
    {"seuil": 73779, "taux": 0.30, "deduction_par_part": 5798},
    {"seuil": 156244, "taux": 0.41, "deduction_par_part": 13913.69},
    {"seuil": float('inf'), "taux": 0.45, "deduction_par_part": 20163.45}
]

# Begrenzung des Familienquotienten
GAIN_MAX_DEMI_PART = 1551.0  # Maximaler Verdienst pro zusätzlichem halben Anteil

# Schwellenwerte und Beträge für das Dekokonto
SEUIL_APPLICATION_DECOTE = {"celibataire": 1595.0, "couple": 2627.0}
SEUIL_CALCUL_DECOTE = {"celibataire": 1196.0, "couple": 1970.0}

# Schwellenwerte für die Steuerermäßigung von 20%
SEUIL_BASE_REDUCTION_20 = {"celibataire": 21037.0, "couple": 42074.0}
MAJORATION_SEUIL_REDUCTION_PAR_DEMI_PART = 3797.0


def calculer_nombre_parts(adultes: int, enfants: int) -> float:
"""
Berechnet die Anzahl der Steueranteile des Haushalts.
- Jeder Elternteil bringt 1 Anteil ein.
- Die ersten beiden Kinder bringen jeweils einen halben Anteil ein.
- Die weiteren Kinder bringen jeweils einen Anteil ein.
"""
    if adultes not in [1, 2]:
        raise ValueError("Le nombre d'adultes doit être 1 ou 2.")

    parts = float(adultes)
    if enfants > 0:
        parts += 0.5 * min(enfants, 2)
    if enfants > 2:
        parts += 1.0 * (enfants - 2)

    return parts


def calculer_revenu_imposable(revenus: float) -> float:
"""
Berechnet das steuerpflichtige Nettoeinkommen nach Abzug des Freibetrags von 10 %.
Dieser Freibetrag ist begrenzt.
Der Freibetrag wird auf den nächsten vollen Euro aufgerundet.
"""
    abattement_calcule = revenus * 0.1
    # Der Abschlag ist zwischen einem Minimum und einem Maximum gedeckelt
    abattement = min(PLAFOND_ABATTEMENT_10_POURCENT, max(MINIMUM_ABATTEMENT_10_POURCENT, abattement_calcule))

    # In der Aufgabenstellung wird gefordert, den Abschlag auf den nächsten Euro aufzurunden
    abattement_arrondi = math.ceil(abattement)

    return revenus - abattement_arrondi


def calculer_impot_brut_base(revenu_imposable: float, nombre_parts: float) -> float:
    """
    Berechnet die Bruttosteuer nach dem progressiven Steuertarif.
    """
    if nombre_parts <= 0:
        return 0.0

    quotient_familial = revenu_imposable / nombre_parts

    tranche_applicable = None
    for tranche in BAREME_IMPOT_2019:
        if quotient_familial <= tranche["seuil"]:
            tranche_applicable = tranche
            break

    # Wenn der QF größer als alle Schwellenwerte ist, wird die letzte Scheibe verwendet
    if tranche_applicable is None:
        tranche_applicable = BAREME_IMPOT_2019[-1]

    # Formel zur Berechnung der Bruttosteuer
    impot_brut = (revenu_imposable * tranche_applicable["taux"]) - (
            tranche_applicable["deduction_par_part"] * nombre_parts)

    return max(0.0, impot_brut)


def appliquer_plafonnement_qf(impot_brut_avec_enfants: float, revenu_imposable: float, adultes: int,
                              enfants: int) -> float:
    """
    Wendet gegebenenfalls die Obergrenze für den Familienquotienten an.
    Die endgültige Steuer darf nicht niedriger sein als die Steuer, die ohne Kinder berechnet wurde,
    abzüglich eines Höchstbetrags pro halber Anteile.
    """
    if enfants == 0:
        return impot_brut_avec_enfants

    # Steuerberechnung ohne Kinderanteile
    parts_sans_enfants = calculer_nombre_parts(adultes, 0)
    impot_sans_enfants = calculer_impot_brut_base(revenu_imposable, parts_sans_enfants)

    # Berechnung des maximalen kinderbezogenen Verdienstes
    parts_avec_enfants = calculer_nombre_parts(adultes, enfants)
    demi_parts_enfants = (parts_avec_enfants - parts_sans_enfants) * 2
    gain_maximal = demi_parts_enfants * GAIN_MAX_DEMI_PART

    impot_minimal_plafone = impot_sans_enfants - gain_maximal

    # Die einbehaltene Steuer ist die höhere der beiden Berechnungen
    return max(impot_brut_avec_enfants, impot_minimal_plafone)


def appliquer_decote(impot_avant_decote: float, adultes: int) -> tuple[float, float]:
    """
    Wendet den Abschlag an, wenn die Steuer unter bestimmten Schwellenwerten liegt.
    Der Abschlag wird auf den nächsten vollen Euro aufgerundet.
    """
    statut = "couple" if adultes == 2 else "celibataire"
    seuil_application = SEUIL_APPLICATION_DECOTE[statut]
    seuil_calcul = SEUIL_CALCUL_DECOTE[statut]

    decote = 0.0
    # Der Steuerabschlag wird angewendet, wenn die Steuer unter der Anwendungsschwelle liegt
    if impot_avant_decote < seuil_application:
        # Formel für den Abschlag: Schwelle - 0,75 * Bruttosteuer
        decote_calculee = seuil_calcul - (0.75 * impot_avant_decote)

        # Aufgerundet auf den nächsten Euro
        decote = math.ceil(decote_calculee)

        # Der Abschlag kann weder negativ noch höher als die Steuer sein
        decote = max(0.0, min(decote, impot_avant_decote))

    impot_apres_decote = impot_avant_decote - decote
    return impot_apres_decote, decote


def appliquer_reduction_20_pourcent(impot_avant_reduction: float, revenu_imposable: float, adultes: int,
                                    enfants: int) -> tuple[float, float]:
    """
    Wendet den einkommensabhängigen Rabatt von 20 % an.
    Der Rabatt wird auf den nächsten vollen Euro aufgerundet.
    """
    statut = "couple" if adultes == 2 else "celibataire"
    seuil_base = SEUIL_BASE_REDUCTION_20[statut]

    # Der Schwellenwert wird für jeden kinderbezogenen halben Anteil erhöht
    parts_avec_enfants = calculer_nombre_parts(adultes, enfants)
    parts_adultes = calculer_nombre_parts(adultes, 0)
    demi_parts_enfants = (parts_avec_enfants - parts_adultes) * 2
    seuil_final = seuil_base + (demi_parts_enfants * MAJORATION_SEUIL_REDUCTION_PAR_DEMI_PART)

    reduction = 0.0
    # Die Ermäßigung gilt, wenn das zu versteuernde Einkommen unter dem Schwellenwert liegt
    if revenu_imposable < seuil_final:
        reduction_calculee = impot_avant_reduction * 0.20

        # Aufgerundet auf den nächsten Euro
        reduction = math.ceil(reduction_calculee)

    impot_apres_reduction = impot_avant_reduction - reduction
    return max(0.0, impot_apres_reduction), reduction


def calculer_impot(adultes: int, revenus: float, enfants: int) -> dict:
    """
    Berechnet die gesamte zu zahlende Nettosteuer.
    """
    # Schritt 1: Berechnung des zu versteuernden Einkommens
    revenu_imposable = calculer_revenu_imposable(revenus)

    # Schritt 2: Berechnung der Anzahl der Anteile
    nombre_parts = calculer_nombre_parts(adultes, enfants)

    # Schritt 3: Berechnung der Bruttosteuer
    impot_brut_initial = calculer_impot_brut_base(revenu_imposable, nombre_parts)

    # Schritt 4: Anwendung der QF-Deckelung
    impot_apres_plafonnement = appliquer_plafonnement_qf(impot_brut_initial, revenu_imposable, adultes, enfants)

    # Schritt 5: Anwendung des Bewertungsabschlags
    impot_apres_decote, decote_calculee = appliquer_decote(impot_apres_plafonnement, adultes)

    # Schritt 6: Anwendung der 20%igen Ermäßigung
    impot_avant_arrondi_final, reduction_calculee = appliquer_reduction_20_pourcent(impot_apres_decote,
                                                                                    revenu_imposable, adultes, enfants)

    # Schritt 7: Endgültige Abrundung der Steuer auf den nächsten Euro
    impot_final = math.floor(impot_avant_arrondi_final)

    return {
        "impot": impot_final,
        "decote": decote_calculee,
        "reduction": reduction_calculee
    }


# --- TESTS UNITAIRES ---
# Validierung des script mit den bereitgestellten Fällen
class TestCalculImpot2019(unittest.TestCase):

    def _verifier_resultat(self, adultes, enfants, revenus, impot_attendu, decote_attendue, reduction_attendue):
        """Fonction utilitaire pour exécuter un test et vérifier les résultats à 1 euro près."""
        resultat = calculer_impot(adultes=adultes, revenus=revenus, enfants=enfants)

        self.assertAlmostEqual(resultat["impot"], impot_attendu, delta=1,
                               msg=f"Test ({adultes}, {enfants}, {revenus}): Impôt attendu {impot_attendu}, obtenu {resultat['impot']}")

        self.assertAlmostEqual(resultat["decote"], decote_attendue, delta=1,
                               msg=f"Test ({adultes}, {enfants}, {revenus}): Décote attendue {decote_attendue}, obtenue {resultat['decote']}")

        self.assertAlmostEqual(resultat["reduction"], reduction_attendue, delta=1,
                               msg=f"Test ({adultes}, {enfants}, {revenus}): Réduction attendue {reduction_attendue}, obtenue {resultat['reduction']}")

    def test_cas_1(self):
        # (2, 2, 55555) -> (2815, 0, 0)
        self._verifier_resultat(2, 2, 55555, 2815, 0, 0)

    def test_cas_2(self):
        # (2, 2, 50000) -> (1385, 384, 346)
        self._verifier_resultat(2, 2, 50000, 1385, 384, 346)

    def test_cas_3(self):
        # (2, 3, 50000) -> (0, 720, 0)
        self._verifier_resultat(2, 3, 50000, 0, 720, 0)

    def test_cas_4(self):
        # (1, 2, 100000) -> (19884, 0, 0)
        self._verifier_resultat(1, 2, 100000, 19884, 0, 0)

    def test_cas_5(self):
        # (1, 3, 100000) -> (16782, 0, 0)
        self._verifier_resultat(1, 3, 100000, 16782, 0, 0)

    def test_cas_6(self):
        # (2, 3, 100000) -> (9200, 0, 0)
        self._verifier_resultat(2, 3, 100000, 9200, 0, 0)

    def test_cas_7(self):
        # (2, 5, 100000) -> (4230, 0, 0)
        self._verifier_resultat(2, 5, 100000, 4230, 0, 0)

    def test_cas_8(self):
        # (1, 0, 100000) -> (22986, 0, 0)
        self._verifier_resultat(1, 0, 100000, 22986, 0, 0)

    def test_cas_9(self):
        # (2, 2, 30000) -> (0, 0, 0)
        self._verifier_resultat(2, 2, 30000, 0, 0, 0)

    def test_cas_10(self):
        # (1, 0, 200000) -> (64211, 0, 0)
        self._verifier_resultat(1, 0, 200000, 64211, 0, 0)

    def test_cas_11(self):
        # (2, 3, 200000) -> (42843, 0, 0)
        self._verifier_resultat(2, 3, 200000, 42843, 0, 0)


if __name__ == '__main__':
    print("Exécution des tests unitaires...")
    unittest.main(argv=['first-arg-is-ignored'], exit=False)

    # Beispiel für die Verwendung des Rechners in einem bestimmten Fall
    print("\n--- Exemple de calcul ---")
    revenus_annuels = 50000
    nombre_adultes = 2
    nombre_enfants = 2

    resultat_calcul = calculer_impot(adultes=nombre_adultes, revenus=revenus_annuels, enfants=nombre_enfants)

    print(f"Pour un couple ({nombre_adultes} adultes) avec {nombre_enfants} enfants et {revenus_annuels}€ de revenus :")
    print(f"  - Impôt à payer : {resultat_calcul['impot']}€")
    print(f"  - Montant de la décote : {resultat_calcul['decote']}€")
    print(f"  - Montant de la réduction : {resultat_calcul['reduction']}€")

Ich ai diesen Code nicht überprüft. Da alle 11 Unit-Tests bestanden wurden, betrachte ich ihn als "wahrscheinlich korrekt". Ich ai habe für meinen eigenen Code nicht mehr getan, als diese 11 Tests zu überprüfen.

4.4. Das Problem 3

Aufgabe 3 ist mit Aufgabe 2 identisch, außer dass man dem IA nicht mehr den PDF gibt, der die zu beachtenden Rechenregeln vorgab.

Die Ausgangsfrage an Gemini lautet wie folgt:

 

Die Anweisungsdatei in [1] ist fast dieselbe wie in Problem 2 mit den folgenden Unterschieden:

1 - Drück dich auf Französisch aus.

2 - Kannst du ein Python-Skript erstellen, mit dem sich die Steuern berechnen lassen, die Familien im Jahr 2019 auf ihre Einkünfte aus dem Jahr 2018 gezahlt haben?

3 - Du wirst dich auf Quellen stützen, die du im Internet findest. Gib diese Quellen in deiner Antwort an.

4 - Du solltest folgende Punkte beachten:
  • In [3] wird ihm gesagt, dass er im Internet die Regeln für die Berechnung der Steuer 2019 auf das Einkommen 2018 finden soll. Diese Übung ist schwieriger als die vorherige;

Im Folgenden gebe ich nur Teile von Geminis erster Antwort wieder:

 
 

Die geschätzte Zeit ist plausibel. Wir warten lange auf die Antwort von Gemini.

Wie zuvor hat Gemini einen Link zum Herunterladen des erzeugten script bereitgestellt, der nicht funktioniert. Wir sagen es ihm:

 

Geminis Antwort :

 

Man lädt den script in PyCharm unter dem Namen [gemini2]:

 

Wir führen es aus und ... es funktioniert nicht. Die Logs der Ausführung sind wie folgt:


"C:\Program Files\Python313\python.exe" "C:/Program Files/JetBrains/PyCharm 2025.2.0.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\gemini2.py" 
Testing started at 17:23 ...
Launching unittests with arguments python -m unittest C:\Data\st-2025\dev\python\code\python-flask-2025-cours\outils ia\gemini\gemini2.py in C:\Data\st-2025\dev\python\code\python-flask-2025-cours


Failure
Traceback (most recent call last):
  File "C:\Data\st-2025\dev\python\code\python-flask-2025-cours\outils ia\gemini\gemini2.py", line 278, in test_cas_2
    self.assertAlmostEqual(impot, 1385, delta=1)
    ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^
AssertionError: 1691 != 1385 within 1 delta (306 difference)


Error
Traceback (most recent call last):
  File "C:\Data\st-2025\dev\python\code\python-flask-2025-cours\outils ia\gemini\gemini2.py", line 291, in test_cas_3
    impot, _, _ = calculer_impot_final(2, 3, 50000)
                  ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^
  File "C:\Data\st-2025\dev\python\code\python-flask-2025-cours\outils ia\gemini\gemini2.py", line 187, in calculer_impot_final
    decote, impot_apres_decote = calculer_decote(impot_apres_plafonnement, adultes)
                                 ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Data\st-2025\dev\python\code\python-flask-2025-cours\outils ia\gemini\gemini2.py", line 134, in calculer_decote
    decote = seuil_decote - (impot_avant_decote * COFFICIENT_DECOTE)
                                                  ^^^^^^^^^^^^^^^^^
NameError: name 'COFFICIENT_DECOTE' is not defined. Did you mean: 'COEFFICIENT_DECOTE'?


Error
Traceback (most recent call last):
  File "C:\Data\st-2025\dev\python\code\python-flask-2025-cours\outils ia\gemini\gemini2.py", line 316, in test_cas_9
    self._verifier_cas(2, 2, 30000, (0, 0, 0))
    ~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Data\st-2025\dev\python\code\python-flask-2025-cours\outils ia\gemini\gemini2.py", line 216, in _verifier_cas
    impot_calcule, decote_calculee, reduction_calculee = calculer_impot_final(adultes, enfants, revenus)
                                                         ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Data\st-2025\dev\python\code\python-flask-2025-cours\outils ia\gemini\gemini2.py", line 187, in calculer_impot_final
    decote, impot_apres_decote = calculer_decote(impot_apres_plafonnement, adultes)
                                 ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Data\st-2025\dev\python\code\python-flask-2025-cours\outils ia\gemini\gemini2.py", line 134, in calculer_decote
    decote = seuil_decote - (impot_avant_decote * COFFICIENT_DECOTE)
                                                  ^^^^^^^^^^^^^^^^^
NameError: name 'COFFICIENT_DECOTE' is not defined. Did you mean: 'COEFFICIENT_DECOTE'?



Ran 11 tests in 0.038s

FAILED (failures=1, errors=2)

Process finished with exit code 1
  • Zeile 11, ein Test ist fehlgeschlagen;
  • Zeilen 25, 42: Ein und derselbe Kompilierungsfehler ;

Wir packen diese Logs in eine Textdatei, die wir Gemini geben:

 

Geminis Antwort :

 
 

Wir laden in PyCharm den script und führen ihn aus. Es treten wieder Fehler auf. Wir teilen es Gemini mit und fügen erneut die Logs der Ausführung bei:

 

Geminis Antwort :

 
 
 

Wir laden diesen neuen script in PyCharm und führen ihn aus. Diesmal kommen alle 11 Unit-Tests durch:

Der von Gemini erzeugte Code lautet wie folgt:

# -*- Codierung: utf-8 -*-
import math
import unittest

# ==============================================================================
# GRUNDLAGEN FÜR DIE VERANLAGUNG DER EINKÜNFTE 2018 (ZU ZAHLEN IM JAHR 2019)
# ==============================================================================
BAREME_IMPOT_2019 = [
    {'seuil': 0, 'taux': 0.0},
    {'seuil': 9964, 'taux': 0.14},
    {'seuil': 27519, 'taux': 0.30},
    {'seuil': 73779, 'taux': 0.41},
    {'seuil': 156244, 'taux': 0.45},
]
ABATTEMENT_FORFAITAIRE_TAUX = 0.10
ABATTEMENT_FORFAITAIRE_MINIMUM = 437
ABATTEMENT_FORFAITAIRE_PLAFOND = 12502
PLAFONNEMENT_AVANTAGE_QF_DEMI_PART = 1551
SEUIL_DECOTE_CELIBATAIRE = 1196
SEUIL_DECOTE_COUPLE = 1970
COEFFICIENT_DECOTE = 0.75
TAUX_REDUCTION_20_POURCENT = 0.20
SEUIL_RFR_REDUCTION_CELIBATAIRE = 18985
SEUIL_RFR_REDUCTION_COUPLE = 37970
MAJORATION_RFR_REDUCTION_PAR_DEMI_PART = 3803


# ==============================================================================
# RECHENFUNKTIONEN
# ==============================================================================

def calculer_nombre_parts(adultes: int, enfants: int) -> float:
    """Berechnet die Anzahl der Mitglieder des Steuerhaushalts."""
    if adultes < 1: return 0
    parts = float(adultes)
    if enfants >= 1: parts += 0.5
    if enfants >= 2: parts += 0.5
    if enfants >= 3: parts += (enfants - 2) * 1.0
    return parts


def calculer_revenu_imposable(revenus_bruts: float) -> float:
    """Berechnet das steuerpflichtige Nettoeinkommen nach Abzug von 10 %."""
    if revenus_bruts == 0: return 0.0
    abattement = revenus_bruts * ABATTEMENT_FORFAITAIRE_TAUX
    if abattement < ABATTEMENT_FORFAITAIRE_MINIMUM: abattement = ABATTEMENT_FORFAITAIRE_MINIMUM
    if abattement > ABATTEMENT_FORFAITAIRE_PLAFOND: abattement = ABATTEMENT_FORFAITAIRE_PLAFOND
    abattement = math.ceil(abattement)
    revenu_imposable = revenus_bruts - abattement
    return revenu_imposable if revenu_imposable > 0 else 0


def calculer_impot_brut_par_tranche(revenu_imposable: float, nombre_parts: float) -> float:
    """Berechnet die Bruttosteuer unter Anwendung des progressiven Steuertarifs."""
    if nombre_parts <= 0 or revenu_imposable <= 0: return 0.0
    quotient_familial = revenu_imposable / nombre_parts
    impot_par_part = 0.0
    for i in range(len(BAREME_IMPOT_2019)):
        tranche = BAREME_IMPOT_2019[i]
        seuil_actuel = tranche['seuil']
        taux = tranche['taux']
        if quotient_familial > seuil_actuel:
            base_imposable_tranche = 0
            if i < len(BAREME_IMPOT_2019) - 1:
                seuil_suivant = BAREME_IMPOT_2019[i + 1]['seuil']
                base_imposable_tranche = min(quotient_familial, seuil_suivant) - seuil_actuel
            else:
                base_imposable_tranche = quotient_familial - seuil_actuel
            impot_par_part += base_imposable_tranche * taux
    return impot_par_part * nombre_parts


def appliquer_plafonnement_qf(revenu_imposable: float, nombre_parts: float, adultes: int,
                              impot_brut_famille: float) -> float:
    """Wendet die Begrenzung der Auswirkungen des Familienquotienten an."""
    if nombre_parts <= adultes: return impot_brut_famille
    impot_base = calculer_impot_brut_par_tranche(revenu_imposable, float(adultes))
    demi_parts_enfants = (nombre_parts - adultes) * 2
    avantage_qf_max = PLAFONNEMENT_AVANTAGE_QF_DEMI_PART * demi_parts_enfants
    avantage_qf_reel = impot_base - impot_brut_famille
    if avantage_qf_reel > avantage_qf_max:
        return impot_base - avantage_qf_max
    return impot_brut_famille


def calculer_impot_final(adultes: int, enfants: int, revenus: float) -> (int, int, int):
    """Organisiert die gesamte Steuerberechnung."""
    revenu_imposable = calculer_revenu_imposable(revenus)
    nombre_parts = calculer_nombre_parts(adultes, enfants)
    impot_brut = calculer_impot_brut_par_tranche(revenu_imposable, nombre_parts)
    impot_apres_plafonnement = appliquer_plafonnement_qf(revenu_imposable, nombre_parts, adultes, impot_brut)

    # CORRECTION : Wenn die Steuer bereits 0 ist, gibt es keinen Abschlag oder eine Ermäßigung.
    if impot_apres_plafonnement == 0:
        return 0, 0, 0

    # --- LOGIQUE KORRIGIERT POUR DEN INTERACTION ABSCHLAG / KÜRZUNG ---
    decote_calculee = 0.0
    reduction_calculee = 0.0
    impot_a_traiter = impot_apres_plafonnement

    # 1. Feststellung der Berechtigung für die 20%ige Ermäßigung
    est_eligible_reduction = False
    if adultes >= 2:
        seuil_rfr = SEUIL_RFR_REDUCTION_COUPLE + max(0, (nombre_parts - 2) * 2) * MAJORATION_RFR_REDUCTION_PAR_DEMI_PART
    else:
        seuil_rfr = SEUIL_RFR_REDUCTION_CELIBATAIRE + max(0, (
                nombre_parts - 1) * 2) * MAJORATION_RFR_REDUCTION_PAR_DEMI_PART
    if revenu_imposable < seuil_rfr:
        est_eligible_reduction = True

    # 2. Feststellung der Anspruchsberechtigung für das Disagio
    seuil_decote_foyer = SEUIL_DECOTE_COUPLE if adultes >= 2 else SEUIL_DECOTE_CELIBATAIRE
    reduction_theorique = math.ceil(impot_a_traiter * TAUX_REDUCTION_20_POURCENT) if est_eligible_reduction else 0

    if (impot_a_traiter - reduction_theorique) < seuil_decote_foyer:
        decote_calculee = seuil_decote_foyer - (impot_a_traiter * COEFFICIENT_DECOTE)
        decote_calculee = math.ceil(decote_calculee)
        # CORRECTION : Der zurückgegebene Abschlag darf die Steuer, die er aufhebt, nicht übersteigen
        decote_calculee = min(decote_calculee, math.ceil(impot_a_traiter))
        impot_a_traiter -= decote_calculee
        impot_a_traiter = max(0.0, impot_a_traiter)

    # 3. Anwendung der 20%igen Ermäßigung, wenn berechtigt
    if est_eligible_reduction:
        reduction_calculee = math.ceil(impot_a_traiter * TAUX_REDUCTION_20_POURCENT)
        impot_a_traiter -= reduction_calculee
        impot_a_traiter = max(0.0, impot_a_traiter)

    impot_final = math.floor(impot_a_traiter)

    return impot_final, int(decote_calculee), int(reduction_calculee)


# ==============================================================================
# TESTS UNITAIRES
# ==============================================================================

class TestCalculImpot2019(unittest.TestCase):
    def _verifier_cas(self, adultes, enfants, revenus, attendu):
        impot_attendu, decote_attendue, reduction_attendue = attendu
        impot_calcule, decote_calculee, reduction_calculee = calculer_impot_final(adultes, enfants, revenus)
        self.assertAlmostEqual(impot_calcule, impot_attendu, delta=1, msg=f"Impôt ({impot_calcule} vs {impot_attendu})")
        self.assertAlmostEqual(decote_calculee, decote_attendue, delta=1,
                               msg=f"Décote ({decote_calculee} vs {decote_attendue})")
        self.assertAlmostEqual(reduction_calculee, reduction_attendue, delta=1,
                               msg=f"Réduction ({reduction_calculee} vs {reduction_attendue})")

    def test_cas_1(self): self._verifier_cas(2, 2, 55555, (2815, 0, 0))

    def test_cas_2(self): self._verifier_cas(2, 2, 50000, (1385, 384, 346))

    def test_cas_3(self): self._verifier_cas(2, 3, 50000, (0, 720, 0))

    def test_cas_4(self): self._verifier_cas(1, 2, 100000, (19884, 0, 0))

    def test_cas_5(self): self._verifier_cas(1, 3, 100000, (16782, 0, 0))

    def test_cas_6(self): self._verifier_cas(2, 3, 100000, (9200, 0, 0))

    def test_cas_7(self): self._verifier_cas(2, 5, 100000, (4230, 0, 0))

    def test_cas_8(self): self._verifier_cas(1, 0, 100000, (22986, 0, 0))

    def test_cas_9(self): self._verifier_cas(2, 2, 30000, (0, 0, 0))

    def test_cas_10(self): self._verifier_cas(1, 0, 200000, (64211, 0, 0))

    def test_cas_11(self): self._verifier_cas(2, 3, 200000, (42843, 0, 0))


if __name__ == '__main__':
    print("Lancement des tests unitaires pour le calcul de l'impôt 2019...")
    unittest.main(argv=['first-arg-is-ignored'], exit=False)

Auch hier habe ich ai den Code nicht überprüft. Ich ai lediglich festgestellt, dass er alle 11 Tests erfolgreich bestanden hat.

Aber man darf gespannt sein, wie er argumentiert, insbesondere bei Sonderfällen der Steuerberechnung. Wir fragen ihn:

 

Dies ist ein Fall für hohe Einkommen mit sowohl einer möglichen Obergrenze für den 10%igen Freibetrag als auch einer möglichen Obergrenze für den Familienquotienten.

Geminis Antwort lautet wie folgt:

 
 
 
 
 

Die letzten beiden Screenshots sind interessant. Gemini verwendet eine andere Berechnungsmethode als die, die im PDF erklärt wird. Diese Berechnungsmethode findet man tatsächlich im Internet. Beide Methoden sind gleichwertig.

 
 
 

Die Erklärung ist bemerkenswert klar. Man könnte sie so, wie sie ist, Studenten geben, um die Methode der Steuerberechnung zu erklären.

Nun nehmen wir ein anderes Beispiel, diesmal mit einem niedrigen Einkommen. In diesem Fall kann es zu einem Abschlag und einer Ermäßigung kommen :

 

Geminis Antwort lautet wie folgt:

 
 
 
 
 

Ici, stellt man fest, dass Gemini eine Regel anwendet, die nicht in PDF steht. Wahrscheinlich hat er sie im Internet gefunden, aber ist die Quelle zuverlässig?

 

Ici, wendet Gemini weiterhin eine unbekannte Regel an (die oben genannte Sonderregel).

 
 
 

Also passen Geminis Ergebnisse mit dem Ergebnis des offiziellen Steuersimulators zusammen. Aber er hat eine Regel verwendet, die in PDF nicht vorhanden ist. Wo ist der Fehler? Wir fragen ihn das, indem wir ihm PDF beilegen:

 

Geminis Antwort :

 
 
 
 

Ich denke, dass Gemini Recht hat und dass mein PDF falsch ist. Um das zu überprüfen, bitte ich ihn um einen Test :

  • Wo seine Argumentation zu denselben Ergebnissen führen würde wie der offizielle Steuersimulator ;
  • Die Argumentation des PDF würde zu anderen Ergebnissen führen als die des Simulators;
 

Geminis Antwort lautet wie folgt:

 

Ici Gemini macht einen Fehler. Ich ai startete den Simulator an diesem Beispiel und ai fand folgendes vor:

 

Wir werden jedoch herausfinden, dass Geminis Argumentation tatsächlich die oben genannten Ergebnisse liefert. Wir fahren fort:

 
 
 
 

Sehr gut. Das ist notiert. Wir fahren fort:

 
 
 
 

Gemini hat also (Steuer, Abschlag, Ermäßigung)= (431, 325, 1296) gefunden, während der von mir verwendete Simulator (431, 324, 1297) ergibt. Gemini hat also die richtigen Ergebnisse auf 1 Euro genau gefunden, aber er weiß es nicht. Wir sagen es ihm:

 

Gemini antwortet:

 
 

Nun fragt man sich, ob Gemini einen korrigierten PDF generieren könnte :

 

Geminis Antwort :

 

Gemini hat mir also keinen Link zu einem PDF gegeben, sondern einen Text generiert, um selbst diesen PDF zu erzeugen. Obwohl es umständlich ist, ici, die Screenshots des PDF, zu geben, tue ich dies, damit der Leser die generative Seite des IA sieht:

 

Image

Image

Image

Image

Image

Image

Image

Image

Image

Image

Image

Image

Image

Ehrlich gesagt habe ich ai nicht überprüft, ob alles, was in diesem PDF steht, wahr ist. Auf jeden Fall ist es ein perfektes Dokument für einen TD, das in wenigen Sekunden erstellt wurde.

Trotzdem kann man Gemini selbst überprüfen lassen, ob sein PDF in Ordnung ist. Wir starten eine neue Konversation:

 
  • in [1] wurde der von Gemini erzeugte PDF [Das Problem nach Gemini.pdf] eingefügt;
  • in [2] ist [instructionsAvecPDF2.txt] identisch mit den Anweisungen in [instructionsAvecPDF.txt], außer dass ein zwölfter Einheitstest hinzugefügt wurde, derselbe, der gezeigt hat, dass der ursprüngliche PDF fehlerhaft war:
test12 : (2, 2, 49500) -> (1297, 431, 324)

Kurioserweise dauerte es einige Male hin und her, bis Gemini den richtigen script erzeugte:

Frage 2

 

Frage 3

 

Wie jetzt schon mehrfach geschehen, gibt man Gemini, wenn der erzeugte und in PyCharm geladene script fehlschlägt, die Textdatei mit den Logs der Ausführung. Gemini versteht sie sehr gut.

Frage 4

 

Frage 5

 

Frage 6 und Ende

Jetzt sind wir beruhigt, was die Gültigkeit des von Gemini erzeugten PDF angeht. Die darin angegebenen Rechenregeln sind korrekt.

Wir werden nun das Gleiche für die anderen fünf IA tun, aber wir werden uns bei unseren Erklärungen sehr kurz fassen, außer bei ChatGPT dem derzeit führenden IA. Was uns interessiert, ist, ob IA die drei probleme, die man ihm stellt. Die Schnittstellen all dieser IA sind nämlich sehr ähnlich, und ich ai gehe mit ihnen genauso vor wie mit Gemini. Der Leser wird ermutigt, die Gemini-Konversationen mit einem IA seiner Wahl nachzuspielen.