Skip to content

4. Uygulama alıştırması - IMPOTS

4.1. Sorun

Bir vergi mükellefinin vergisini hesaplayabilen bir program yazmak istiyoruz. Beyan edeceği tek geliri maaşı olan bir vergi mükellefi gibi basitleştirilmiş bir durum ele alalım:

  • Çalışanın pay sayısı şu şekilde hesaplanır: nbParts = nbEnfants/2 + 1 (eğer bekarsa), evliyse nbEnfants/2+2 olarak hesaplanır; burada nbEnfants, çalışanın çocuk sayısıdır.
  • Vergiye tabi geliri R=0,72*S olarak hesaplanır; burada S, yıllık maaşıdır
  • aile katsayısı Q = R/N olarak hesaplanır

Aşağıdaki verilere göre vergi tutarı I hesaplanır

12620,0
0
0
13.190
0,05
631
15640
0,1
1290,5
24.740
0,15
2072,5
31810
0,2
3309,5
39.970
0,25
4900
48360
0,3
6898,5
55790
0,35
9316,5
92970
0,4
12106
127.860
0,45
16754,5
151250
0,50
23147,5
172.040
0,55
30710
195.000
0,60
39312
0
0,65
49062

Her satırda 3 alan vardır. I vergisini hesaplamak için, QF<=alan1 olan ilk satır aranır. Örneğin, QF=30000 ise şu satır bulunur:

    24740        0.15        2072.5

bulunur. I vergisi bu durumda 0,15*R - 2072,5*nbParts'e eşittir. Eğer QF, QF<=alan1 ilişkisini hiçbir zaman karşılamıyorsa, o zaman son satırdaki katsayılar kullanılır. Burada:

    0                0.65        49062

bu da I=0,65*R – 49062*nbParts vergi tutarını verir.

4.2. Tablolu versiyon (impots_01)

Aşağıda, vergi hesaplaması için gerekli verilerin üç tabloda (sınırlar, coeffR, coeffN) yer aldığı ilk programı sunuyoruz

  • vergi hesaplaması için gerekli veriler üç tabloda yer almaktadır (sınırlar, coeffR, coeffN)
  • vergi mükelleflerine ait veriler (evli, çocuk sayısı, maaş) ilk metin dosyasında yer almaktadır
  • vergi hesaplamasının sonuçları (evli, çocuk sayısı, maaş, vergi) ikinci bir metin dosyasında saklanmaktadır

<?php

// sabitlerin tanımlanması
$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);

// verilerin okunması
$data = fopen($DATA, "r");
if (!$data) {
  print "Impossible d'ouvrir en lecture le fichier des données [$DATA]\n";
  exit;
}

// sonuç dosyasının açılması
$résultats = fopen($RESULTATS, "w");
if (!$résultats) {
  print "Impossible de créer le fichier des résultats [$RESULTATS]\n";
  exit;
}

// veri dosyasının geçerli satırını işliyoruz
while ($ligne = fgets($data, 100)) {
  // varsa satır sonu işaretini kaldırma
  $ligne = cutNewLineChar($ligne);
  // $ligne'i oluşturan "evli", "çocuklar" ve "maaş" olmak üzere 3 alanı alınır
  list($marié, $enfants, $salaire) = explode(",", $ligne);
  // vergi hesaplanır
  $impôt = calculImpots($marié, $enfants, $salaire, $limites, $coeffR, $coeffN);
  // sonuç, sonuç dosyasına kaydedilir
  fputs($résultats, "$marié:$enfants:$salaire:$impôt\n");
  // bir sonraki vergi mükellefi
}
// dosyalar kapatılır
fclose($data);
fclose($résultats);

// son
exit;

