Skip to content

4. Esercizio pratico – Calcolo delle imposte

4.1. Il problema

Il nostro obiettivo è scrivere un programma per calcolare l'imposta di un contribuente. Prenderemo in considerazione il caso semplificato di un contribuente che deve dichiarare solo il proprio stipendio:

  • Il numero di quote per il dipendente è calcolato come nbParts = nbEnfants / 2 + 1 se è celibe, oppure nbEnfants / 2 + 2 se è coniugato, dove nbEnfants è il numero di figli che ha.
  • Calcoliamo il loro reddito imponibile R = 0,72 * S, dove S è il loro stipendio annuale
  • Calcoliamo il loro coefficiente familiare Q = R / N

Calcoliamo la loro imposta I sulla base dei seguenti dati

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

Ogni riga ha 3 campi. Per calcolare l'imposta I, cerchiamo la prima riga in cui QF <= campo1. Ad esempio, se QF = 30000, troveremo la riga

    24740        0.15        2072.5

L'imposta I è quindi pari a 0,15*R - 2072,5*nbParts. Se QF è tale che la condizione QF<=field1 non è mai soddisfatta, vengono utilizzati i coefficienti dell'ultima riga. Qui:

    0                0.65        49062

il che dà come risultato l'imposta I = 0,65*R – 49062*nbParts.

4.2. Versione con array (impots_01)

Presentiamo un programma iniziale in cui:

  • i dati necessari per il calcolo delle imposte sono contenuti in tre array (limits, coeffR, coeffN)
  • i dati del contribuente (stato civile, figli, stipendio) si trovano in un primo file di testo
  • i risultati del calcolo dell'imposta (stato civile, figli, stipendio, imposta) sono memorizzati in un secondo file di testo

<?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]);
}
?>

Il file di dati data.txt (stato civile, figli, stipendio):

oui,2,200000
non,2,200000
oui,3,200000
non,3,200000
oui,5,50000
non,0,3000000

I file results.txt (stato civile, figli, stipendio, imposte) relativi ai risultati ottenuti:

oui:2:200000:22504
non:2:200000:33388
oui:3:200000:16400
non:3:200000:22504
oui:5:50000:0
non:0:3000000:1354938

Commenti

  • riga 4: il nome del file di testo contenente i dati del contribuente (stato civile, figli, stipendio)
  • riga 5: il nome del file di testo contenente i risultati (stato civile, figli, stipendio, imposta) del calcolo fiscale
  • Righe 6–8: le tre tabelle di dati utilizzate per calcolare l'imposta
  • righe 11-15: aprono il file dei dati del contribuente per la lettura
  • righe 18–22: aprono il file dei risultati per la scrittura
  • riga 25: ciclo per leggere le righe (stato civile, figli, stipendio) dal file del contribuente
  • riga 27: il carattere di fine riga viene rimosso
  • riga 29: vengono recuperati i componenti (stato civile, figli, stipendio) della riga
  • riga 31: si calcola l'imposta
  • riga 33: l'imposta viene memorizzata nel file dei risultati
  • righe 37-38: una volta che il file dei contribuenti è stato completamente elaborato, i file vengono chiusi
  • riga 44: la funzione che rimuove il carattere di fine riga da una riga $line. Il carattere di fine riga è la stringa "\r\n" sui sistemi Windows, "\n" sui sistemi Unix. Il risultato è la stringa di input senza il carattere di fine riga.
  • righe 47-48: substr($string, $start, $size) restituisce la sottostringa di $string che inizia dal carattere $start e contiene al massimo $size caratteri.
  • riga 63: strtolower($string) converte $string in minuscolo
  • riga 76: array_push($array, $element) aggiunge $element alla fine di $array. Si noti che l'array $limits viene passato per valore alla funzione calculateTax (riga 56). L'aggiunta di un elemento viene quindi eseguita su una copia del parametro effettivo, che rimane invariato.
  • riga 84: la funzione floor($x) restituisce il valore intero immediatamente inferiore a $x.

4.3. Versione con file di testo (impots_02)

Questa nuova versione differisce dalla precedente solo per il fatto che i dati ($limites, $coeffR, $coeffN) necessari per calcolare l'imposta si trovano ora in un file di testo nel seguente formato:

File 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

La nuova versione legge semplicemente i dati dal file [impots.txt] e li inserisce in tre array ($limites, $coeffR, $coeffN). Questo ci riporta al caso precedente. Presentiamo solo le modifiche:


<?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);
}
?>

Commenti

  • Riga 11: La funzione getTables($IMPOTS) elabora il file di testo $IMPOTS per estrarre le tre tabelle ($limites, $coeffR, $coeffN). Il risultato restituito è ($error, $limites, $coeffR, $coeffN), dove $error è un messaggio di errore; è vuoto se non si è verificato alcun errore.
  • Riga 40: La funzione getTables($IMPOTS).
  • Riga 43: la funzione files_exists(filename) restituisce il valore booleano true se il file filename esiste, e false in caso contrario.
  • Riga 46: la funzione file(filename) legge l'intero file di testo filename. Restituisce un array in cui ogni elemento è una riga del file di testo. Poiché il file impots.txt contiene tre righe di testo, la funzione restituirà un array con tre elementi.
  • Righe 50–52: utilizzare le tre righe recuperate per creare i tre array ($limits, $coeffR, $coeffN)

I risultati ottenuti sono gli stessi di quelli ottenuti nella versione precedente.