Skip to content

8. Anwendungsübung – Version 1

8.1. Das Problem

Anhand der obigen Tabelle können wir die Steuer im vereinfachten Fall eines Steuerpflichtigen berechnen, der nur sein Gehalt anzugeben hat. Wie in Anmerkung (1) angegeben, handelt es sich bei der auf diese Weise berechneten Steuer um die Steuer vor Anwendung der folgenden drei Mechanismen:

  • die Obergrenze für den Familienquotienten, die für hohe Einkommen gilt;
  • die Steuergutschrift und die Steuerermäßigung, die für niedrige Einkommen gelten;

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

Image

Wir schlagen vor, ein Programm zu schreiben, das die Steuer eines Steuerpflichtigen im vereinfachten Fall berechnet, in dem dieser nur sein Gehalt anzugeben hat:

8.1.1. Berechnung der Bruttosteuer

Die Bruttosteuer lässt sich wie folgt berechnen:

Zunächst berechnen wir die Anzahl der Anteile des Steuerpflichtigen:

  • Jeder Elternteil trägt 1 Anteil bei;
  • die ersten beiden Kinder bringen jeweils 1/2 Anteil ein;
  • die weiteren Kinder bringen jeweils einen Anteil ein:

Die Anzahl der Anteile beträgt daher:

  • nbParts=1+nbChildren*0,5+(nbChildren-2)*0,5, wenn der Arbeitnehmer unverheiratet ist;
  • nbParts=2+nbChildren*0,5+(nbChildren-2)*0,5, wenn er verheiratet ist;
    • wobei nbChildren die Anzahl der Kinder ist;
  • wir berechnen das zu versteuernde Einkommen R = 0,9 * S, wobei S das Jahresgehalt ist;
  • Der Familienquotient QF wird berechnet als QF = R / nbParts;
  • Wir berechnen die Bruttosteuer I auf der Grundlage der folgenden Daten (2019):
9964
0
0
27.519
0,14
1.394,96
73.779
0,3
5.798
156.244
0,4
13.913,69
0
0,45
20163,45

Jede Zeile enthält 3 Felder: Feld1, Feld2, Feld3. Um die Steuer I zu berechnen, suchen wir die erste Zeile, in der QF <= Feld1 ist, und übernehmen die Werte aus 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 = 45.000 / 3 = 15.000

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*AnzahlAktien=[0,14*45000-1394,96*3]=2115. Die Steuer wird auf den nächsten Euro abgerundet.

Wenn in der ersten Zeile die Bedingung QF <= Feld1 erfüllt ist, beträgt die Steuer null.

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

    0    0.45    20163.45

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

8.1.2. Obergrenze für den Familienquotienten