// --------------------------------------------------------------------------
function cutNewLinechar($ligne) {
  // varsa, $ligne dosyasındaki satır sonu işaretini silin
  $L = strlen($ligne);  // satır uzunluğu
  while (substr($ligne, $L - 1, 1) == "\n" or substr($ligne, $L - 1, 1) == "\r") {
    $ligne = substr($ligne, 0, $L - 1);
    $L--;
  }
  // son
  return($ligne);
}

// --------------------------------------------------------------------------
function calculImpots($marié, $enfants, $salaire, $limites, $coeffR, $coeffN) {
  // $marié: evet, hayır
  // $enfants: çocuk sayısı
  // $salaire : yıllık maaş
  // $limites, $coeffR, $coeffN: vergi hesaplamasına olanak tanıyan veri tabloları
  
  // pay sayısı
  $marié = strtolower($marié);
  if ($marié == "oui")
    $nbParts = $enfants / 2 + 2;
  else
    $nbParts=$enfants / 2 + 1;
  // en az 3 çocuk varsa 1/2 hisse daha
  if ($enfants >= 3)
    $nbParts+=0.5;
  // vergilendirilebilir gelir
  $revenuImposable = 0.72 * $salaire;
  // aile katsayısı
  $quotient = $revenuImposable / $nbParts;
  // takip eden döngüyü durdurmak için sınır tablosunun sonuna eklenir
  array_push($limites, $quotient);
  // vergi hesaplaması
  $i = 0;
  while ($quotient > $limites[$i])
    $i++;
  // $quotient'in $limites tablosunun sonuna yerleştirilmesi nedeniyle, önceki döngü
  // $limites tablosunun sınırlarını aşamaz
  // şimdi vergiyi hesaplayabiliriz
  return floor($revenuImposable * $coeffR[$i] - $nbParts * $coeffN[$i]);
}
?>

data.txt veri dosyası (evli, çocuk sayısı, maaş):

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

Elde edilen sonuçlara ait résultats.txt dosyaları (evli, çocuk sayısı, maaş, vergi):

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

Açıklamalar

    1. satır: vergi mükelleflerinin verilerini (evli, çocuk sayısı, maaş) içeren metin dosyasının adı
    1. satır: vergi hesaplamasının sonuçlarını (evli, çocuk sayısı, maaş, vergi) içeren metin dosyasının adı
  • 6-8. satırlar: vergi hesaplamasına olanak tanıyan üç veri tablosu
  • satır 11-15: vergi mükellefi veri dosyasının okuma modunda açılması
  • satır 18-22: sonuç dosyasının yazma modunda açılması
  • satır 25: vergi mükellefleri dosyasındaki satırların (evli, çocuk sayısı, maaş) okunması döngüsü
  • satır 27: satır sonu işareti kaldırılır
  • satır 29: satırın bileşenleri (evli, çocuk sayısı, maaş) alınır
  • satır 31: vergi hesaplanır
  • satır 33: vergi, sonuç dosyasına kaydedilir
  • satır 37-38: vergi mükellefleri dosyası tamamen işlendikten sonra dosyalar kapatılır
  • satır 44: $ligne satırındaki satır sonu işaretini silen işlev. Satır sonu işareti, Windows sistemlerinde "\r\n", Unix sistemlerinde "\n" dizesidir. Sonuç, satır sonu işareti çıkarılmış giriş dizesidir.
  • 47-48. satırlar: substr($chaîne,$début,$taille) işlevi, $début karakterinden başlayan ve en fazla $taille karakter içeren $chaîne alt dizesidir.
    1. satır: strtolower($chaîne) işlevi, $chaîne'i küçük harflerle yazdırır
    1. satır: array_push($tableau,$élément) işlevi, $élément değerini $tableau dizisinin sonuna ekler. $limites tablosunun, calculerImpot işlevine (56. satır) değer olarak aktarıldığına dikkat edilmelidir. Dolayısıyla bu eleman ekleme işlemi, asıl parametrenin kopyası üzerinde gerçekleştirilir; asıl parametre ise değişmeden kalır.
    1. satır: floor($x) işlevi, $x değerinden hemen küçük olan tamsayı değerini verir.

