1. 程式人生 > >編譯原理第一個專案——個人所得稅PersonalTax

編譯原理第一個專案——個人所得稅PersonalTax

1、實驗目的

本實驗面向 Java 語言的初學者,假設學生已掌握結構化程式設計方法,對面向物件程式設計方法有初步瞭解。學生最好至少已掌握一門 Java 之外的面向物件程式設計語言,例如 C++或 Smalltalk-80。學生通過本實驗可掌握 Java 程式的開發過程,以及面向物件技術中封裝、資訊隱藏、資料抽象、異常處理等機制在實際應用中的有機運用,並養成遵循良好程式設計編碼規範的風格。學生從本實驗還可體會到傳統的結構化程式設計方法與當前主流的面向物件程式設計方法在建模與設計上的主要區別,為後續的編譯原理實驗打下初步基礎。

2、實驗環境

本實驗基於當前主流的面向物件開發平臺,編碼規範遵循主流的參考規範。

  2.1、程式語言

         java語言,JDK1.5以上版本

  2.2、開發工具

        學生可自由選擇 Eclipse、JBuilder 等 IDE 環境,也可直接採用 UltraEdit、EditPlus 等編輯器在命令列工作。但提交的實驗結果必須獨立於特定的 IDE,可直接執行在 JDK 上。

  2.3、編碼規範

        你需要採用面向物件風格來設計實驗中的所有類,並遵循一種良好的程式設計習慣。例如,如果你將一個程式的很多功能全部放在一個長長的 main()方法中實現,這樣的設計與編碼風格會被扣分。學生在實驗過程中應注意培養規範的編碼風格。本實驗要求所有原始碼嚴格遵循 Sun 公司關於 Java 程式設計語言的編碼規範,參見:

http://java.sun.com/docs/codeconv/。完成後的程式碼應使用 JDK 附帶的文件工具 javadoc 根據源程式中的文件化註釋生成相應的文件。

3、實驗內容

  3.1、基本要求

         設計一個基於命令列介面的計算個人所得稅(工資、薪金所得)應用程式,根據使用者輸入的當月工資薪金總額計算應繳納的個人所得稅額。為適應未來個人所得稅法的可能變化(歷史上曾有不同城市執行不同標準的情況,也曾發生過立法修改個人所得稅起徵基數;當前對個人所得稅進行改革的呼聲也日益高漲),該程式應支援對個人所得稅起徵點進行調整的功能,並且個人所得稅各級稅率也允許修改。請使用簡單的命令列選單方式讓使用者選擇所需的功能。

    3.2、個人所得稅計算方法

          我國稅法規定,公民每月工資、薪金收入總額超過 800 元(即個人所得稅起徵點,2006 年修訂立法改為 1,600 元,2011 年調至 3,500 元)者應繳納個人所得稅。收入總額減去免徵基數後剩餘部分稱為應納稅所得額,應納稅所得額按下表規定的超額累進稅率計算應繳納的個人所得稅。實際上,個人所得稅稅率表共分 9 級(2011 年調整為 7 級),最高稅率為 45%;本實驗將稅率表簡化為以下 5 個級別:

                                       

    設計思路:

     這個專案的話我個人覺得對管理於一個java初學者的而言是不難的,其難度遠在網上的一些圖書系統之下,非常簡單的,適合java初學者用來練手。當然了,這也意味著我使用的語言是java了。下面我來說一下我的設計思路。

      實驗要求其實核心要求就兩條:1、起徵點可調;2、稅率可調。試問一個程式執行起來後,這些因素客戶是可以設定的嗎?當然不是,不然天下大亂了。只有管理員可以,而這個管理員在現實生活中誰來做和咱們的實驗沒關係,那是政府的事。我們作為程式的設計者給他留個位就可以了。所以,這個專案裡面會有管理員的角色,為了保險我們要求管理員有密碼,所以程式得有一個manager類。看程式碼:

package cn.mldn.util;

public class Manager {
	private int passWorld;
	public Manager(){
		this.passWorld = 15332008;
	}
	public int getPassWorld() {
		return passWorld;
	}
	public void setPassWorld(int passWorld) {
		this.passWorld = passWorld;
	}
	
}


