Skip to content

4. Lösung der drei Probleme mit Google Gemini

Wir zeigen Ihnen Screenshots der drei Gemini-Sitzungen, mit denen die drei gestellten Probleme gelöst werden konnten. Wir gehen dabei recht detailliert vor. Anschließend werden wir den Vorgang für die anderen getesteten KI-Systeme nicht wiederholen. Diese funktionieren auf ähnliche Weise. Wir werden nur die auffälligsten Details anführen.

4.1. Einleitung

Wir verweisen auf den zuvor gezeigten ersten Screenshot von Gemini:

 
  • In [1] die URL von Gemini;
  • In [2] die verwendete Gemini-Version;
  • In [3-5] die drei an Gemini gestellten Aufgaben;

Gemini ist ein Produkt von Google, das unter der URL [https://gemini.google.com/] verfügbar ist. Um einen Verlauf Ihrer Frage-Antwort-Sitzungen wie oben zu erhalten, müssen Sie ein Konto erstellen. Außerdem begrenzt Gemini, wie alle anderen getesteten KI-Systeme, die Anzahl Ihrer Fragen und die Anzahl der hochgeladenen Dateien. Wenn dieses Limit erreicht ist, wird die Sitzung beendet und Ihnen wird angeboten, sie zu einem späteren Zeitpunkt fortzusetzen. Da es ziemlich frustrierend ist, mitten in einer Sitzung aufhören zu müssen, habe ich ein Abonnement abgeschlossen. Der erste Monat des Gemini-Abonnements ist glücklicherweise kostenlos. Das Gleiche habe ich mit den anderen KI-Systemen gemacht, die diese Beschränkungen hatten, nämlich ChatGPT, MistralAI und ClaudeAI. Ich habe ein Monatsabonnement abgeschlossen, aber hier war der erste Monat kostenpflichtig. Bei Grok bin ich auf keine Beschränkungen gestoßen. DeepSeek gibt keine Beschränkungen an, antwortet aber manchmal mit [Server busy] und bricht die Sitzung ab. Das läuft darauf hinaus, Beschränkungen zu setzen, ohne es zu sagen.

Im Folgenden werde ich von Frage-Antwort-Sitzungen sprechen, die ich einfach als „Sitzung“ abkürzen werde. KI-Systeme verwenden meist den englischen Begriff „Chat“ (Diskussion) oder „Conversation“ (Gespräch).

Die Benutzeroberfläche von Gemini zum Stellen einer Frage sieht wie folgt aus:

  • In [1] Ihre Frage;
  • In [2] das Symbol, das die KI zur Berechnung der Antwort startet;
  • In [3-4] können Sie Dateien anhängen; ## 4.2. Aufgabe 1

Die Sitzung für Aufgabe 1 sieht wie folgt aus:

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

Der Rest der Antwort lautet wie folgt:

 
 
 
 

Die Antwort ist korrekt. Die fünf anderen KI-Systeme werden ebenfalls die richtige Antwort in ähnlicher Form geben.

4.3. Aufgabe 2

4.3.1. Einleitung

Wir erinnern hier an das ursprüngliche Problem aus dem Kurs [python3-flask-2020]. Es handelt sich um einen Text, der den Studierenden in einer Übung vorgelegt wurde.

 

Anhand der obigen Tabelle lässt sich die Steuer im vereinfachten Fall eines Steuerpflichtigen berechnen, der nur sein Gehalt anzugeben hat. Wie in Anmerkung (1) angegeben, handelt es sich bei der so berechneten Steuer um die Steuer vor drei Mechanismen:

  • Die Begrenzung des Familienquotienten, die bei hohen Einkommen greift;
  • Der Steuerfreibetrag und die Steuerermäßigung, die bei niedrigen Einkommen zum Tragen kommen;

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

 

Wir wollen ein Programm schreiben, mit dem die Steuer eines Steuerpflichtigen im Jahr 2019 im vereinfachten Fall berechnet werden kann, in dem der Steuerpflichtige nur sein Gehalt anzugeben hat.

4.3.1.1. Berechnung der Bruttosteuer

Die Bruttosteuer kann wie folgt berechnet werden:

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

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

Die Anzahl der Anteile beträgt somit:

  • AnzahlAnteile=1+AnzahlKinder*0,5+(AnzahlKinder-2)*0,5, wenn der Arbeitnehmer unverheiratet ist;
  • nbParts=2+nbEnfants*0,5+(nbEnfants-2)*0,5, wenn er verheiratet ist;
  • wobei nbEnfants die Anzahl seiner Kinder ist;
  • Man berechnet das zu versteuernde Einkommen R = 0,9 * S, wobei S das Jahresgehalt ist;
  • Man berechnet den Familienquotienten QF=R/AnzahlAnteile;
  • Man berechnet die Bruttosteuer I anhand der 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 3 Felder: Feld1, Feld2, Feld3. Um die Steuer I zu berechnen, sucht man die erste Zeile, in der QF <= Feld1 ist, und übernimmt die Werte dieser Zeile. Beispiel für einen verheirateten Arbeitnehmer mit zwei Kindern und einem Jahresgehalt S von 50.000 Euro:

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

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

Familienquotient: QF=45000/3=15000

Die erste Zeile, in der QF <= Feld1 ist, lautet wie folgt:

    27519    0,14    1394,96

Die Steuer I beträgt dann 0,14*R – 1394,96*AnzahlAnteile=[0,14*45000-1394,96*3]=2115. Die Steuer wird auf den nächsten ganzen Euro abgerundet.

Wenn die Beziehung QF <= Feld1 bereits in der ersten Zeile gilt, beträgt die Steuer null.

Wenn QF so ist, dass die Bedingung QF <= Feld1 nie erfüllt ist, werden die Koeffizienten der letzten Zeile verwendet. Hier:

    0    0,45    20163,45

was die Bruttosteuer I = 0,45 * R – 20163,45 * nbParts ergibt.

4.3.1.2. Obergrenze des Familienquotienten

 

Um festzustellen, ob die Obergrenze für den Familienquotienten QF gilt, wird die Bruttosteuer ohne Kinder neu berechnet. Wiederum für den verheirateten Arbeitnehmer mit zwei Kindern und einem Jahresgehalt S von 50.000 Euro:

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

Anzahl der Anteile: nbParts=2 (die Kinder werden nicht mehr berücksichtigt)

Familienquotient: QF = 45.000 / 2 = 22.500

Die erste Zeile, in der QF <= Feld1 gilt, lautet wie folgt:

    27519    0,14    1394,96

Die Steuer I beträgt dann 0,14*R – 1394,96*AnzahlAnteile=[0,14*45000-1394,96*2]=3510.

Maximaler Kinderfreibetrag: 1551 * 2 = 3102 Euro

Mindeststeuer: 3510 – 3102 = 408 Euro

Die im vorigen Absatz bereits berechnete Bruttosteuer bei 2 Anteilen in Höhe von 2115 Euro liegt über der Mindeststeuer von 408 Euro, daher findet die Familienobergrenze hier keine Anwendung.

Im Allgemeinen ist die Bruttosteuer größer als (Steuer1, Steuer2), wobei:

  • [Steuer1]: die mit den Kindern berechnete Bruttosteuer;
  • [Steuer2]: die Bruttosteuer, die ohne Kinder berechnet und um den maximalen Kinderfreibetrag (hier 1551 Euro pro Halbanteil) verringert wurde;

4.3.1.3. Berechnung des Abschlags

 

Weiterhin für den verheirateten Arbeitnehmer mit zwei Kindern und einem Jahresgehalt S von 50.000 Euro:

Die aus dem vorherigen Schritt resultierende Bruttosteuer (2115 Euro) liegt unter 2627 Euro für ein Paar (1595 Euro für einen Alleinstehenden): Der Steuerabzug kommt daher zur Anwendung. Er ergibt sich aus folgender Berechnung:

Abzug = Schwellenwert (Paar = 1970 / Alleinstehender = 1196) – 0,75 * Bruttosteuer

Abzug = 1970 – 0,75 * 2115 = 383,75, gerundet auf 384 Euro.

Neue Bruttosteuer = 2115 – 384 = 1731 Euro

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

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

4.3.1.4. Berechnung der Steuerermäßigung

 

Unterhalb einer bestimmten Schwelle wird eine Ermäßigung von 20 % auf die aus den vorangegangenen Berechnungen resultierende Bruttosteuer gewährt. Im Jahr 2019 gelten folgende Schwellenwerte:

  • Alleinstehend: 21.037 Euro;
  • Paar: 42.074 Euro; (die im obigen Beispiel verwendete Zahl 37.968 scheint falsch zu sein);

Dieser Schwellenwert wird um den Wert 3797 * (Anzahl der durch die Kinder eingebrachten halben Anteile) erhöht.

Weiterhin für den verheirateten Arbeitnehmer mit zwei Kindern und einem Jahresgehalt S von 50.000 Euro:

  • Sein zu versteuerndes Einkommen (45.000 Euro) liegt unter dem Schwellenwert (42.074 + 2 * 3.797) = 49.668 Euro;
  • Er hat daher Anspruch auf eine Ermäßigung seiner Steuer um 20 %: 1731 * 0,2 = 346,2 Euro, gerundet auf 347 Euro;
  • Die Bruttosteuer des Steuerpflichtigen beträgt somit: 1731 – 347 = 1384 Euro; #### 4.3.1.5. Berechnung der Nettosteuer

Unsere Berechnung endet hier: Die zu zahlende Nettosteuer beträgt 1384 Euro. In der Realität kann der Steuerpflichtige weitere Ermäßigungen in Anspruch nehmen, insbesondere für Spenden an gemeinnützige oder öffentliche Einrichtungen.

4.3.1.6. Fälle mit hohem Einkommen

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

4.3.1.6.1. Obergrenze für den 10-prozentigen Freibetrag auf das Jahreseinkommen

In den meisten Fällen ergibt sich das zu versteuernde Einkommen aus der Formel: R = 0,9 * S, wobei S das Jahreseinkommen ist. Dies wird als 10-prozentige Ermäßigung bezeichnet. Diese Ermäßigung ist begrenzt. Im Jahr 2019:

  • Sie darf 12.502 Euro nicht überschreiten;
  • Sie darf nicht unter 437 Euro liegen;

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

  • Die 10-prozentige Reduzierung beträgt 200.000 Euro > 12.502 Euro. Sie wird daher auf 12.502 Euro gesenkt; ##### 4.3.1.6.2. Obergrenze des Familienquotienten

Nehmen wir einen Fall, in dem die im Abschnitt |Obergrenze des Familienquotienten| dargestellte Obergrenze zum Tragen kommt. Nehmen wir den Fall eines Paares mit drei Kindern und einem Jahreseinkommen von 100.000 Euro. Gehen wir die Berechnungsschritte noch einmal durch:

  • Der Freibetrag von 10 % beträgt 100.000 Euro < 12.502 Euro. Das zu versteuernde Einkommen R beträgt somit 100.000 – 10.000 = 90.000 Euro;
  • Das Paar hat nbParts = 2 + 0,5 * 2 + 1 = 4 Anteile;
  • Sein Familienquotient beträgt somit QF = R / Anzahl der Anteile = 90.000 / 4 = 22.500 Euro;
  • Seine Bruttosteuer I1 mit Kindern beträgt I1 = 0,14 * 90.000 – 1.394,96 * 4 = 7.020 Euro;
  • Seine Bruttosteuer I2 ohne Kinder:
    • QF = 90.000 / 2 = 45.000 Euro;
    • I2 = 0,3 * 90.000 – 5.798 * 2 = 15.404 Euro;
  • Die Regel zur Begrenzung des Familienquotienten besagt, dass der durch die Kinder erzielte Gewinn (1551 * 4 halbe Anteile) = 6204 Euro nicht überschreiten darf. Hier beträgt er jedoch I2 – I1 = 15404 – 7020 = 8384 Euro und liegt somit über 6204 Euro;
  • Die Bruttosteuer wird daher neu berechnet als I3 = I2 – 6204 = 15404 – 6204 = 9200 Euro;
  • Da I3 > I1 ist, wird die Steuer I3 beibehalten;

Dieses Paar erhält weder einen Freibetrag 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 die Berechnungen anhand der folgenden Beispiele 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 Algorithmus in diesem Dokument
Paar mit 2 Kindern und einem Jahreseinkommen von 55.555 Euro
Steuer = 2815 Euro
Steuersatz = 14 %
Steuer = 2814 Euro
Steuersatz = 14 %
Paar mit 2 Kindern und einem Jahreseinkommen von 50.000 Euro
Steuer = 1385 Euro
Steuerermäßigung = 384 Euro
Ermäßigung = 346 Euro
Steuersatz = 14 %
Steuer = 1.384 Euro
Abzug = 384 Euro
Ermäßigung = 347 Euro
Steuersatz = 14 %
Paar mit 3 Kindern und einem Jahreseinkommen von 50.000 Euro
Steuer = 0 Euro
Abzug = 720 Euro
Ermäßigung = 0 Euro
Steuersatz = 14 %
Steuer = 0 Euro
Abschlag=720 Euro
Ermäßigung=0 Euro
Steuersatz = 14 %
Alleinstehend mit 2 Kindern und einem Jahreseinkommen von 100.000 Euro
Steuer = 19.884 Euro
Abzug = 0 Euro
Abzug = 0 Euro
Steuersatz = 41 %
Steuer = 19.884 Euro
Zuschlag = 4480 Euro
Abschlag=0 Euro
Abzug = 0 Euro
Steuersatz = 41 %
Alleinstehend mit 3 Kindern und einem Jahreseinkommen von 100.000 Euro
Steuer = 16.782 Euro
Abzug = 0 Euro
Abzug = 0 Euro
Steuersatz = 41 %
Steuer = 16.782 Euro
Zuschlag = 7176 Euro
Abschlag=0 Euro
Ermäßigung = 0 Euro
Steuersatz = 41 %
Paar mit 3 Kindern und einem Jahreseinkommen von 100.000 Euro
Steuer = 9.200 Euro
Abzug = 0 Euro
Abzug = 0 Euro
Steuersatz = 30 %
Steuer = 9200 Euro
Zuschlag = 2180 Euro
Abschlag = 0 Euro
Ermäßigung = 0 Euro
Steuersatz = 30 %
Paar mit 5 Kindern und einem Jahreseinkommen von 100.000 Euro
Steuer = 4230 Euro
Abzug = 0 Euro
Abzug = 0 Euro
Steuersatz = 14 %
Steuer = 4230 Euro
Abschlag = 0 Euro
Abzug=0 Euro
Steuersatz = 14 %
Alleinstehend, ohne Kinder und mit einem Jahreseinkommen von 100.000 Euro
Steuer = 22.986 Euro
Abzug = 0 Euro
Abzug = 0 Euro
Steuersatz = 41 %
Steuer = 22.986 Euro
Zuschlag = 0 Euro
Abschlag=0 Euro
Abzug = 0 Euro
Steuersatz = 41 %
Paar mit 2 Kindern und einem Jahreseinkommen von 30.000 Euro
Steuer = 0 Euro
Abzug=0 Euro
Abzug = 0 Euro
Steuersatz = 0 %
Steuer = 0 Euro
Abschlag=0 Euro
Abzug=0 Euro
Steuersatz = 0 %
Alleinstehend, ohne Kinder und mit einem Jahreseinkommen von 200.000 Euro
Steuer = 64.211 Euro
Abzug = 0 Euro
Abzug = 0 Euro
Steuersatz = 45 %
Steuer = 64.210 Euro
Zuschlag = 7498 Euro
Abschlag=0 Euro
Abzug = 0 Euro
Steuersatz = 45 %
Paar mit 3 Kindern und einem Jahreseinkommen von 200.000 Euro
Steuer = 42.843 Euro
Abzug = 0 Euro
Abzug = 0 Euro
Steuersatz = 41 %
Steuer = 42.842 Euro
Zuschlag = 17.283 Euro
Abschlag=0 Euro
Ermäßigung = 0 Euro
Steuersatz = 41 %

Oben wird als Zuschlag bezeichnet, was Personen mit hohem Einkommen aufgrund zweier Phänomene zusätzlich zahlen:

  • Die Begrenzung des Freibetrags von 10 % auf das Jahreseinkommen;
  • Die Begrenzung des Familienquotienten;

Dieser Indikator konnte nicht überprüft werden, da er im Simulator der Steuerbehörde nicht angegeben ist.

Man sieht, dass der Algorithmus des Dokuments jedes Mal eine korrekte Steuer angibt, allerdings mit einer Fehlermarge von 1 Euro. Diese Fehlermarge resultiert aus Rundungen. Alle Geldbeträge werden mal auf den nächsten Euro aufgerundet, mal auf den nächsten Euro abgerundet. Da ich die offiziellen Regeln nicht kannte, wurden die Geldbeträge im Algorithmus des Dokuments wie folgt gerundet:

  • auf den nächsten höheren Euro bei Preisnachlässen und Rabatten;
  • auf den nächsten Euro nach unten für Aufschläge und die endgültige Steuer;

Wir werden die KI bitten, diese Steuerberechnung durchzuführen.

4.3.2. Konfiguration der Gemini-Sitzung

Die an Gemini gestellte Frage wird von zwei Dateien begleitet:

 
  • In [1] wurde die soeben erläuterte Berechnung in ein PDF-Dokument übertragen, das Gemini zur Verfügung gestellt wird. Gemini findet darin die genauen Regeln für die vereinfachte Berechnung der Steuer 2019 auf die Einkünfte 2018;
  • In [2] unsere Anweisungen;
  • In [3] zum Starten der KI;

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

1 – Drücke dich auf Französisch aus.

2 – Kannst du ein Python-Skript erstellen, mit dem sich die von Familien im Jahr 2019 auf ihre Einkünfte aus dem Jahr 2018 gezahlte Steuer berechnen lässt?

3 – Nutze dazu das von mir angehängte PDF-Dokument, in dem die durchzuführenden Berechnungen erklärt werden.

4 – Du musst auf folgende Punkte achten:

- Begrenzung des Familienquotienten. Es sind bestimmte Schwellenwerte zu prüfen.
- Berechnung des Abschlags in bestimmten Fällen. Es sind Schwellenwerte zu prüfen.
- Berechnung der Ermäßigung von 20 % in bestimmten Fällen. Es sind Schwellenwerte zu prüfen.
- Begrenzung des Freibetrags von 10 % auf das Jahreseinkommen in bestimmten Fällen.
- Du musst davon ausgehen, dass alle Einkünfte für den Steuerpflichtigen 1 anzugeben sind, auch wenn das Paar verheiratet ist.

5 – Du fügst dem generierten Skript Unit-Tests für die folgenden Fälle hinzu.

In diesen Tests wird Folgendes aufgerufen:

Erwachsene: Anzahl der Erwachsenen im Steuerhaushalt
Kinder: Anzahl der Kinder im Steuerhaushalt
Einkommen: jährliches Nettoeinkommen vor Steuern, d. h. vor der ersten Berechnung des Freibetrags.
Steuer: die zu zahlende Steuer
Abzug: der eventuelle Abzug des Steuerhaushalts
Ermäßigung: die Ermäßigung von 20 % für Geringverdiener

Hier sind die 11 zu überprüfenden Punkte. Sie wurden alle manuell anhand des offiziellen Simulators
zur Steuerberechnung 2019 [https://www3.impots.gouv.fr/simulateur/calcul_impot/2019/simplifie/index.html] überprüft.
Wenn du diesen Simulator verwendest, müssen die Einkünfte nur dem ersten Steuerpflichtigen (Deklarant 1) zugeordnet werden; im Falle eines Paares wird der zweite Steuerpflichtige (Deklarant 2) dabei ignoriert. Wenn man die Einkünfte
auf zwei Steuerpflichtige aufgeteilt werden, erhält man nicht das gleiche Ergebnis.

Man verwendet die Syntax (Erwachsene, Kinder, Einkommen) -> (Steuer, Abschlag, Ermäßigung), um anzugeben, dass das Skript die Eingaben
(Erwachsene, Kinder, Einkommen) und die Ergebnisse (Steuer, Abschlag, Ermäßigung) ausgibt

test1: (2,2,55555) -> (2815, 0, 0)
test2: (2, 2, 50000) -> (1385, 384, 346)
test3: (2,3,50000) -> (0, 720, 0)
test4: (1,2,100000) -> (19884, 0, 0)
test5: (1,3,100000) -> (16782, 0, 0)
test6: (2, 3, 100000) -> (9200, 0, 0)
test7: (2, 5, 100000) -> (4230, 0, 0)
test8: (1, 0, 100000) -> (22986, 0, 0)
test9: (2, 2, 30000) -> (0, 0, 0)
test10: (1, 0, 200000) -> (64211, 0, 0)
test11: (2, 3, 200000) -> (42843, 0, 0)

6 – Es können Rundungsprobleme auftreten. Gehe wie folgt vor
- Die zu zahlende Steuer wird auf den nächsten ganzen Euro abgerundet,
- der Abschlag wird auf den nächsten Euro aufgerundet,
- die Ermäßigung von 20 % wird auf den nächsten ganzen Euro aufgerundet.
- Der Freibetrag von 10 % wird auf den nächsten ganzen Euro aufgerundet

Führe alle Unit-Tests auf den nächsten Euro genau durch, um diese möglichen Rundungsfehler zu berücksichtigen.
Versuche nicht, die oben genannten exakten Werte zu erhalten, sondern diese Werte auf 1 Euro genau.

7 – Vermeide es, im Internet zu suchen. Das PDF, das ich dir gebe, ist korrekt.
Gib dein Ergebnis erst ab, wenn du alle 11 Einzeltests erfolgreich bestanden hast.

8 – Wenn einer der Tests fehlschlägt und du nicht weiterkommst, zeige deine Überlegungen zu diesem Test auf,
, damit ich dir helfen kann.

9 – Füge detaillierte Kommentare in das von dir erstellte Skript ein.
Füge die progressive Skala in eine Liste oder ein Wörterbuch ein und verwende diese Liste oder dieses Wörterbuch
Füge die feststehenden Zahlen (magische Zahlen), die du verwendest, als Konstanten ein
Verwende Funktionen, um die einzelnen Rechenschritte voneinander zu trennen.
Schreibe alles auf Französisch

9 – Zeige den generierten Code nicht auf dem Bildschirm an. Gib mir einfach einen Link, über den ich ihn abrufen kann.
Wenn die Unit-Tests fehlschlagen, gebe ich dir die Logs der Skriptausführung, damit
du deine Fehler sehen kannst.

10 – Wenn möglich, gib bitte die Zeit in Minuten und Sekunden an, die du für die Erstellung
das angeforderte Skript erstellt hast.

Diese Anweisungen sind das Ergebnis zahlreicher Fragen, die an Gemini gestellt wurden. Ziemlich schnell wird klar, dass die KI sehr genau angeleitet werden muss, wenn man das gewünschte Ergebnis erzielen will. Aufgrund all dieser Versuche wurde die Gemini-Sitzung schließlich wegen Überschreitung der Limits beendet. Schauen wir uns den Rest dieser Anweisungen an:

  • Zeile 1: Wir verlangen, dass die Unterhaltung auf Französisch stattfindet. Diese Angabe richtet sich an DeepSeek, das dazu neigte, Englisch zu sprechen;
  • Zeile 3: Was wir wollen;
  • Zeile 5: Wir weisen die KI an, das ihr zur Verfügung gestellte PDF zu verwenden;
  • Zeilen 7–14: eine Reihe nützlicher Tipps, insbesondere für Aufgabe 3 ohne PDF. Mehrere KI-Systeme haben sich bei der Steuerberechnung verirrt;
  • Zeilen 15–44: die 11 Unit-Tests, die im generierten Skript enthalten sein sollen. Sobald das Skript generiert ist, führen wir es in PyCharm aus und prüfen, ob alle 11 Tests erfolgreich sind;
  • Zeilen 46–53: Ohne diese Anweisungen generierten die KI-Systeme Unit-Tests, die nach exakten Ergebnissen suchten und fehlschlugen;
  • Zeilen 55–56: Ich weise die KI an, nicht ins Internet zu gehen. Die einfachste Lösung ist die Verwendung der PDF-Datei;
  • Zeilen 58–59: Diese Anweisung wurde von den KI-Systemen nicht befolgt. Ich war gezwungen, sie explizit in eine Frage zu schreiben, als ich feststellte, dass ein Test fehlgeschlagen war;
  • Zeilen 61–65: Ich gebe an, welche Art von Python-Skript ich wünsche;
  • Zeilen 67–69: Ich hätte einen Link zum Abrufen des generierten Skripts bevorzugt, da die Anzeige des Codes auf dem Bildschirm Zeit kostet. Es stellte sich heraus, dass die meisten KI-Systeme dazu nicht in der Lage sind. Die angegebenen Links funktionierten nicht;
  • Zeilen 71–72: Ich hätte gerne gewusst, wie viel Zeit die KI für die Beantwortung der Frage gebraucht hat. Nur Gemini konnte mir diese Information geben. Die anderen KIs reagierten entweder gar nicht auf diese Anweisung oder gaben willkürliche Zahlen an, was zeigte, dass sie diese Anweisung nicht verstanden; ### 4.3.3. Die Antwort von Gemini

Die erste Antwort von Gemini lautet wie folgt:

 
  • In [1-4] liefert Gemini Links zu dem Teil des PDFs oder der Textdatei mit den Anweisungen, den es zu einem bestimmten Zeitpunkt verwendet;

Weiter geht es wie folgt:

 
  • In [1] behauptet Gemini, dass es die 11 Unit-Tests erfolgreich ausgeführt hat. Die meisten KI-Systeme haben dies sowohl bei Problem 2 als auch bei Problem 3 behauptet, und oft funktionierte das Skript beim Laden nicht. Man sollte dieser Behauptung also mit Vorsicht begegnen. Bei Gemini wird sich dies als wahr herausstellen;
  • In [2] ein Link, der sich als nicht funktionierend herausstellen wird;
  • In [3] hat nur Gemini eine realistische Ausführungszeit angegeben;

Der Link [2] funktioniert also nicht. Wir teilen dies Gemini mit:

 

Die Antwort von Gemini:

 
  • In [1] das von Gemini generierte Python-Skript;

Wir laden dieses Skript in PyCharm und führen es aus:

 
  • In [1] ist [gemini1] das von Gemini generierte Skript;

Bei der Ausführung des Skripts treten Kompilierungsfehler 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" 
Teststart um 17:12 Uhr ...
Starten der Unit-Tests mit den Argumenten 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):
  Datei C:\Program Files\JetBrains\PyCharm 2025.2.0.1\plugins\python-ce\helpers\pycharm\_jb_unittest_runner.py, Zeile 38, in <Modul>
    sys.exit(main(argv=args, module=None, testRunner=unittestpy.TeamcityTestRunner,
             ~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                  buffer=not JB_DISABLE_BUFFERING))
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  Datei C:\Program Files\Python313\Lib\unittest\main.py, Zeile 103, in __init__
    self.parseArgs(argv)
    ~~~~~~~~~~~~~~^^^^^^
  Datei C:\Program Files\Python313\Lib\unittest\main.py, Zeile 142, in parseArgs
    self.createTests()
    ~~~~~~~~~~~~~~~~^^
  Datei C:\Program Files\Python313\Lib\unittest\main.py, Zeile 153, in createTests
    self.test = self.testLoader.loadTestsFromNames(self.testNames,
                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^
                                                   self.module)
                                                   ^^^^^^^^^^^^
  Datei C:\Program Files\Python313\Lib\unittest\loader.py, Zeile 207, in loadTestsFromNames
    suites = [self.loadTestsFromName(name, module) for name in names]
              ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^
  Datei C:\Program Files\Python313\Lib\unittest\loader.py, Zeile 137, in loadTestsFromName
    module = __import__(module_name)
  Datei C:\Data\st-2025\dev\python\code\python-flask-2025-cours\outils ia\chatGPT\chatGPT1.py, Zeile 28, in <module>
    [cite_start]
     ^^^^^^^^^^
NameError: Name 'cite_start' ist nicht definiert

Prozess beendet mit Exit-Code 1

Leere Fortsetzung
  • Zeile 30, der Kompilierungsfehler. [cite_start] ist ein Marker, um eine bestimmte Textform zu generieren;

Wir speichern die oben genannten Logs in einer Datei [logs gemini1.txt] und übergeben diese an Gemini:

 

Die Antwort von Gemini lautet dann wie folgt:

 

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

 

Die Antwort von Gemini lautet wie folgt:

 

Diesmal klappt es. Alle 11 Unit-Tests sind erfolgreich. Wir teilen dies Gemini mit:

 

Darauf antwortet Gemini:

 

Das von Gemini generierte Skript hat die Anweisungen in der Textdatei [instructionsAvecPDF.txt] befolgt:

# -*- coding: utf-8 -*-
"""
Skript zur Berechnung der Steuer 2019 auf die Einkünfte von 2018 in Frankreich,
basierend auf den vereinfachten Regeln aus dem PDF-Dokument.
"""

import math
import unittest

# --- BERECHNUNGSKONSTANTEN FÜR DIE STEUER 2019 ---
# Alle Werte stammen aus dem bereitgestellten PDF-Dokument.

# Obergrenzen für den Freibetrag von 10 % auf das Jahreseinkommen
OBERGRENZE_FÜR_10_PROZENT_FREIBETRAG = 12502.0
MINIMUM_ABZUG_10_PROZENT = 437.0

# Einkommensteuertabelle 2019
# Struktur: (Obergrenze der Steuerklasse, Steuersatz, abzugsfähiger Betrag pro Anteil)
EINKOMMENSTAX_2019 = [
    {"Schwellenwert": 9964, "Steuersatz": 0.0, "Abzug_pro_Anteil": 0},
    {"Schwellenwert": 27519, "Steuersatz": 0.14, "Abzug_pro_Stufe": 1394.96},
    {"Schwellenwert": 73779, "Steuersatz": 0.30, "Abzug_pro_Anteil": 5798},
    {"Schwellenwert": 156244, "Satz": 0.41, "Abzug_pro_Anteil": 13913.69},
    {"Schwellenwert": float('inf'), "Satz": 0.45, "Abzug_pro_Anteil": 20163.45}
]

# Obergrenze für den Familienquotienten
GAIN_MAX_DEMI_PART = 1551.0  # Maximaler Gewinn pro zusätzlichem halben Anteil

# Schwellenwerte und Beträge für den Abschlag
SEUIL_APPLICATION_DECOTE = {"Alleinstehend": 1595.0, "Paar": 2627.0}
SEUIL_CALCUL_DECOTE = {"Alleinstehend": 1196,0, "Paar": 1970,0}

# Schwellenwerte für die Steuerermäßigung von 20 %
GRENZWERT_BASIS_ERMÄSSIGUNG_20 = {"Alleinstehend": 21037,0, "Paar": 42074,0}
ZUSCHLAG_GRENZWERT_ERMÄSSIGUNG_PRO_HALBTEIL = 3797.0


def Anzahl_Anteile_berechnen(Erwachsene: int, Kinder: int) -> float:
    """
    Berechnet die Anzahl der Steueranteile des Haushalts.
    - Jeder Elternteil bringt 1 Anteil mit.
    - Die ersten beiden Kinder bringen jeweils 1/2 Anteil mit.
    - Die folgenden Kinder bringen jeweils einen Anteil bei.
    """
    if adults not in [1, 2]:
        raise ValueError("Die Anzahl der Erwachsenen muss 1 oder 2 sein.")

    Anteile = float(Erwachsene)
    if Kinder > 0:
        Anteile += 0.5 * min(Kinder, 2)
    if Kinder > 2:
        Anteile += 1.0 * (Kinder - 2)

    return Anteile


def steuerpflichtiges_einkommen_berechnen(Einkommen: float) -> float:
    """
    Berechnet das steuerpflichtige Nettoeinkommen nach Abzug des Freibetrags von 10 %.
    Dieser Freibetrag ist begrenzt.
    Der Freibetrag wird auf den nächsten ganzen Euro aufgerundet.
    """
    abzug_berechnet = einnahmen * 0.1
    # Der Freibetrag ist zwischen einem Mindest- und einem Höchstbetrag begrenzt
    Freibetrag = min(FREIBETRAGSOBERGRENZE_10_PROZENT, max(FREIBETRAGSUNTERGRENZE_10_PROZENT, berechneter_Freibetrag))

    # Die Aufgabe verlangt, den Freibetrag auf den nächsten ganzen Euro auf- oder abzurunden
    abgezogener_Betrag_gerundet = math.ceil(abgezogener_Betrag)

    return Einnahmen - abgerundeter_Freibetrag


def berechnen_bruttosteuerbemessungsgrundlage(steuerpflichtiges_Einkommen: float, Anzahl_Anteile: float) -> float:
    """
    Berechnet die Bruttosteuer nach dem progressiven Steuertarif.
    """
    if Anteile <= 0:
        return 0.0

    Familienquotient = steuerpflichtiges_Einkommen / Anzahl_Anteile

    anwendbare_Steuerklasse = None
    for Steuerklasse in STEUERTABELLE_2019:
        if Familienquotient <= Steuerklasse["Schwellenwert"]:
            anwendbarer_Steuersatz = Steuersatz
            break

    # Wenn der Familienquotient alle Schwellenwerte überschreitet, wird der letzte Steuerbereich verwendet
    if anwendbare_Steuerklasse is None:
        anwendbare_Steuerklasse = BAREME_IMPOT_2019[-1]

    # Formel zur Berechnung der Bruttosteuer
    Bruttosteuer = (steuerpflichtiges_Einkommen * anwendbare_Steuerklasse["Steuersatz"]) - (
            anwendbare_Steuerklasse["Abzug_pro_Anteil"] * Anzahl_Anteile)

    return max(0.0, Bruttosteuer)


def anwenden_Obergrenze_qf(Bruttosteuer_mit_Kindern: float, steuerpflichtiges_Einkommen: float, Erwachsene: int,
                              Kinder: int) -> float:
    """
    Wendet bei Bedarf die Obergrenze für den Familienquotienten an.
    Die endgültige Steuer darf nicht niedriger sein als die ohne Kinder berechnete Steuer,
    abzüglich eines maximalen Gewinns pro Halbanteil.
    """
    if Kinder == 0:
        return Bruttosteuer_mit_Kindern

    # Berechnung der Steuer ohne die Anteile der Kinder
    Anteile_ohne_Kinder = Anzahl_Anteile_berechnen(Erwachsene, 0)
    Steuer_ohne_Kinder = Bruttosteuer_Basis_berechnen(steuerpflichtiges_Einkommen, Anteile_ohne_Kinder)

    # Berechnung des maximalen Kinderfreibetrags
    Anteile_mit_Kindern = Anzahl_Anteile_berechnen(Erwachsene, Kinder)
    halb_Anteile_Kinder = (Anteile_mit_Kindern - Anteile_ohne_Kinder) * 2
    maximaler_Einkommen = halbe_Kinderanteile * MAXIMALER_HALBER_ANTEIL

    Mindeststeuerobergrenze = Steuer_ohne_Kinder - maximaler_Einkommen

    # Die einbehaltene Steuer ist der höhere der beiden Beträge
    return max(Bruttosteuer_mit_Kindern, Mindeststeuer_Obergrenze)


def Rabatt_anwenden(Steuer_vor_Rabatt: float, Erwachsene: int) -> Tupel[float, float]:
    """
    Wendet den Abschlag an, wenn die Steuer unter bestimmten Schwellenwerten liegt.
    Der Abschlag wird auf den nächsten ganzen Euro aufgerundet.
    """
    status = "Paar", wenn Erwachsene == 2, sonst "Alleinstehend"
    Anwendungsschwelle = ANWENDUNGSSCHWELLE_ABZUG[Status]
    Berechnungsschwelle = SEUIL_CALCUL_DECOTE[status]

    Rabatt = 0.0
    # Der Abschlag gilt, wenn die Steuer unter dem Anwendungsschwellenwert liegt
    if Steuer_vor_Abzug < Anwendungsschwelle:
        # Formel für den Abschlag: Schwellenwert - 0,75 * Bruttosteuer
        berechneter_Abschlag = Schwellenwert_Berechnung - (0,75 * Steuer_vor_Abschlag)

        # Auf den nächsten Euro aufgerundet
        Rabatt = math.ceil(berechneter_Rabatt)

        # Der Abschlag darf weder negativ sein noch die Steuer übersteigen
        Abschlag = max(0,0, min(Abstand, Steuer_vor_Abstand))

    Steuer_nach_Abschlag = Steuer_vor_Abschlag - Abschlag
    return Steuer_nach_Abschlag, Abschlag


def 20-prozentige_Ermäßigung_anwenden(Steuer_vor_Ermäßigung: float, steuerpflichtiges_Einkommen: float, Erwachsene: int,
                                    Kinder: int) -> Tupel[float, float]:
    """
    Wendet den einkommensabhängigen Rabatt von 20 % an.
    Der Rabatt wird auf den nächsten ganzen Euro aufgerundet.
    """
    status = "Paar", wenn Erwachsene == 2, sonst "Alleinstehend"
    Basis-Schwellenwert = SEUIL_BASE_REDUCTION_20[Status]

    # Der Schwellenwert wird für jeden halben Anteil im Zusammenhang mit Kindern erhöht
    Anteile_mit_Kindern = Anzahl_Anteile_berechnen(Erwachsene, Kinder)
    Anteile_Erwachsene = Anzahl_Anteile_berechnen(Erwachsene, 0)
    Halbanteile_Kinder = (Anteile_mit_Kindern - Anteile_Erwachsene) * 2
    endgültiger_Schwellenwert = basisschwellenwert + (Halbanteile_Kinder * SCHWELLENWERT_ERHÖHUNG_PRO_HALBANTEIL)

    Ermäßigung = 0.0
    # Die Ermäßigung gilt, wenn das zu versteuernde Einkommen unter dem Schwellenwert liegt
    if steuerpflichtiges_Einkommen < Endschwelle:
        berechnete_Ermäßigung = Steuer_vor_Ermäßigung * 0.20

        # Auf den nächsten Euro aufgerundet
        Ermäßigung = math.ceil(berechnete_Ermäßigung)

    Steuer_nach_Ermäßigung = Steuer_vor_Ermäßigung - Ermäßigung
    return max(0.0, Steuer_nach_Ermäßigung), Ermäßigung


def Steuer_berechnen(Erwachsene: int, Einkommen: float, Kinder: int) -> dict:
    """
    Führt die vollständige Berechnung der zu zahlenden Nettosteuer durch.
    """
    # Schritt 1: Berechnung des steuerpflichtigen Einkommens
    steuerpflichtiges_Einkommen = berechnen_steuerpflichtiges_Einkommen(Einkommen)

    # Schritt 2: Berechnung der Anzahl der Anteile
    Anzahl_Anteile = berechnen_Anzahl_Anteile(Erwachsene, Kinder)

    # Schritt 3: Berechnung der Bruttosteuer
    ursprüngliche_Bruttosteuer = berechnen_Bruttosteuer_Basis(steuerpflichtiges_Einkommen, Anzahl_Anteile)

    # Schritt 4: Anwendung der QF-Obergrenze
    Steuer_nach_Obergrenze = Obergrenze_QF_anwenden(ursprüngliche_Bruttosteuer, steuerpflichtiges_Einkommen, Erwachsene, Kinder)

    # Schritt 5: Anwendung des Abschlags
    Steuer_nach_Abzug, berechneter_Abzug = Abzug_anwenden(Steuer_nach_Obergrenze, Erwachsene)

    # Schritt 6: Anwendung der 20-prozentigen Ermäßigung
    Steuer_vor_endgültiger_Rundung, berechnete_Ermäßigung = 20-Prozent-Ermäßigung_anwenden(Steuer_nach_Abzug,
                                                                                    steuerpflichtiges_Einkommen, Erwachsene, Kinder)

    # Schritt 7: Abschließende Rundung der Steuer auf den nächsten ganzen Euro
    endg_Steuer = math.floor(Steuer_vor_endg_Rundung)

    return {
        "Steuer": endg_Steuer,
        "Rabatt": berechneter_Rabatt,
        "reduction": reduction_calculee
    }


# --- EINZELTESTS ---
# Validierung des Skripts mit den bereitgestellten Fällen
class TestCalculImpot2019(unittest.TestCase):

    def _verifier_resultat(self, Erwachsene, Kinder, Einkommen, erwartete_Steuer, erwarteter_Abzug, erwartete_Ermäßigung):
        """Hilfsfunktion zum Ausführen eines Tests und zum Überprüfen der Ergebnisse auf 1 Euro genau."""
        resultat = berechnen_steuer(Erwachsene=Erwachsene, Einkommen=Einkommen, Kinder=Kinder)

        self.assertAlmostEqual(resultat["impot"], erwartete_Steuer, delta=1,
                               msg=f"Test ({Erwachsene}, {Kinder}, {Einkommen}): Erwartete Steuer {erwartete_Steuer}, erhaltene Steuer {Ergebnis['Steuer']}")

        self.assertAlmostEqual(resultat["Rabatt"], erwarteter_Rabatt, delta=1,
                               msg=f"Test ({Erwachsene}, {Kinder}, {Einkommen}): Erwarteter Abschlag {decote_attendue}, erhaltener {resultat['decote']}")

        self.assertAlmostEqual(resultat["reduction"], reduction_attendue, delta=1,
                               msg=f"Test ({Erwachsene}, {Kinder}, {Einkommen}): Erwarteter Rabatt {reduction_attendue}, erhaltener Rabatt {resultat['reduction']}")

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

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

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

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

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

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

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

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

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

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

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


if __name__ == '__main__':
    print("Ausführung der Unit-Tests...")
    unittest.main(argv=['first-arg-is-ignored'], exit=False)

    # Beispiel für die Verwendung des Rechners in einem konkreten Fall
    print("\n--- Berechnungsbeispiel ---")
    Jahreseinkommen = 50000
    Anzahl_Erwachsene = 2
    Anzahl_Kinder = 2

    Berechnungsergebnis = Steuerberechnung(Erwachsene=Anzahl_Erwachsener, Einkommen=Jahreseinkommen, Kinder=Anzahl_Kinder)

    print(f"Für ein Paar ({Anzahl_Erwachsene} Erwachsene) mit {Anzahl_Kinder} Kindern und einem Einkommen von {Jahreseinkommen} €:")
    print(f"  - Zu zahlende Steuer: {resultat_calcul['impot']} €")
    print(f"  - Höhe des Abschlags: {resultat_calcul['decote']} €")
    print(f"  - Höhe der Ermäßigung: {resultat_calcul['reduction']}€")

Ich habe diesen Code nicht überprüft. Da die 11 Unit-Tests bestanden wurden, gehe ich davon aus, dass er „wahrscheinlich korrekt“ ist. Ich habe für meinen eigenen Code nicht mehr getan, als diese 11 Tests zu überprüfen.

4.4. Problem 3

Problem 3 ist identisch mit Problem 2, nur dass der KI nicht mehr die PDF-Datei mit den zu beachtenden Berechnungsregeln zur Verfügung gestellt wird.

Die ursprüngliche Frage an Gemini lautet wie folgt:

 

Die Anleitungsdatei in [1] ist fast dieselbe wie bei Aufgabe 2, mit folgenden Unterschieden:


1 – Drücke dich auf Französisch aus.

2 – Kannst du ein Python-Skript erstellen, mit dem sich die von den Familien im Jahr 2019 auf ihre Einkünfte aus dem Jahr 2018 gezahlte Steuer berechnen lässt?

3 – Nutze die Quellen, die du im Internet findest. Gib diese Quellen in deiner Antwort an.

4 – Du musst folgende Punkte beachten:

  • In [3] wird er aufgefordert, im Internet die Regeln zur Berechnung der Steuer für 2019 auf die Einkünfte von 2018 zu finden. Diese Aufgabe ist schwieriger als die vorherige;

Ich gebe im Folgenden nur Teile der ersten Antwort von Gemini wieder:

 
 

Die geschätzte Zeit ist plausibel. Man wartet lange auf die Antwort von Gemini.

Wie zuvor hat Gemini einen Download-Link für das generierte Skript bereitgestellt, der jedoch nicht funktioniert. Wir weisen ihn darauf hin:

 

Die Antwort von Gemini:

 

Wir laden das Skript unter dem Namen [gemini2] in PyCharm:

 

Wir führen es aus und… es funktioniert nicht. Die Ausführungsprotokolle lauten 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" 
Teststart um 17:23 Uhr ...
Starten der Unit-Tests mit den Argumenten 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


Fehler
Traceback (most recent call last):
  Datei „C:\Data\st-2025\dev\python\code\python-flask-2025-cours\outils ia\gemini\gemini2.py“, Zeile 278, in test_cas_2
    self.assertAlmostEqual(impot, 1385, delta=1)
    ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^
AssertionError: 1691 != 1385 innerhalb von 1 Delta (306 Differenz)


Fehler
Traceback (most recent call last):
  Datei „C:\Data\st-2025\dev\python\code\python-flask-2025-cours\outils ia\gemini\gemini2.py“, Zeile 291, in test_cas_3
    impot, _, _ = calculer_impot_final(2, 3, 50000)
                  ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^
  Datei „C:\Data\st-2025\dev\python\code\python-flask-2025-cours\outils ia\gemini\gemini2.py“, Zeile 187, in calculer_impot_final
    Rabatt, Steuer_nach_Rabatt = berechnen_Rabatt(Steuer_nach_Obergrenze, Erwachsene)
                                 ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  Datei „C:\Data\st-2025\dev\python\code\python-flask-2025-cours\outils ia\gemini\gemini2.py“, Zeile 134, in calculer_decote
    Abzug = Abzugsschwelle - (Steuer_vor_Abzug * ABZUGSKOEFFIZIENT)
                                                  ^^^^^^^^^^^^^^^^^
NameError: Der Name 'COFFICIENT_DECOTE' ist nicht definiert. Meintest du vielleicht: 'COEFFICIENT_DECOTE'?


Fehler
Traceback (most recent call last):
  Datei „C:\Data\st-2025\dev\python\code\python-flask-2025-cours\outils ia\gemini\gemini2.py“, Zeile 316, in test_cas_9
    self._verifier_cas(2, 2, 30000, (0, 0, 0))
    ~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^
  Datei „C:\Data\st-2025\dev\python\code\python-flask-2025-cours\outils ia\gemini\gemini2.py“, Zeile 216, in _verifier_cas
    berechnete_Steuer, berechnete_Ermäßigung, berechnete_Reduzierung = berechnen_endg_Steuer(Erwachsene, Kinder, Einkommen)
                                                         ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^
  Datei „C:\Data\st-2025\dev\python\code\python-flask-2025-cours\outils ia\gemini\gemini2.py“, Zeile 187, in calculer_impot_final
    Rabatt, Steuer_nach_Rabatt = Rabatt_berechnen(Steuer_nach_Obergrenze, Erwachsene)
                                 ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  Datei „C:\Data\st-2025\dev\python\code\python-flask-2025-cours\outils ia\gemini\gemini2.py“, Zeile 134, in calculer_decote
    Abzug = Abzugsschwelle - (Steuer_vor_Abzug * ABZUGSKOEFFIZIENT)
                                                  ^^^^^^^^^^^^^^^^^
NameError: Der Name 'COFFICIENT_DECOTE' ist nicht definiert. Meintest du vielleicht: 'COEFFICIENT_DECOTE'?



11 Tests in 0,038 s ausgeführt

FEHLER (Fehler=1, Fehlermeldungen=2)

Prozess mit Exit-Code 1 beendet
  • Zeile 11, ein Test ist fehlgeschlagen;
  • Zeilen 25, 42: derselbe Kompilierungsfehler;

Wir speichern diese Protokolle in einer Textdatei, die wir Gemini übergeben:

 

Die Antwort von Gemini:

 
 

Wir laden das Skript in PyCharm und führen es aus. Wieder Fehler. Wir teilen dies Gemini mit und fügen erneut die Ausführungsprotokolle bei:

 

Die Antwort von Gemini:

 
 
 

Wir laden dieses neue Skript in PyCharm und führen es aus. Diesmal bestehen alle 11 Unit-Tests:

Der von Gemini generierte Code lautet wie folgt:

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

# ==============================================================================
# KONSTANTEN FÜR DIE EINKOMMENSTEUER 2018 (ZAHLUNG 2019)
# ==============================================================================
STEUERTABELLE_2019 = [
    {'Schwellenwert': 0, 'Satz': 0.0},
    {'Schwellenwert': 9964, 'Satz': 0.14},
    {'Schwellenwert': 27519, 'Satz': 0.30},
    {'Schwellenwert': 73779, 'Satz': 0,41},
    {'Schwellenwert': 156244, 'Satz': 0.45},
]
PAUSCHALABZUG_SATZ = 0,10
Pauschalabzug_Minimum = 437
PAUSCHALABZUG_OBERGRENZE = 12502
OBERGRENZE_VORTEIL_QF_HALBTEIL = 1551
ABZUGSSCHWELLE_LLEBENDER_ALLEINSTEHENDER = 1196
ABZUGSSCHWELLE_PAAR = 1970
ABZUGSKOEFFIZIENT = 0,75
REDUZIERUNGSSATZ_20_PROZENT = 0,20
Schwellenwert_RFR_Ermäßigung_Alleinstehende = 18985
GRENZWERT_RFR_ERMÄSSIGUNG_PAAR = 37970
ZUSCHLAG_RFR_REDUZIERUNG_PRO_HALBTEIL = 3803


# ==============================================================================
# BERECHNUNGSFUNKTIONEN
# ==============================================================================

def Anzahl_Anteile_berechnen(Erwachsene: int, Kinder: int) -> float:
    """Berechnet die Anzahl der Anteile des Steuerhaushalts."""
    if Erwachsene < 1: return 0
    Anteile = float(Erwachsene)
    if Kinder >= 1: Anteile += 0.5
    if Kinder >= 2: Anteile += 0.5
    if Kinder >= 3: Anteile += (Kinder - 2) * 1.0
    return Anteile


def steuerpflichtiges_Einkommen_berechnen(Bruttoeinkommen: float) -> float:
    """Berechnet das steuerpflichtige Nettoeinkommen nach Abzug von 10 %."""
    if Bruttoeinkommen == 0: return 0.0
    Abzug = Bruttoeinkommen * PAUSCHALABZUGSSATZ
    if Freibetrag < MINIMALER_PAUSCHALFREIBETRAG: Freibetrag = MINIMALER_PAUSCHALFREIBETRAG
    if Freibetrag > Pauschalfreibetrag_Obergrenze: Freibetrag = Pauschalfreibetrag_Obergrenze
    Freibetrag = math.ceil(Freibetrag)
    steuerpflichtiges_Einkommen = Bruttoeinkommen - Freibetrag
    return steuerpflichtiges_Einkommen if steuerpflichtiges_Einkommen > 0 else 0


def bruttosteuer_pro_Stufe_berechnen(steuerpflichtiges_Einkommen: float, Anteile: float) -> float:
    """Berechnet die Bruttosteuer unter Anwendung des progressiven Steuertarifs."""
    if Anzahl_Anteile <= 0 or steuerpflichtiges_Einkommen <= 0: return 0.0
    Familienquotient = steuerpflichtiges_Einkommen / Anzahl_Anteile
    Steuer_pro_Anteil = 0.0
    for i in range(len(STEUERTABELLE_2019)):
        Steuerklasse = BAREME_IMPOT_2019[i]
        aktueller_Schwellenwert = Steuerklasse['Schwellenwert']
        Steuersatz = Steuerklasse['Steuersatz']
        if Familienquotient > aktueller_Schwellenwert:
            Steuerbemessungsgrundlage_Steuerklasse = 0
            if i < len(STEUERTABELLE_2019) - 1:
                nächster_Schwellenwert = BAREME_IMPOT_2019[i + 1]['Schwellenwert']
                Steuerbemessungsgrundlage_Stufe = min(Familienquotient, nächster_Schwellenwert) - aktueller_Schwellenwert
            sonst:
                Steuerbemessungsgrundlage_Steuerklasse = Familienfreibetrag - aktueller Freibetrag
            Steuer_pro_Anteil += Steuerbemessungsgrundlage_der_Stufe * Steuersatz
    return Steuer_pro_Anteil * Anzahl_Anteile


def Obergrenze_anwenden(steuerpflichtiges_Einkommen: float, Anzahl_Anteile: float, Erwachsene: int,
                              Bruttosteuer_Familie: float) -> float:
    """Wendet die Begrenzung der Auswirkungen des Familienquotienten an."""
    if Anteile <= Erwachsene: return Bruttosteuer_Familie
    Basis_Steuer = Brutto_Steuer_pro_Einkommensklasse(steuerpflichtiges_Einkommen, float(Erwachsene))
    halb_Anteile_Kinder = (Anzahl_Anteile - Erwachsene) * 2
    maximaler_Familienquotient-Vorteil = Obergrenze_Familienquotient-Vorteil_halber_Anteil * halb_Anteile_Kinder
    tatsächlicher_QF-Vorteil = Grundsteuer  Bruttosteuer_Familie
    if tatsächlicher_QF-Vorteil > maximaler_QF-Vorteil:
        return Grundsteuer - QF-Vorteil_max
    return Bruttoeinkommen_Familie


def endg_steuer_berechnen(Erwachsene: int, Kinder: int, Einkommen: float) -> (int, int, int):
    """Führt die vollständige Steuerberechnung durch."""
    steuerpflichtiges_Einkommen = berechnen_steuerpflichtiges_Einkommen(Einkommen)
    Anzahl_Anteile = berechnen_Anzahl_Anteile(Erwachsene, Kinder)
    Bruttosteuer = Bruttosteuer_pro_Stufe_berechnen(steuerpflichtiges_Einkommen, Anzahl_Anteile)
    Steuer_nach_Obergrenze = Obergrenze_anwenden(steuerpflichtiges_Einkommen, Anzahl_Anteile, Erwachsene, Bruttosteuer)

    # KORREKTUR: Wenn die Steuer bereits 0 ist, erfolgt keine Ermäßigung oder Reduzierung.
    if Steuer_nach_Obergrenze == 0:
        return 0, 0, 0

    # --- KORRIGIERTE LOGIK FÜR DIE INTERAKTION ZWISCHEN ABZUG UND ERMÄSSIGUNG ---
    berechneter_Abschlag = 0.0
    berechnete_Ermäßigung = 0.0
    zu_bearbeitende_Steuer = Steuer_nach_Obergrenze

    # 1. Feststellen der Berechtigung für den Rabatt von 20 %
    ist_rabattberechtigt = False
    if Erwachsene >= 2:
        Schwellenwert_RFR = SCHWELLENWERT_RFR_ERMÄSSIGUNG_PAAR + max(0, (Anzahl_Anteile - 2) * 2) * AUFSCHLAG_RFR_ERMÄSSIGUNG_PRO_HALBEN_ANTEIL
    else:
        Schwellenwert_RFR = SCHWELLENWERT_RFR_ERMÄSSIGUNG_ALLEINSTÄNDIGE + max(0, (
                Anzahl_Anteile - 1) * 2) * RFR-ERHÖHUNG_REDUZIERUNG_PRO_HALB_ANTEIL
    if steuerpflichtiges_Einkommen < Schwellenwert_RFR:
        ist_anspruchsberechtigt_auf_Ermäßigung = True

    # 2. Feststellen der Anspruchsberechtigung auf den Abschlag
    Schwellenwert_Ermäßigung_Haushalt = SCHWELLENWERT_ERMÄSSIGUNG_PAAR if Erwachsene >= 2 else SCHWELLENWERT_ERMÄSSIGUNG_ALLEINSTÄNDIG
    theoretische_Ermäßigung = math.ceil(zu_verarbeitende_Steuer * ERMÄSSIGUNGSSATZ_20_PROZENT) if ist_ermäßigungsberechtigt else 0

    if (zu_verarbeitende_Steuer - theoretischer_Rabatt) < Schwellenwert_Rabatt_Haushalt:
        berechneter_Rabatt = Schwellenwert_Rabatt_Haushalt - (zu_verarbeitende_Steuer * RABATTKOEFFIZIENT)
        berechneter_Abschlag = math.ceil(berechneter_Abschlag)
        # KORREKTUR: Der zurückgegebene Abschlag darf die Steuer, die er aufhebt, nicht übersteigen
        berechneter_Abschlag = min(berechneter_Abschlag, math.ceil(zu_behandelnde_Steuer))
        zu_behandelnde_Steuer -= berechneter_Abschlag
        zu_verarbeitende_Steuer = max(0.0, zu_verarbeitende_Steuer)

    # 3. 20 %-Ermäßigung anwenden, falls berechtigt
    if ist_ermäßigungsberechtigt:
        berechneter_Rabatt = math.ceil(zu_behandelnde_Steuer * RABATT_20_PROZENT)
        zu_behandelnde_Steuer -= berechneter_Rabatt
        zu_behandelnde_Steuer = max(0.0, zu_behandelnde_Steuer)

    endg_steuer = math.floor(zu_bearbeitende_steuer)

    return Endsteuerbetrag, int(berechneter Rabatt), int(berechnete Ermäßigung)


# ==============================================================================
# EINZELTESTS
# ==============================================================================

class TestCalculImpot2019(unittest.TestCase):
    def _verifier_cas(self, Erwachsene, Kinder, Einkommen, Erwartet):
        erwartete_Steuer, erwarteter_Abschlag, erwartete_Ermäßigung = erwarteter
        berechnete_Steuer, berechneter_Abzug, berechnete_Ermäßigung = berechnen_endg_Steuer(Erwachsene, Kinder, Einkommen)
        self.assertAlmostEqual(berechnete_Steuer, erwartete_Steuer, delta=1, msg=f"Steuer ({berechnete_Steuer} vs {erwartete_Steuer})")
        self.assertAlmostEqual(berechneter_Abschlag, erwarteter_Abschlag, delta=1,
                               msg=f"Abschlag ({berechneter_Abschlag} vs {erwarteter_Abschlag})")
        self.assertAlmostEqual(berechneter_Rabatt, erwarteter_Rabatt, delta=1,
                               msg=f"Rabatt ({berechneter_Rabatt} vs {erwarteter_Rabatt})")

    def test_fall_1(self): self._fall_prüfer(2, 2, 55555, (2815, 0, 0))

    def test_case_2(self): self._verify_case(2, 2, 50000, (1385, 384, 346))

    def test_case_3(self): self._verify_case(2, 3, 50000, (0, 720, 0))

    def test_case_4(self): self._verifier_case(1, 2, 100000, (19884, 0, 0))

    def test_case_5(self): self._verifier_case(1, 3, 100000, (16782, 0, 0))

    def test_case_6(self): self._verifier_case(2, 3, 100000, (9200, 0, 0))

    def test_case_7(self): self._verifier_case(2, 5, 100000, (4230, 0, 0))

    def test_case_8(self): self._verifier_case(1, 0, 100000, (22986, 0, 0))

    def test_case_9(self): self._verifier_case(2, 2, 30000, (0, 0, 0))

    def test_case_10(self): self._verifier_case(1, 0, 200000, (64211, 0, 0))

    def test_case_11(self): self._verifier_case(2, 3, 200000, (42843, 0, 0))


if __name__ == '__main__':
    print("Start der Unit-Tests für die Steuerberechnung 2019...")
    unittest.main(argv=['first-arg-is-ignored'], exit=False)

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

Aber man könnte neugierig sein, wie er zu diesem Ergebnis kommt, insbesondere bei den Sonderfällen der Steuerberechnung. Wir fragen ihn:

 

Es handelt sich um einen Fall mit hohem Einkommen, bei dem sowohl eine mögliche Begrenzung des Freibetrags von 10 % als auch eine mögliche Begrenzung des Familienquotienten vorliegt.

Die Antwort von Gemini lautet wie folgt:

 
 
 
 
 

Diese beiden letzten Screenshots sind interessant. Gemini verwendet eine andere Berechnungsmethode als die im PDF erläuterte. Diese Berechnungsmethode findet man tatsächlich im Internet. Beide Methoden sind gleichwertig.

 
 
 

Die Erklärung besticht durch ihre Klarheit. Man könnte sie so wie sie ist an Studierende weitergeben, um die Methode zur Steuerberechnung zu erklären.

Nehmen wir nun ein weiteres Beispiel, diesmal mit geringem Einkommen. In diesem Fall kann es zu einem Abschlag und einer Ermäßigung kommen:

 

Die Antwort von Gemini lautet wie folgt:

 
 
 
 
 

Hier stellt man fest, dass Gemini eine Regel anwendet, die nicht im PDF steht. Er hat sie wahrscheinlich im Internet gefunden, aber ist die Quelle zuverlässig?

 

Auch hier wendet Gemini weiterhin eine unbekannte Regel an (die oben genannte Sonderregel).

 
 
 

Die Ergebnisse von Gemini stimmen also mit dem Ergebnis des offiziellen Steuerrechners überein. Aber er hat eine Regel verwendet, die nicht im PDF steht. Wo liegt der Fehler? Wir fragen ihn danach und fügen das PDF bei:

 

Die Antwort von Gemini:

 
 
 
 

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

  • Bei dem seine Argumentation zu denselben Ergebnissen führen würde wie der offizielle Steuersimulator;
  • wobei die Argumentation im PDF zu anderen Ergebnissen führen würde als der Simulator;
 

Die Antwort von Gemini lautet wie folgt:

 

Hier irrt sich Gemini. Ich habe den Simulator mit diesem Beispiel gestartet und Folgendes festgestellt:

 

Wir werden jedoch feststellen, dass die Argumentation von Gemini tatsächlich zu den oben genannten Ergebnissen führt. Weiter geht’s:

 
 
 
 

Sehr gut. Das ist notiert. Weiter geht’s:

 
 
 
 

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

 

Gemini antwortet:

 
 

Nun fragen wir uns, ob Gemini ein korrigiertes PDF erstellen könnte:

 

Die Antwort von Gemini:

 

Gemini hat mir also keinen Link zu einer PDF-Datei gegeben, sondern einen Text generiert, mit dem ich diese PDF-Datei selbst erstellen kann. Auch wenn es hier etwas umständlich ist, die Screenshots der PDF-Datei einzufügen, tue ich es dennoch, damit der Leser die generative Seite der KI erkennen kann:

 

Image

Image

Image

Image

Image

Image

Image

Image

Image

Image

Image

Image

Image

Ehrlich gesagt habe ich nicht überprüft, ob alles, was in diesem PDF steht, stimmt. Auf jeden Fall ist es ein perfektes Dokument für eine Übung, das in wenigen Sekunden erstellt ist.

Dennoch kann man von Gemini selbst überprüfen lassen, ob sein PDF in Ordnung ist. Man startet eine neue Konversation:

 
  • in [1] haben wir das von Gemini generierte PDF [Das Problem laut Gemini.pdf] eingefügt;
  • in [2] ist [instructionsAvecPDF2.txt] identisch mit den Anweisungen in [instructionsAvecPDF.txt], abgesehen davon, dass wir einen zwölften Unit-Test hinzugefügt haben, genau den, der gezeigt hat, dass das ursprüngliche PDF fehlerhaft war:
test12: (2, 2, 49500) -> (1297, 431, 324)

Seltsamerweise waren mehrere Durchläufe nötig, bevor Gemini das richtige Skript generierte:

Frage 2

 

Frage 3

 

Wie bereits mehrfach geschehen, geben wir Gemini die Textdatei mit den Ausführungsprotokollen, wenn das generierte und in PyCharm geladene Skript fehlschlägt. Gemini versteht diese sehr gut.

Frage 4

 

Frage 5

 

Frage 6 und Ende

Nun sind wir von der Richtigkeit des von Gemini generierten PDFs überzeugt. Die darin angegebenen Berechnungsregeln sind korrekt.

Wir werden nun dasselbe für die fünf anderen KI-Systeme tun, uns dabei jedoch in unseren Erläuterungen sehr kurz fassen, außer bei ChatGPT, der derzeit führenden KI. Uns interessiert vor allem, ob die KI die drei gestellten Aufgaben löst oder nicht. Tatsächlich sind die Benutzeroberflächen all dieser KI-Systeme sehr ähnlich, und ich bin bei ihnen genauso vorgegangen wie bei Gemini. Der Leser ist aufgefordert, die Gemini-Gespräche mit der KI seiner Wahl nachzuspielen.