4.3. Metin dosyaları içeren sürüm (impots_02)

Bu yeni sürüm, önceki sürümden yalnızca vergi hesaplaması için gerekli olan verilerin ($limites, $coeffR, $coeffN) artık aşağıdaki biçimde bir metin dosyasında yer almasıyla farklılık gösterir:

impots.txt dosyası:

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

Yeni sürüm, [impots.txt] dosyasındaki verileri okuyarak bunları üç tabloya ($limites, $coeffR, $coeffN) aktarmaktadır. Böylece önceki duruma geri dönülmüş oluyor. Yalnızca değişiklikleri sunuyoruz:


<?php

// sabitlerin tanımlanması
$DATA = "data.txt";
$RESULTATS = "resultats.txt";
$IMPOTS = "impots.txt";

// vergi hesaplaması için gerekli veriler $IMPOTS dosyasına yerleştirildi
// her tablo için bir satır olacak şekilde şu biçimde
// val1:val2:val3,...
list($erreur, $limites, $coeffR, $coeffN) = getTables($IMPOTS);

// Bir hata mı oluştu?
if ($erreur) {
  print "$erreur\n";
  exit;
}//if
// kullanıcı verilerinin okunması
...

// son
exit;

// --------------------------------------------------------------------------
function cutNewLinechar($ligne) {
  // varsa, $ligne'ten satır sonu işaretini sil
...
}

// --------------------------------------------------------------------------
function calculImpots($marié, $enfants, $salaire, $limites, $coeffR, $coeffN) {
  // $marié: evet, hayır
  // $enfants: çocuk sayısı
  // $salaire: yıllık maaş
  // $limites, $coeffR, $coeffN: vergi hesaplamasına olanak tanıyan veri tabloları
  ...
}

// --------------------------------------------------------------------------
function getTables($IMPOTS) {
  // $IMPOTS : $limites, $coeffR, $coeffN tablolarındaki verileri içeren dosyanın adı
  // $IMPOTS dosyası mevcut mu?
  if (!file_exists($IMPOTS))
    return array("Le fichier $IMPOTS n'existe pas","","","");
  // dosyanın toplu olarak okunması
  $tables = file($IMPOTS);
  if (!$tables)
    return array("Erreur lors de l'exploitation du fichier $IMPOTS","","","");
  // 3 tablonun oluşturulması - satırların sözdizimsel olarak doğru olduğu varsayılır
  $limites = explode(":", cutNewLineChar($tables[0]));
  $coeffR = explode(":", cutNewLineChar($tables[1]));
  $coeffN = explode(":", cutNewLineChar($tables[2]));
  // son
  return array("", $limites, $coeffR, $coeffN);
}
?>

Açıklamalar

    1. satır: getTables($IMPOTS) işlevi, $IMPOTS metin dosyasını kullanarak bu dosyadan üç tabloyu çıkarır ($limites, $coeffR, $coeffN). Elde edilen sonuç şöyledir: ($erreur, $limites, $coeffR, $coeffN) şeklindedir; burada $erreur bir hata mesajıdır ve hata yoksa boştur.
  • satır 40: getTables($IMPOTS) işlevi.
    1. satır: files_exists(nom_fichier) işlevi, nom_fichier dosyası varsa true boole değerini, yoksa false boole değerini döndürür.
    1. satır: file(nom_fichier) işlevi, nom_fichier metin dosyasının tamamını okur. Bu işlev, her bir elemanı metin dosyasının bir satırı olan bir dizi döndürür. Burada impots.txt dosyası üç satır metin içerdiğinden, işlev üç elemanlı bir dizi döndürür.
  • 50-52. satırlar: Alınan üç satır kullanılarak üç dizi ($limites, $coeffR, $coeffN) oluşturulur

Elde edilen sonuçlar, önceki sürümde elde edilenlerle aynıdır.