這段程式碼特別簡單,它裡面的屬性就password一個然後一個getter和setter函式,加上構造方法沒了,沒什麼技術可言,至於作用,前面說過了。

這個程式的最終目的是讓客戶能夠算自己的個人所得稅,所以還得有一個客戶的工資類,也就是wage類。這個類的屬性包括三個:1、稅前工資wage;2、起徵點taxThreshold;3、稅率taxRate[]。根據題目的要求,個人所得稅稅率是分級的,本題只分了五級,所以,我把稅率設定成陣列,每個陣列元素代表一個稅率,這些稅率包括起徵點都是可變的,但是我把初始值設定成了題目裡面例子裡的值了。關於wage類,看程式碼:

package cn.mldn.util;

public class Wage {
	private double wage;               //稅前工資
	private double taxThreshold;       //稅起徵點
	private double taxRate[] = new double [5];            //稅率
	
	
	
	public Wage() {
		super();
		this.taxThreshold = 1600.0;
		this.taxRate = new double []{0.25, 0.20, 0.15, 0.10, 0.05};
	}
	public double getWage() {
		return wage;
	}
	public void setWage(double wage) {
		this.wage = wage;
	}
	public double getTaxThreshold() {
		return taxThreshold;
	}
	public void setTaxThreshold(double taxThreshold) {
		this.taxThreshold = taxThreshold;
	}
	public double[] getTaxRate() {
		return taxRate;
	}
	public void setTaxRate(double[] taxRate) {
		this.taxRate = taxRate;
	}
}


這段程式碼也是非常的簡單,比簡單java類還簡單,因為簡單java類裡面至少還有tostring方法吧。

當然啦,以上兩個類僅僅是影響著我們程式的兩個物件的屬性而已,即使用者和管理員。如何操作,我們有專門的主選單類,mainselect,看程式碼。這個類的功能主要有三個大的部分:1、管理員的許可權;2、使用者的許可權;3、選單。請看程式碼:

package cn.mldn.util;
import cn.mldn.util.*;
import java.util.Scanner;


public class MainSelect {
	private Wage wg = new Wage();
	private Manager mg = new Manager();
	private boolean j = true;        //負責控制退出系統
	private boolean i = true;
	/**
	 * 這是一個稅的計算軟體,根據實驗要求起徵點可調,稅率可調
	 * 但是這些工作誰來做,當然是管理員,管理員如何確認,當然需要一個祕鑰
	 */
	/**
	 * 管理員要根據政府的規定設定起徵點和稅率
	 * @param newTaxThreshold 這是新的起徵點
	 * @param newTaxRate 這是新的稅率
	 */
	public void setTaxThreshold(){
		Scanner input = new Scanner(System.in);
		System.out.println("請輸入新的稅率起徵點:");
		double newTaxThreshold = input.nextDouble();
		this.wg.setTaxThreshold(newTaxThreshold);
		System.out.println("設定起徵點完畢!");
	}
	public void setTaxRate(){
		Scanner input = new Scanner(System.in);
		double rate[] = new double[5];
        System.out.println("請輸入新的稅率:");
		for(int i = 0; i <= this.wg.getTaxRate().length - 1; i ++){
			rate[i] = input.nextDouble();
		}
		this.wg.setTaxRate(rate);
		System.out.println("設定稅率完畢!");
	}
	/**
	 * 現在題目給出的收稅級別有五個,也就是說,一個人的工資最多被劃分為五段,然後計算每段的稅,最後求和
	 * 我們把每段的稅後工資存放在數組裡,最後陣列求和
	 * @param Arry[5] 這個陣列用來存放每段的工資
	 * @return salaryAfterTax稅後工資;
	 */
	public double Calculation(){
		Scanner input = new Scanner(System.in);
		System.out.println("請輸入您的稅前工資!");
		double incomeBeforeTax = input.nextDouble();
		this.wg.setWage(incomeBeforeTax);
		double remain = this.wg.getWage();
		double salaryAfterTax = 0;
		double Arry [] = new double[5];
		if(remain < this.wg.getTaxThreshold()){
			System.out.println("根據國家法律規定,您的工資不在納稅範圍內");
		}
		if(remain >= this.wg.getTaxThreshold()){
			remain -= this.wg.getTaxThreshold();
			if(remain > 20000){
				Arry[0] = (remain - 20000) * this.wg.getTaxRate()[0];
				remain -= (remain -20000);
				salaryAfterTax += Arry[0];
			}
			if(remain > 5000 && remain <= 20000){
				Arry[1] = (remain - 5000) * this.wg.getTaxRate()[1];
				remain -= (remain -5000);
				salaryAfterTax += Arry[1];
			}
			if(remain > 2000 && remain <= 5000){
				Arry[2] = (remain - 2000) * this.wg.getTaxRate()[2];
				remain -= (remain -2000);
				salaryAfterTax += Arry[2];
			}
			if(remain > 500 && remain <= 2000){
				Arry[3] = (remain - 500) * this.wg.getTaxRate()[3];
				remain -= (remain - 500);
				salaryAfterTax += Arry[3];
			}
			if(remain <= 500){
				Arry[4] = remain * this.wg.getTaxRate()[4];
				salaryAfterTax += Arry[4];
			}
		}
		return salaryAfterTax;
	}
	//------------------exit退出操作-----------------
	 public void exit1(){
	 	j = false;
	 }
	 
