4. تمرين تطبيقي – حساب الضريبة
4.1. المشكلة
نهدف إلى كتابة برنامج لحساب ضريبة دافع الضرائب. سنأخذ في الاعتبار الحالة المبسطة لدافع الضرائب الذي لا يملك سوى راتبه ليبلغ عنه:
- يُحسب عدد الحصص الخاصة بالموظف على النحو التالي: nbParts = nbEnfants / 2 + 1 إذا كان غير متزوج، أو nbEnfants / 2 + 2 إذا كان متزوجًا، حيث nbEnfants هو عدد أطفاله.
- نحسب دخلهم الخاضع للضريبة R = 0.72 * S، حيث S هو راتبهم السنوي
- نحسب معامل الأسرة Q = R / N
نحسب ضريبتهم I بناءً على البيانات التالية
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 | 4900 |
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 |
يحتوي كل صف على 3 حقول. لحساب الضريبة I، نبحث عن الصف الأول الذي يكون فيه QF <= الحقل 1. على سبيل المثال، إذا كان QF = 30000، فسنجد الصف
الضريبة I تساوي إذن 0.15*R - 2072.5*nbParts. إذا كان QF بحيث لا تتحقق الشرط QF<=field1 أبدًا، يتم استخدام المعاملات من الصف الأخير. هنا:
مما يعطي الضريبة I = 0.65*R – 49062*nbParts.
4.2. الإصدار باستخدام المصفوفات (impots_01)
نقدم برنامجًا أوليًا حيث:
- توجد البيانات اللازمة لحساب الضريبة في ثلاثة مصفوفات (limits، coeffR، coeffN)
- توجد بيانات دافع الضرائب (متزوج، أطفال، راتب) في ملف نصي أول
- يتم تخزين نتائج حساب الضريبة (متزوج، أطفال، راتب، ضريبة) في ملف نصي ثانٍ
<?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]);
}
?>
ملف البيانات data.txt (متزوج، أطفال، راتب):
ملفات results.txt (متزوج، أطفال، راتب، ضريبة) للنتائج التي تم الحصول عليها:
oui:2:200000:22504
non:2:200000:33388
oui:3:200000:16400
non:3:200000:22504
oui:5:50000:0
non:0:3000000:1354938
تعليقات
- السطر 4: اسم الملف النصي الذي يحتوي على بيانات دافع الضرائب (متزوج، أطفال، راتب)
- السطر 5: اسم الملف النصي الذي يحتوي على نتائج (متزوج، أطفال، راتب، ضريبة) حساب الضريبة
- الأسطر 6-8: جداول البيانات الثلاثة المستخدمة لحساب الضريبة
- الأسطر 11-15: فتح ملف بيانات دافع الضرائب للقراءة
- الأسطر 18-22: فتح ملف النتائج للكتابة
- السطر 25: حلقة لقراءة الأسطر (متزوج، أطفال، راتب) من ملف دافع الضرائب
- السطر 27: إزالة حرف نهاية السطر
- السطر 29: يتم استرداد مكونات السطر (متزوج، أطفال، راتب)
- السطر 31: يتم حساب الضريبة
- السطر 33: يتم تخزين الضريبة في ملف النتائج
- السطران 37-38: بمجرد الانتهاء من معالجة ملف دافع الضرائب بالكامل، يتم إغلاق الملفات
- السطر 44: الدالة التي تزيل حرف نهاية السطر من السطر $line. حرف نهاية السطر هو السلسلة "\r\n" في أنظمة Windows، و"\n" في أنظمة Unix. والنتيجة هي سلسلة الإدخال بدون حرف نهاية السطر.
- السطران 47-48: ترجع الدالة substr($string, $start, $size) السلسلة الفرعية من $string التي تبدأ من الحرف $start وتحتوي على $size حرفًا كحد أقصى.
- السطر 63: strtolower($string) تحول $string إلى أحرف صغيرة
- السطر 76: تضيف الدالة array_push($array, $element) العنصر $element إلى نهاية المصفوفة $array. لاحظ أن المصفوفة $limits تُمرر بالقيمة إلى الدالة calculateTax (السطر 56). وبالتالي، تتم عملية إضافة العنصر هذه على نسخة من المعلمة الفعلية، التي تظل دون تغيير.
- السطر 84: تُرجع الدالة floor($x) القيمة الصحيحة الأقرب إلى $x.
4.3. الإصدار الذي يستخدم ملفات نصية (impots_02)
يختلف هذا الإصدار الجديد عن الإصدار السابق فقط في أن البيانات ($limites، $coeffR، $coeffN) اللازمة لحساب الضريبة موجودة الآن في ملف نصي بالصيغة التالية:
ملف 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
تقوم النسخة الجديدة ببساطة بقراءة البيانات من ملف [impots.txt] ووضعها في ثلاثة مصفوفات ($limites، $coeffR، $coeffN). وهذا يعيدنا إلى الحالة السابقة. نقدم التغييرات فقط:
<?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);
}
?>
تعليقات
- السطر 11: تعالج الدالة getTables($IMPOTS) الملف النصي $IMPOTS لاستخراج الجداول الثلاثة ($limites، $coeffR، $coeffN). والنتيجة المرجعة هي ($error، $limites، $coeffR، $coeffN)، حيث $error عبارة عن رسالة خطأ؛ وتكون فارغة في حالة عدم حدوث أي خطأ.
- السطر 40: الدالة getTables($IMPOTS).
- السطر 43: تُرجع الدالة files_exists(filename) القيمة المنطقية true إذا كان الملف filename موجودًا، و false في حالة عدم وجوده.
- السطر 46: تقرأ الدالة file(filename) ملف النص filename بالكامل. وتُرجع مصفوفة يكون كل عنصر فيها سطرًا من ملف النص. ونظرًا لأن ملف impots.txt يحتوي على ثلاثة أسطر من النص، فستُرجع الدالة مصفوفة ذات ثلاثة عناصر.
- الأسطر 50–52: استخدم الأسطر الثلاثة التي تم استردادها لإنشاء المصفوفات الثلاثة ($limits، $coeffR، $coeffN)
النتائج التي تم الحصول عليها هي نفس تلك التي تم الحصول عليها في الإصدار السابق.