Um festzustellen, ob die Obergrenze für den Familienquotienten (QF) gilt, berechnen wir die Bruttosteuer ohne die Kinder neu. Noch einmal 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 (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*Anzahl der Aktien = [0,14*45.000 – 1394,96*2] = 3.510.

Maximaler Kinderfreibetrag: 1551 * 2 = 3102 Euro

Mindeststeuer: 3.510 – 3.102 = 408 Euro

Die Bruttosteuer mit 3 Steuerklassen, die bereits auf 2.115 Euro berechnet wurde, ist höher als die Mindeststeuer von 408 Euro, daher gilt die Familienobergrenze hier nicht.

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

  • [Steuer1]: die Bruttosteuer ist, die unter Berücksichtigung der Kinder berechnet wurde;
  • [Steuer2]: die Bruttosteuer ist, die ohne Kinder berechnet und um den maximalen Kinderfreibetrag (hier 1.551 Euro pro Halbanteil) reduziert wurde;

8.1.3. Berechnung der Ermäßigung

Image

Wir verwenden weiterhin das Beispiel eines verheirateten Arbeitnehmers mit zwei Kindern und einem Jahresgehalt S von 50.000 Euro:

Die Bruttosteuer (2.115) aus dem vorherigen Schritt liegt unter 2.627 Euro für ein Ehepaar (1.595 Euro für eine alleinstehende Person): Die Ermäßigung kommt daher zur Anwendung. Sie berechnet sich wie folgt:

Ermäßigung = Schwellenwert (Ehepaar = 1.970 / Alleinstehender = 1.196) – 0,75 * Bruttosteuer

Rabatt = 1.970 – 0,75 * 2.115 = 383,75, gerundet auf 384 Euro.

Neue Bruttosteuer = 2.115 – 384 = 1.731 Euro

8.1.4. Berechnung der Steuerermäßigung

Image

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

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

Dieser Schwellenwert wird um den Wert 3.797 * (Anzahl der von den Kindern eingebrachten Halbanteile) erhöht.

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

  • liegt sein zu versteuerndes Einkommen (45.000 Euro) unter dem Schwellenwert (42.074 + 2 × 3.797) = 49.668 Euro;
  • er hat daher Anspruch auf eine Steuerermäßigung von 20 %: 1.731 * 0,2 = 346,2 Euro, aufgerundet auf 347 Euro;
  • die Bruttosteuer des Steuerpflichtigen beträgt: 1.731 – 347 = 1.384 Euro;

8.1.5. Berechnung der Nettosteuer

Unsere Berechnung endet hier: Die zu zahlende Nettosteuer beträgt 1.384 Euro. In der Praxis hat der Steuerpflichtige möglicherweise Anspruch auf weitere Abzüge, insbesondere für Spenden an gemeinnützige oder im öffentlichen Interesse tätige Organisationen.

8.1.6. Fälle mit hohem Einkommen

Unser vorheriges Beispiel gilt für die Mehrheit der Arbeitnehmer. Für Personen mit hohem Einkommen sieht die Steuerberechnung jedoch anders aus.

8.1.6.1. Obergrenze für die 10-prozentige Reduzierung des Jahreseinkommens

In den meisten Fällen wird das zu versteuernde Einkommen nach folgender Formel berechnet: R = 0,9 × S, wobei S das Jahresgehalt ist. Dies wird als 10-Prozent-Abzug bezeichnet. Dieser Abzug ist begrenzt. Im Jahr 2019

  • darf sie 12.502 Euro nicht überschreiten;
  • sie darf nicht weniger als 437 Euro betragen;

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

  • Die 10-prozentige Kürzung beträgt 200.000 Euro > 12.502 Euro. Sie ist daher auf 12.502 Euro begrenzt;

8.1.6.2. Obergrenze für den Familienquotienten

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

  • Der 10-prozentige Abzug beträgt 10.000 Euro < 12.502 Euro. Das zu versteuernde Einkommen R beträgt daher 100.000 – 10.000 = 90.000 Euro;
  • das Paar hat nbParts = 2 + 0,5 × 2 + 1 = 4 Anteile;
  • ihr Familienquotient beträgt daher QF = R / nbParts = 90.000 / 4 = 22.500 Euro;
  • ihre Bruttosteuer I1 mit Kindern beträgt I1 = 0,14 × 90.000 – 1.394,96 × 4 = 7.020 Euro;
  • ihre Bruttosteuer I2 ohne Kinder:
  • QF = 90.000 / 2 = 45.000 Euro;
  • I2 = 0,3 × 90.000 – 5.798 × 2 = 15.404 Euro;
  • die Obergrenze für den Familienquotienten besagt, dass der durch Kinder gewährte Vorteil (1.551 × 4 halbe Anteile) = 6.204 Euro nicht überschreiten darf. Hier beträgt er jedoch I2 – I1 = 15.404 – 7.020 = 8.384 Euro, was mehr als 6.204 Euro ist;
  • die Bruttosteuer wird daher neu berechnet als I3 = I2 – 6.204 = 15.404 – 6.204 = 9.200 Euro;

Dieses Paar erhält weder eine Steuergutschrift noch eine Ermäßigung, und seine endgültige Steuer beträgt 9.200 Euro.

8.1.7. Offizielle Zahlen

Die Berechnung von Steuern ist komplex. In diesem Dokument basieren die Berechnungen auf den folgenden Beispielen. 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 = 2.815 Euro
Steuersatz = 14 %
Steuer = 2.814 Euro
Steuersatz = 14 %
Paar mit 2 Kindern und einem Jahreseinkommen von 50.000 Euro ( )
Steuer = 1.385 Euro
Steuergutschrift = 720 Euro
Ermäßigung = 0 Euro
Steuersatz = 14 %
Steuer = 1.384 Euro
Rabatt = 384 Euro
Gutschrift = 347 Euro
Steuersatz = 14 %
Paar mit 3 Kindern und einem Jahreseinkommen von 50.000 Euro
Steuer = 0 Euro
Steuergutschrift = 384 Euro
Ermäßigung = 346 Euro
Steuersatz = 14 %
Steuer = 0 Euro
Rabatt = 720 Euro
Abzug = 0 Euro
Steuersatz = 14 %
Alleinstehend mit 2 Kindern und einem Jahreseinkommen von 100.000 Euro
Steuer = 19.884 Euro
Steuergutschrift = 0 Euro
Abzug = 0 Euro
Steuersatz = 41 %
Steuer = 19.884 Euro
Zuschlag = 4.480 Euro
Rabatt = 0 Euro
Ermäßigung = 0 Euro
Steuersatz = 41 %
Alleinerziehend mit 3 Kindern und einem Jahreseinkommen von 100.000 Euro
Steuer = 16.782 Euro
Steuergutschrift = 0 Euro
Abzug = 0 Euro
Steuersatz = 41 %
Steuer = 16.782
Zuschlag = 7.176 Euro
Rabatt = 0 Euro
Ermäßigung = 0 Euro
Steuersatz = 41 %
Paar mit 3 Kindern und einem Jahreseinkommen von 100.000 Euro
Steuer = 9.200 Euro
Steuergutschrift = 0 Euro
Abzug = 0 Euro
Steuersatz = 30 %
Steuer = 9.200 €
Zuschlag = 2.180 Euro
Rabatt = 0 Euro
Ermäßigung = 0 Euro
Steuersatz = 30 %
Paar mit 5 Kindern und einem Jahreseinkommen von 100.000 Euro
Steuer = 4.230 Euro
Steuergutschrift = 0 Euro
Abzug = 0 Euro
Steuersatz = 14 %
Steuer = 4.230
Rabatt = 0 Euro
Abzug = 0 Euro
Steuersatz = 14 %
Alleinstehend, keine Kinder, Jahreseinkommen von 100.000 Euro
Steuer = 22.986 Euro
Steuergutschrift = 0 Euro
Abzug = 0 Euro
Steuersatz = 41 %
Steuer = 22.986 Euro
Zuschlag = 0 Euro
Rabatt = 0 Euro
Ermäßigung = 0 Euro
Steuersatz = 41 %
Paar mit 2 Kindern und einem Jahreseinkommen von 30.000 Euro
Steuer = 0 Euro
Steuergutschrift = 0 Euro
Abzug = 0 Euro
Steuersatz = 0 %
Steuer = 0 Euro
Rabatt = 0 Euro
Ermäßigung = 0 Euro
Steuersatz = 0 %
Alleinstehend ohne Kinder und mit einem Jahreseinkommen von 200.000 Euro
Steuer = 64.211 Euro
Steuergutschrift = 0 Euro
Abzug = 0 Euro
Steuersatz = 45 %
Steuer = 64.210 Euro
Zuschlag = 7.498 Euro
Rabatt = 0 Euro
Ermäßigung = 0 Euro
Steuersatz = 45 %
Paar mit 3 Kindern und einem Jahreseinkommen von 200.000 Euro
Steuer = 42.843 Euro
Steuergutschrift = 0 Euro
Abzug = 0 Euro
Steuersatz = 41 %
Steuer = 42.842 Euro
Zuschlag = 17.283 Euro
Rabatt = 0 Euro
Ermäßigung = 0 Euro
Steuersatz = 41 %

Im obigen Beispiel bezieht sich der „Zuschlag“ auf den zusätzlichen Betrag, den Personen mit hohem Einkommen aufgrund von zwei Faktoren zahlen:

  • die Obergrenze für den 10-prozentigen Abzug vom Jahreseinkommen;
  • die Obergrenze für den Familienfreibetrag;

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

Wir können sehen, dass der Algorithmus des Dokuments jedes Mal den korrekten Steuerbetrag berechnet, wenn auch mit einer Abweichung von 1 Euro. Diese Abweichung resultiert aus der Rundung. Alle Geldbeträge werden in einigen Fällen auf den nächsten Euro aufgerundet und in anderen Fällen auf den nächsten Euro abgerundet. Da ich mit den offiziellen Regeln nicht vertraut war, wurden die Geldbeträge im Algorithmus des Dokuments gerundet:

  • bei Rabatten und Ermäßigungen auf den nächsten Euro aufgerundet;
  • auf den nächsten Euro abwärts bei Zuschlägen und der endgültigen Steuer;

Wir werden mehrere Versionen der Steuerberechnungsanwendung entwickeln.

8.2. Version 1

Image

8.2.1. Das Hauptskript

Wir stellen ein erstes Programm vor, in dem:

  • die zur Berechnung der Steuer benötigten Daten als Listen und Konstanten fest im Code hinterlegt sind;
  • die Steuerzahlerdaten (verheiratet, Kinder, Gehalt) in einer ersten Textdatei [taxpayersdata.txt] gespeichert sind;
  • die Ergebnisse der Steuerberechnung (verheiratet, Kinder, Gehalt, Steuer) in einer zweiten Textdatei [results.txt] gespeichert werden;

Das Skript [v-01/main.py] lautet wie folgt:

#  modules
import sys

from impots.v01.shared.impôts_module_01 import *

#  hand -----------------------

#  constants
#  taxpayer file
DATA = "./data/taxpayersdata.txt"
#  results file
RESULTATS = "./data/résultats.txt"

try:
    #  reading taxpayer data
    tax_payers = get_taxpayers_data(DATA)
    #  results list
    results = []
    #  taxpayers' taxes are calculated
    for tax_payer in tax_payers:
        #  tax calculation returns a dictionary of keys
        #  ['married', 'children', 'salary', 'tax', 'surcôte', 'décôte', 'réduction', 'taux']
        result = calcul_impôt(tax_payer['marié'], tax_payer['enfants'], tax_payer['salaire'])
        #  the dictionary is added to the list of results
        results.append(result)
    #  we record the results
    record_results(RESULTATS, results)
except BaseException as erreur:
    #  there may be various errors: no file, incorrect file content
    #  display the error and exit the application
    print(f"l'erreur suivante s'est produite : {erreur}]\n")
    sys.exit()

Anmerkungen

  • Zeile 4: Wir verwenden das Modul [impots.v01.modules.impôts_module_01]. Beachten Sie, dass dieser Pfad relativ zum Stammverzeichnis des PyCharm-Projekts ist;
  • Zeile 10: Die Datei [data/taxpayersdata.txt] sieht wie folgt aus:
oui,2,55555
oui,2,50000
oui,3,50000
non,2,100000
non,3,100000
oui,3,100000
oui,5,100000
non,0,100000
oui,2,30000
non,0,200000
oui,3,200000

Jede Zeile stellt ein Tupel aus drei Elementen dar [verheiratet/in einer eingetragenen Lebenspartnerschaft oder nicht, Anzahl der Kinder, Jahresgehalt in Euro].

  • Zeile 12: Die Datei, in der die Ergebnisse der Steuerberechnung für jeden Steuerzahler in der Datei [taxpayersdata.txt] gespeichert werden. Sie hat folgenden Inhalt:
{'marié': 'oui', 'enfants': 2, 'salaire': 55555, 'impôt': 2814, 'surcôte': 0, 'décôte': 0, 'réduction': 0, 'taux': 0.14}
{'marié': 'oui', 'enfants': 2, 'salaire': 50000, 'impôt': 1384, 'surcôte': 0, 'décôte': 384, 'réduction': 347, 'taux': 0.14}
{'marié': 'oui', 'enfants': 3, 'salaire': 50000, 'impôt': 0, 'surcôte': 0, 'décôte': 720, 'réduction': 0, 'taux': 0.14}
{'marié': 'non', 'enfants': 2, 'salaire': 100000, 'impôt': 19884, 'surcôte': 4480, 'décôte': 0, 'réduction': 0, 'taux': 0.41}
{'marié': 'non', 'enfants': 3, 'salaire': 100000, 'impôt': 16782, 'surcôte': 7176, 'décôte': 0, 'réduction': 0, 'taux': 0.41}
{'marié': 'oui', 'enfants': 3, 'salaire': 100000, 'impôt': 9200, 'surcôte': 2180, 'décôte': 0, 'réduction': 0, 'taux': 0.3}
{'marié': 'oui', 'enfants': 5, 'salaire': 100000, 'impôt': 4230, 'surcôte': 0, 'décôte': 0, 'réduction': 0, 'taux': 0.14}
{'marié': 'non', 'enfants': 0, 'salaire': 100000, 'impôt': 22986, 'surcôte': 0, 'décôte': 0, 'réduction': 0, 'taux': 0.41}
{'marié': 'oui', 'enfants': 2, 'salaire': 30000, 'impôt': 0, 'surcôte': 0, 'décôte': 0, 'réduction': 0, 'taux': 0}
{'marié': 'non', 'enfants': 0, 'salaire': 200000, 'impôt': 64210, 'surcôte': 7498, 'décôte': 0, 'réduction': 0, 'taux': 0.45}
{'marié': 'oui', 'enfants': 3, 'salaire': 200000, 'impôt': 42842, 'surcôte': 17283, 'décôte': 0, 'réduction': 0, 'taux': 0.41}
  • Zeile 16: Wir rufen die in [taxpayersdata.txt] enthaltenen Steuerzahlerdaten ab. Wir erhalten eine Liste von Wörterbüchern mit den Schlüsseln [verheiratet, Kinder, Gehalt], wobei jedes Wörterbuch einen Steuerzahler repräsentiert;
  • Zeilen 17–25: Die Steuer für die Steuerzahler in der Liste [taxPayers] wird berechnet. Es wird eine Liste [results] zurückgegeben, wobei jedes Element wiederum ein Wörterbuch mit den Schlüsseln [verheiratet, Kinder, Gehalt, Steuer, Zuschlag, Rabatt, Ermäßigung, Satz] ist;
  • Zeile 27: Die Liste [results] wird im oben gezeigten Format in der Datei [results.txt] gespeichert;
  • Zeilen 28–32: Wir fangen alle Ausnahmen ab, die vom Modul [impots.v01.modules.impôts_module_01] ausgelöst werden können;

Wir werden nun die drei Funktionen, die vom Skript [main] verwendet werden, im Detail beschreiben:

  • [get_taxpayers_data]: zum Einlesen der Steuerzahlerdaten;
  • [calcul_impôt]: zur Berechnung ihrer Steuern;
  • [record_results]: zum Speichern der Ergebnisse in einer Textdatei;

Alle diese Funktionen befinden sich im Modul [impots.modules.impôts_module_01].

8.2.2. Das Modul [impots.v01.shared.impôts_module_01]

Die für die Steuerberechnung erforderlichen Funktionen wurden im Modul [impots.v01.shared.impôts_module_01] zusammengefasst:

Image

  • in [1]: Definition der Konstanten für die Steuerberechnung;
  • in [2]: die Liste der Funktionen im Modul;

8.2.3. Die Funktion [get_taxpayers_data]

Die Funktion [get_taxpayers_data] lautet wie folgt:

#  imports
import codecs


#  reading taxpayer data
# ----------------------------------------
def get_taxpayers_data(taxpayers_filename: str) -> list:
    #  reading taxpayer data
    file = None
    try:
        #  list of taxpayers
        taxpayers = []
        #  open file
        file = codecs.open(taxpayers_filename, "r", "utf8")
        #  read the first line of the taxpayer file
        ligne = file.readline().strip()
        #  as long as there's a line left to operate
        while ligne != '':
            #  we retrieve the 3 fields married,children,salary which form the line
            (marié, enfants, salaire) = ligne.split(",")
            #  we add them to the list of taxpayers
            taxpayers.append({'marié': marié.strip().lower(), 'enfants': int(enfants), 'salaire': int(salaire)})
            #  a new line is read from the taxpayer file
            ligne = file.readline().strip()
        #  we return the result
        return taxpayers
    finally:
        #  close the file if it has been opened
        if file:
            file.close()

Anmerkungen

  • Zeile 7: [taxpayers_filename] ist der Name der zu verarbeitenden Datei. Die Funktion gibt eine Liste zurück;
  • Zeilen 18–24: Die Schleife verarbeitet die Zeilen [married, children, salary] der Textdatei;
  • Zeile 20: Die drei Elemente der Zeile werden abgerufen. Wir gehen hier davon aus, dass die Zeile syntaktisch korrekt ist, d. h., dass sie tatsächlich die drei erwarteten Elemente enthält;
  • Zeile 22: Es wird ein Wörterbuch mit den Schlüsseln [married, children, salary] erstellt, und dieses Wörterbuch wird der Liste [taxPayers] hinzugefügt;
  • Zeile 26: Sobald die Datei verarbeitet wurde, wird die Liste [taxPayers] zurückgegeben;
  • Zeilen 10–30: Beachten Sie, dass dem [try]-Block in Zeile 10 keine [catch]-Klausel hinzugefügt wurde. Die [catch]-Klausel ist nicht zwingend erforderlich. In Zeile 27 wurde eine [finally]-Klausel hinzugefügt, um die Textdatei in jedem Fall zu schließen, unabhängig davon, ob ein Fehler auftritt oder nicht;
  • Diese try/finally-Struktur lässt eine mögliche Ausnahme durch (es gibt kein catch). Diese Ausnahme wird an das Hauptskript [main] weitergeleitet, das dann stoppt und die Ausnahme anzeigt (siehe Abschnitt |Das Hauptskript|). Dieser Mechanismus wurde für die meisten Funktionen des Moduls verwendet;

8.2.4. Die Funktion [calcul_impôt]

Die Funktion [calcul_impôt] lautet wie folgt:

#  imports
import codecs
import math

#  2019 tax brackets
limites = [9964, 27519, 73779, 156244, 0]
coeffr = [0, 0.14, 0.3, 0.41, 0.45]
coeffn = [0, 1394.96, 5798, 13913.69, 20163.45]

#  constant for 2019 tax calculation
PLAFOND_QF_DEMI_PART = 1551
PLAFOND_REVENUS_CELIBATAIRE_POUR_REDUCTION = 21037
PLAFOND_REVENUS_COUPLE_POUR_REDUCTION = 42074
VALEUR_REDUC_DEMI_PART = 3797
PLAFOND_DECOTE_CELIBATAIRE = 1196
PLAFOND_DECOTE_COUPLE = 1970
PLAFOND_IMPOT_COUPLE_POUR_DECOTE = 2627
PLAFOND_IMPOT_CELIBATAIRE_POUR_DECOTE = 1595
ABATTEMENT_DIXPOURCENT_MAX = 12502
ABATTEMENT_DIXPOURCENT_MIN = 437


#  tAX CALCULATION
# ----------------------------------------
def calcul_impôt(marié: str, enfants: int, salaire: int) -> dict:
    #  married: yes, no
    #  children: number of children
    #  salary: annual salary
    #  limits, coeffr, coeffn: data tables for tax calculation
    #
    #  tax calculation with children
    result1 = calcul_impôt_2(marié, enfants, salaire)
    impot1 = result1["impôt"]
    #  tax calculation without children
    if enfants != 0:
        result2 = calcul_impôt_2(marié, 0, salaire)
        impot2 = result2["impôt"]
        #  application of the family allowance ceiling
        if enfants < 3:
            #  PLAFOND_QF_DEMI_PART euros for the first 2 children
            impot2 = impot2 - enfants * PLAFOND_QF_DEMI_PART
        else:
            #  PLAFOND_QF_DEMI_PART euros for the first 2 children, double for subsequent children
            impot2 = impot2 - 2 * PLAFOND_QF_DEMI_PART - (enfants - 2) * 2 * PLAFOND_QF_DEMI_PART
    else:
        impot2 = impot1
        result2 = result1

    #  we take the highest tax with the rate and surcharge that go with it
    if impot1 > impot2:
        impot = impot1
        taux = result1["taux"]
        surcôte = result1["surcôte"]
    else:
        surcôte = impot2 - impot1 + result2["surcôte"]
        impot = impot2
        taux = result2["taux"]

    #  calculation of any discount
    décôte = get_décôte(marié, salaire, impot)
    impot -= décôte
    #  calculation of any tax reduction
    réduction = get_réduction(marié, salaire, enfants, impot)
    impot -= réduction
    #  result
    return {"marié": marié, "enfants": enfants, "salaire": salaire, "impôt": math.floor(impot), "surcôte": surcôte,
            "décôte": décôte, "réduction": réduction, "taux": taux}

Anmerkungen

  • Zeilen 6–8: Steuerklassen (siehe Abschnitt |Berechnung der Bruttosteuer|);
  • Zeilen 11–20: Konstanten für die Steuerberechnung;
  • Beachten Sie, dass die in den Zeilen 5–20 initialisierten Elemente für die Funktionen, die wir gleich beschreiben werden, global sind. Sie sind daher bekannt, solange die Funktion, die sie verwendet, keine Variablen mit denselben Namen deklariert;
  • die Zahlen in den Zeilen 5–20 ändern sich jedes Jahr. Hier handelt es sich um die Zahlen für 2019;
  • Zeile 25: Die Funktion [calculate_tax] nimmt drei Parameter entgegen:
    • [married]: ja/nein, gibt an, ob der Steuerzahler verheiratet ist oder in einer eingetragenen Lebenspartnerschaft lebt;
    • [children]: die Anzahl der Kinder;
    • [salary]: sein Jahresgehalt in Euro;
  • Zeilen 31–33: Steuerberechnung unter Berücksichtigung der Kinder;
  • Zeilen 34–47: Diese Zeilen implementieren die Begrenzung des Familienquotienten (siehe Abschnitt |Begrenzung des Familienquotienten|);
  • Zeilen 49–57: In diesen Zeilen werden der Steuersatz des Steuerpflichtigen sowie etwaige Zuschläge berechnet (siehe Abschnitt |Fälle mit hohem Einkommen|);
  • Zeilen 59–61: Berechnung etwaiger Steuergutschriften (siehe Abschnitt |Berechnung der Steuergutschrift|);
  • Zeilen 62–64: Berechnung etwaiger Steuerermäßigungen (siehe Abschnitt |Berechnung der Steuerermäßigung|);

Der Algorithmus ist recht komplex, und wir werden nicht näher darauf eingehen, als in den Kommentaren angegeben. Der Algorithmus implementiert die im Abschnitt |Das Problem| beschriebene Methode zur Steuerberechnung.

8.2.5. Die Funktion [calcul_tax_2]

Die Funktion [calcul_impôt] ruft die folgende Funktion [calcul_impôt_2] auf:

def calcul_impôt_2(marié: str, enfants: int, salaire: int) -> list:
    #  married: yes, no
    #  children: number of children
    #  salary: annual salary
    #  limits, coeffr, coeffn: data tables for tax calculation
    #
    #  number of shares
    marié = marié.strip().lower()
    if marié == "oui":
        nb_parts = enfants / 2 + 2
    else:
        nb_parts = enfants / 2 + 1

    #  1 part per child from the 3rd
    if enfants >= 3:
        #  an additional half share for each child from the 3rd onwards
        nb_parts += 0.5 * (enfants - 2)

    #  taxable income
    revenu_imposable = get_revenu_imposable(salaire)
    #  surcharge
    surcôte = math.floor(revenu_imposable - 0.9 * salaire)
    #  for rounding problems
    if surcôte < 0:
        surcôte = 0

    #  family quotient
    quotient = revenu_imposable / nb_parts
    #  is set at the end of the limit table to stop the following loop
    limites[len(limites) - 1] = quotient
    #  tAX CALCULATION
    i = 0
    while quotient > limites[i]:
        i += 1
        #  because we've placed quotient at the end of the limit array, the previous loop
    #  cannot go beyond the limit table

    #  now we can calculate the tax
    impôt = math.floor(revenu_imposable * coeffr[i] - nb_parts * coeffn[i])
    #  result
    return {"impôt": impôt, "surcôte": surcôte, "taux": coeffr[i]}

Dieser Algorithmus wurde in Abschnitt 8.1.1 beschrieben.

8.2.6. Die Funktion [get_discount]

Die Funktion [get_discount] implementiert die Berechnung eines etwaigen Steuerrabatts (Abschnitt |Berechnung des Rabatts|):

#  calculates any discount
def get_décôte(marié: str, salaire: int, impots: int) -> int:
    #  at the outset, a zero discount
    décôte = 0
    #  maximum tax amount to qualify for discount
    plafond_impôt_pour_décôte = PLAFOND_IMPOT_COUPLE_POUR_DECOTE if marié == "oui" else PLAFOND_IMPOT_CELIBATAIRE_POUR_DECOTE
    if impots < plafond_impôt_pour_décôte:
        #  maximum discount
        plafond_décôte = PLAFOND_DECOTE_COUPLE if marié == "oui" else PLAFOND_DECOTE_CELIBATAIRE
        #  theoretical discount
        décôte = plafond_décôte - 0.75 * impots
        #  the discount cannot exceed the amount of tax due
        if décôte > impots:
            décôte = impots

        #  no discount <0
        if décôte < 0:
            décôte = 0

    #  result
    return math.ceil(décôte)

8.2.7. Die Funktion [get_reduction]

Die Funktion [get_reduction] implementiert die Berechnung einer etwaigen Steuerermäßigung (Abschnitt |Berechnung der Steuerermäßigung|):

#  calculates any reduction
def get_réduction(marié: str, salaire: int, enfants: int, impots: int) -> int:
    #  the income ceiling to qualify for the 20% reduction
    plafond_revenu_pour_réduction = PLAFOND_REVENUS_COUPLE_POUR_REDUCTION if marié == "oui" else PLAFOND_REVENUS_CELIBATAIRE_POUR_REDUCTION
    plafond_revenu_pour_réduction += enfants * VALEUR_REDUC_DEMI_PART
    if enfants > 2:
        plafond_revenu_pour_réduction += (enfants - 2) * VALEUR_REDUC_DEMI_PART

    #  taxable income
    revenu_imposable = get_revenu_imposable(salaire)
    #  reduction
    réduction = 0
    if revenu_imposable < plafond_revenu_pour_réduction:
        #  20% discount
        réduction = 0.2 * impots

    #  result
    return math.ceil(réduction)

8.2.8. Die Funktion [get_taxable_income]

Die Funktion [get_taxable_income] berechnet das zu versteuernde Einkommen auf der Grundlage des Jahresgehalts:

#  revenu_imposable = salaireAnnuel - allowance
#  the allowance has a minimum and a maximum
# ----------------------------------------
def get_revenu_imposable(salaire: int) -> int:
    #  10% salary deduction
    abattement = 0.1 * salaire
    #  this allowance may not exceed ABATTEMENT_DIXPOURCENT_MAX
    if abattement > ABATTEMENT_DIXPOURCENT_MAX:
        abattement = ABATTEMENT_DIXPOURCENT_MAX

    #  the allowance cannot be less than ABATTEMENT_DIXPOURCENT_MIN
    if abattement < ABATTEMENT_DIXPOURCENT_MIN:
        abattement = ABATTEMENT_DIXPOURCENT_MIN

    #  taxable income
    revenu_imposable = salaire - abattement
    #  result
    return math.floor(revenu_imposable)

8.2.9. Die Funktion [record_results]

Die Funktion [record_results] speichert die Ergebnisse der Steuerberechnung in einer Textdatei:

#  writing results to a text file
# ----------------------------------------
def record_results(results_filename: str, results: list):
    #  results_filename: the name of the text file in which to place the results
    #  results: the results list in the form of a dictionary list
    #  each dictionary is written on a line of text
    résultats = None
    try:
        #  opening the results file
        résultats = codecs.open(results_filename, "w", "utf8")
        #  taxpayer exploitation
        for result in results:
            #  enter the result in the results file
            résultats.write(f"{result}\n")
            #  next taxpayer
    finally:
        #  close the file if it has been opened
        if résultats:
            résultats.close()

8.2.10. Die Ergebnisse

Wie bereits erwähnt, mit der folgenden Steuerzahlerdatei [taxpayersdata.txt]:

oui,2,55555
oui,2,50000
oui,3,50000
non,2,100000
non,3,100000
oui,3,100000
oui,5,100000
non,0,100000
oui,2,30000
non,0,200000
oui,3,200000

Das Skript [main.py] erstellt die folgende Datei [results.txt]:

{'marié': 'oui', 'enfants': 2, 'salaire': 55555, 'impôt': 2814, 'surcôte': 0, 'décôte': 0, 'réduction': 0, 'taux': 0.14}
{'marié': 'oui', 'enfants': 2, 'salaire': 50000, 'impôt': 1384, 'surcôte': 0, 'décôte': 384, 'réduction': 347, 'taux': 0.14}
{'marié': 'oui', 'enfants': 3, 'salaire': 50000, 'impôt': 0, 'surcôte': 0, 'décôte': 720, 'réduction': 0, 'taux': 0.14}
{'marié': 'non', 'enfants': 2, 'salaire': 100000, 'impôt': 19884, 'surcôte': 4480, 'décôte': 0, 'réduction': 0, 'taux': 0.41}
{'marié': 'non', 'enfants': 3, 'salaire': 100000, 'impôt': 16782, 'surcôte': 7176, 'décôte': 0, 'réduction': 0, 'taux': 0.41}
{'marié': 'oui', 'enfants': 3, 'salaire': 100000, 'impôt': 9200, 'surcôte': 2180, 'décôte': 0, 'réduction': 0, 'taux': 0.3}
{'marié': 'oui', 'enfants': 5, 'salaire': 100000, 'impôt': 4230, 'surcôte': 0, 'décôte': 0, 'réduction': 0, 'taux': 0.14}
{'marié': 'non', 'enfants': 0, 'salaire': 100000, 'impôt': 22986, 'surcôte': 0, 'décôte': 0, 'réduction': 0, 'taux': 0.41}
{'marié': 'oui', 'enfants': 2, 'salaire': 30000, 'impôt': 0, 'surcôte': 0, 'décôte': 0, 'réduction': 0, 'taux': 0}
{'marié': 'non', 'enfants': 0, 'salaire': 200000, 'impôt': 64210, 'surcôte': 7498, 'décôte': 0, 'réduction': 0, 'taux': 0.45}
{'marié': 'oui', 'enfants': 3, 'salaire': 200000, 'impôt': 42842, 'surcôte': 17283, 'décôte': 0, 'réduction': 0, 'taux': 0.41}

Diese Ergebnisse stimmen mit den offiziellen Zahlen im Abschnitt |Offizielle Zahlen| überein.

Führen wir diese Version nun in einem Konsolenfenster aus:


(venv) C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\impots\v01>python main.py
Traceback (most recent call last):
  File "main.py", line 4, in <module>
    from impots.v01.shared.impôts_module_01 import *
ModuleNotFoundError: No module named 'impots'

Wir stoßen auf einen Fehler, den wir schon einmal gesehen haben: einen, bei dem ein Modul nicht gefunden werden kann, in diesem Fall das [impots]-Modul. Denken Sie daran, dass dies bedeutet:

  • Der Python-Interpreter hat die Verzeichnisse im Python-Pfad nacheinander durchsucht;
  • in keinem davon hat er ein Verzeichnis gefunden, das ein Skript [impots.py] enthält;

Version [v02] wird eine Lösung für dieses Problem bieten.