4. Anwendungsübung – Steuerberechnung
4.1. Die Aufgabe
Wir wollen ein Programm schreiben, das die Steuer eines Steuerzahlers berechnet. Wir betrachten den vereinfachten Fall eines Steuerzahlers, der nur sein Gehalt angeben muss:
- Die Anzahl der Anteile für den Arbeitnehmer wird berechnet als nbParts = nbEnfants / 2 + 1, wenn er unverheiratet ist, oder nbEnfants / 2 + 2, wenn er verheiratet ist, wobei nbEnfants die Anzahl seiner Kinder ist.
- Wir berechnen ihr zu versteuerndes Einkommen R = 0,72 * S, wobei S ihr Jahresgehalt ist
- Wir berechnen ihren Familienkoeffizienten Q = R / N
Wir berechnen ihre Steuer I auf der Grundlage der folgenden Daten
12620,0 | 0 | 0 |
13.190 | 0,05 | 631 |
15.640 | 0,1 | 1.290,5 |
24.740 | 0,15 | 2.072,5 |
31.810 | 0,2 | 3.309,5 |
39.970 | 0,25 | 4.900 |
48.360 | 0,3 | 6.898,5 |
55.790 | 0,35 | 9.316,5 |
92.970 | 0,4 | 12.106 |
127.860 | 0,45 | 16.754,5 |
151.250 | 0,50 | 23.147,5 |
172.040 | 0,55 | 30.710 |
195.000 | 0,60 | 39.312 |
0 | 0,65 | 49.062 |
Jede Zeile enthält 3 Felder. Um die Steuer I zu berechnen, suchen wir nach der ersten Zeile, in der QF <= Feld1 ist. Wenn beispielsweise QF = 30000 ist, finden wir die Zeile
Steuer I ist dann gleich 0,15*R – 2072,5*nbParts. Wenn QF so ist, dass die Bedingung QF<=field1 nie erfüllt ist, werden die Koeffizienten aus der letzten Zeile verwendet. Hier:
was die Steuer I = 0,65*R – 49062*nbParts ergibt.
4.2. Version mit Arrays (impots_01)
Wir stellen ein erstes Programm vor, in dem:
- die zur Steuerberechnung benötigten Daten in drei Arrays (limits, coeffR, coeffN) gespeichert sind
- die Steuerzahlerdaten (verheiratet, Kinder, Gehalt) in einer ersten Textdatei gespeichert sind
- die Ergebnisse der Steuerberechnung (verheiratet, Kinder, Gehalt, Steuer) in einer zweiten Textdatei gespeichert sind
<?php
// definition of constants
$DATA = "data.txt";
$RESULTATS = "resultats.txt";
$limites = array(12620, 13190, 15640, 24740, 31810, 39970, 48360, 55790, 92970, 127860, 151250, 172040, 195000);
$coeffR = array(0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65);
$coeffN = array(0, 631, 1290.5, 2072.5, 3309.5, 4900, 6898.5, 9316.5, 12106, 16754.5, 23147.5, 30710, 39312, 49062);
// reading data
$data = fopen($DATA, "r");
if (!$data) {
print "Impossible d'ouvrir en lecture le fichier des données [$DATA]\n";
exit;
}
// open results file
$résultats = fopen($RESULTATS, "w");
if (!$résultats) {
print "Impossible de créer le fichier des résultats [$RESULTATS]\n";
exit;
}
// use the current line of the data file
while ($ligne = fgets($data, 100)) {
// remove any end-of-line marker
$ligne = cutNewLineChar($ligne);
// we retrieve the 3 fields married,children,salary which form $ligne
list($marié, $enfants, $salaire) = explode(",", $ligne);
// tax calculation
$impôt = calculImpots($marié, $enfants, $salaire, $limites, $coeffR, $coeffN);
// enter the result in the results file
fputs($résultats, "$marié:$enfants:$salaire:$impôt\n");
// next taxpayer
}
// close files
fclose($data);
fclose($résultats);
// end
exit;
// --------------------------------------------------------------------------
function cutNewLinechar($ligne) {
// delete the end-of-line mark from $ligne if it exists
$L = strlen($ligne); // // line length
while (substr($ligne, $L - 1, 1) == "\n" or substr($ligne, $L - 1, 1) == "\r") {
$ligne = substr($ligne, 0, $L - 1);
$L--;
}
// end
return($ligne);
}
// --------------------------------------------------------------------------
function calculImpots($marié, $enfants, $salaire, $limites, $coeffR, $coeffN) {
// $marié : yes, no
// $enfants : number of children
// $salaire: annual salary
// $limites, $coeffR, $coeffN: tax calculation data tables
// number of shares
$marié = strtolower($marié);
if ($marié == "oui")
$nbParts = $enfants / 2 + 2;
else
$nbParts=$enfants / 2 + 1;
// an additional 1/2 share if at least 3 children
if ($enfants >= 3)
$nbParts+=0.5;
// taxable income
$revenuImposable = 0.72 * $salaire;
// family quotient
$quotient = $revenuImposable / $nbParts;
// is set at the end of the limit table to stop the following loop
array_push($limites, $quotient);
// tAX CALCULATION
$i = 0;
while ($quotient > $limites[$i])
$i++;
// because $quotient has been placed at the end of the $limites array, the previous loop
// cannot exceed the table $limites
// now we can calculate the tax
return floor($revenuImposable * $coeffR[$i] - $nbParts * $coeffN[$i]);
}
?>
Die Datendatei data.txt (verheiratet, Kinder, Gehalt):
Die results.txt-Dateien (verheiratet, Kinder, Gehalt, Steuern) für die erzielten Ergebnisse:
oui:2:200000:22504
non:2:200000:33388
oui:3:200000:16400
non:3:200000:22504
oui:5:50000:0
non:0:3000000:1354938
Kommentare
- Zeile 4: Name der Textdatei, die die Steuerzahlerdaten enthält (verheiratet, Kinder, Gehalt)
- Zeile 5: Name der Textdatei, die die Ergebnisse (Familienstand, Kinder, Gehalt, Steuer) der Steuerberechnung enthält
- Zeilen 6–8: die drei Datentabellen, die zur Berechnung der Steuer verwendet werden
- Zeilen 11–15: Öffnen der Steuerzahler-Datendatei zum Lesen
- Zeilen 18–22: Öffnen der Ergebnisdatei zum Schreiben
- Zeile 25: Schleife zum Lesen der Zeilen (verheiratet, Kinder, Gehalt) aus der Steuerzahlerdatei
- Zeile 27: Das Zeilenendezeichen wird entfernt
- Zeile 29: Die Bestandteile (verheiratet, Kinder, Gehalt) der Zeile werden abgerufen
- Zeile 31: Die Steuer wird berechnet
- Zeile 33: Die Steuer wird in der Ergebnisdatei gespeichert
- Zeilen 37–38: Sobald die Steuerzahlerdatei vollständig verarbeitet wurde, werden die Dateien geschlossen
- Zeile 44: Die Funktion, die das Zeilenendezeichen aus einer Zeile $line entfernt. Das Zeilenendezeichen ist die Zeichenkette „\r\n“ auf Windows-Systemen, „\n“ auf Unix-Systemen. Das Ergebnis ist die Eingabezeichenkette ohne ihr Zeilenendezeichen.
- Zeilen 47–48: substr($string, $start, $size) gibt die Teilzeichenfolge von $string zurück, die am Zeichen $start beginnt und höchstens $size Zeichen enthält.
- Zeile 63: strtolower($string) wandelt $string in Kleinbuchstaben um
- Zeile 76: Mit
array\_push($array, $element)wird$elementan das Ende von$arrayangehängt. Beachten Sie, dass das Array$limitsals Wert an die FunktioncalculateTaxübergeben wird (Zeile 56). Das Hinzufügen eines Elements erfolgt daher an einer Kopie des tatsächlichen Parameters, der unverändert bleibt. - Zeile 84: Die Funktion floor($x) gibt den ganzzahligen Wert zurück, der unmittelbar kleiner als $x ist.
4.3. Version mit Textdateien (impots_02)
Diese neue Version unterscheidet sich von der vorherigen nur dadurch, dass die zur Berechnung der Steuer benötigten Daten ($limites, $coeffR, $coeffN) nun in einer Textdatei im folgenden Format vorliegen:
Datei impots.txt:
12620:13190:15640:24740:31810:39970:48360:55790:92970:127860:151250:172040:195000:0
0:0.05:0.1:0.15:0.2:0.25:0.3:0.35:0.4:0.45:0.5:0.55:0.6:0.65
0:631:1290.5:2072.5:3309.5:4900:6898.5:9316.5:12106:16754.5:23147.5:30710:39312:49062
Die neue Version liest einfach die Daten aus der Datei [impots.txt] ein und speichert sie in drei Arrays ($limites, $coeffR, $coeffN). Damit sind wir wieder beim vorherigen Fall angelangt. Wir stellen nur die Änderungen vor:
<?php
// definition of constants
$DATA = "data.txt";
$RESULTATS = "resultats.txt";
$IMPOTS = "impots.txt";
// the data required to calculate the tax has been placed in the $IMPOTS file
// one line per table in the form
// val1:val2:val3,...
list($erreur, $limites, $coeffR, $coeffN) = getTables($IMPOTS);
// was there a mistake?
if ($erreur) {
print "$erreur\n";
exit;
}//if
// reading user data
...
// end
exit;
// --------------------------------------------------------------------------
function cutNewLinechar($ligne) {
// delete the end-of-line mark from $ligne if it exists
...
}
// --------------------------------------------------------------------------
function calculImpots($marié, $enfants, $salaire, $limites, $coeffR, $coeffN) {
// $marié : yes, no
// $enfants : number of children
// $salaire: annual salary
// $limites, $coeffR, $coeffN: tax calculation data tables
...
}
// --------------------------------------------------------------------------
function getTables($IMPOTS) {
// $IMPOTS: name of the file containing data from tables $limites, $coeffR, $coeffN
// does the $IMPOTS file exist?
if (!file_exists($IMPOTS))
return array("Le fichier $IMPOTS n'existe pas","","","");
// file block playback
$tables = file($IMPOTS);
if (!$tables)
return array("Erreur lors de l'exploitation du fichier $IMPOTS","","","");
// create the 3 tables - assume the rows are syntactically correct
$limites = explode(":", cutNewLineChar($tables[0]));
$coeffR = explode(":", cutNewLineChar($tables[1]));
$coeffN = explode(":", cutNewLineChar($tables[2]));
// end
return array("", $limites, $coeffR, $coeffN);
}
?>
Kommentare
- Zeile 11: Die Funktion getTables($IMPOTS) verarbeitet die Textdatei $IMPOTS, um die drei Tabellen ($limites, $coeffR, $coeffN) zu extrahieren. Das zurückgegebene Ergebnis ist ($error, $limites, $coeffR, $coeffN), wobei $error eine Fehlermeldung ist; sie ist leer, wenn kein Fehler aufgetreten ist.
- Zeile 40: Die Funktion getTables($IMPOTS).
- Zeile 43: Die Funktion files_exists(filename) gibt den booleschen Wert true zurück, wenn die Datei filename existiert, andernfalls false.
- Zeile 46: Die Funktion file(filename) liest die gesamte Textdatei filename ein. Sie gibt ein Array zurück, in dem jedes Element eine Zeile aus der Textdatei ist. Da die Datei impots.txt drei Textzeilen enthält, gibt die Funktion ein Array mit drei Elementen zurück.
- Zeilen 50–52: Verwenden Sie die drei abgerufenen Zeilen, um die drei Arrays ($limits, $coeffR, $coeffN) zu erstellen.
Die erhaltenen Ergebnisse sind dieselben wie in der vorherigen Version.