	 public void exit2(){
		 	i = false;
		 }
	//-------------------選單------------
	 public void select(){
		 System.out.println("--------------------------------------------------");
		 System.out.println("-歡迎您使用稅率計算器,請確認您的身份。【1-客戶 ==0-管理員== 2- 退出】-");
		 System.out.println("--------------------------------------------------");
		while(j){
			j = true;
			System.out.println("請輸入您的選擇:");
			 Scanner input = new Scanner(System.in);
			 int select1 = input.nextInt();
			 switch(select1){
			 case 0:
				 System.out.println("請輸入管理員祕鑰:");
				 int num = input.nextInt();
				 if(num == this.mg.getPassWorld()){
					 System.out.println("------------------------------------------------");
					 System.out.println("-----管理員你好, 請選擇:【修改起徵點1, 修改稅率2,退出修改3】-----");
					 System.out.println("------------------------------------------------");
					while(i){
						i = true;
						int select2 = input.nextInt();
						switch(select2){
						case 1:
							this.setTaxThreshold();
							break;
						case 2:
							this.setTaxRate();
							break;
						case 3:
							System.out.println("退出稅收引數修改!");
							exit2();
							break;
						default:
							System.out.println("您的輸入有誤");
							break;
						}
					 }
					i = true;
				 } else {
					 System.out.println("您不能使用管理員許可權!!!");
				 }
				 break;
			 case 1:
				 System.out.println("---------------------------------------------");
				 System.out.println("----------尊敬 的客戶您好!歡迎您查詢您的個人所得稅---------");
				 System.out.println("---------------------------------------------");
				
				 System.out.println("您的個人所得稅是" + this.Calculation() + "元人民幣");
				 System.out.println("謝謝使用");
				 break;
			 case 2:
				 System.out.println("退出!!!");
				 exit1();
				 break;
			 default:
				System.out.println("您的輸入有誤!");
				break;
			 }
		}
	 }
}

最後,我們得設定一個客戶端吧。你懂得,看程式碼:

package cn.mldn.test;
import cn.mldn.util.*;

public class TestDemo {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		MainSelect money = new MainSelect();
		money.select();
	}
}

程式碼是這麼打完了,但是還得測試

3.3、測試用例

例如,張三某月工資薪金總收入為 4,300 元,減去免徵基數 1,600 元,則應納稅所得額為 2,700 元。應納稅所得額中,超過 2,000 部分為 2,700 – 2,000 = 700 元,按 15%稅率計算應納稅 105 元;而 500 元至 2,000 元的部分為 1,500 元,按 10%稅率計算應納稅 150 元;不超過 500 元的部分為 500 元,按 5%稅率計算應納稅 25 元。所以,該月張三應繳納的個人所得稅金額為 105 + 150 + 25 = 280 元。

4、實驗交流

我個人覺得作為java初學者的話這個專案還是很簡單的,當然我承認我的這個設計思路僅僅是一種,會有更好的思路值得學習的,程式設計的話,多打就是了。