第一週挑戰2:稅後工資計算器

重新實現上一個挑戰中的個稅計算器,可以計算並處理多人的工資並打印稅後工資。

項目需求改變:

輸出稅後工資
計算過程需要扣除社會保險費用
支持多人同時計算工資
打印稅後工資列表
個稅計算公式:

應納稅所得額 = 工資金額 - 各項社會保險費 - 專項扣除 - 起徵點(5000元)
納稅 = 應納稅所得額 × 稅率 - 速算扣除數
其中各項社會保險費我們在本程序中需要計算,計算公式由於各地不一樣,我們此處使用國內某一城市的計算比例,佔工資金額的比例如下:

養老保險:8%
醫療保險:2%
失業保險:0.5%
工傷保險:0%
生育保險:0%
公積金:6%
注意,此處不考慮社保繳費基數和專項扣除的問題。直接使用工資金額計算社保費用即可。
在這裏插入圖片描述
例如工資金額爲 6500,那麼五險一金繳納 1072.5 元,應納稅所得額爲 427.5(6500-5000-1072.5),納稅爲 12.825 元(427.5*3% - 0)。稅後工資爲 5414.68(6500-1072.5-12.825,保留兩位小數)。

程序的輸入爲員工的工號和工資金額,輸入的格式爲 工號:工資 工號:工資,程序使用 Python3 運行,執行過程如下:

$ python3 /home/shiyanlou/calculator.py 101:5000 203:6500 309:15000
101:4175.00
203:5414.68
309:11982.50

注意:輸出必須嚴格按照上述格式,在冒號的兩邊不能有空格
需要注意,程序執行的參數有一個或多個,並且參數爲工號及工資金額,工資金額需要爲整數,如果參數數量不準確或者無法轉成整數,需要使用 print 打印錯誤信息,代碼如下:

print("Parameter Error")
#!/usr/bin/env python3
import sys

def handle_data(i):
    one,two = i.split(":")
    try:
        income = float(two)
    except ValueError:
        print("Parameter Error")

    yingnashui = income - income * 0.165 - 5000

    if yingnashui <= 0 :
        result = income -(income * 0.165) - 0
    elif yingnashui <= 3000 :
        result = income - (income * 0.165) - yingnashui * 0.03 - 0
    elif yingnashui <= 12000:
        result = income - (income * 0.165) - yingnashui * 0.1 - 210
    elif yingnashui <= 25000:
        result = income - (income * 0.165) - yingnashui * 0.2 - 1410
    elif yingnashui <= 35000:
        result = income - (income * 0.165) - yingnashui * 0.25 - 2660
    elif yingnashui <= 55000:
        result = income - (income * 0.165) - yingnashui * 0.3 - 4410
    elif yingnashui <= 80000:
        result = income - (income * 0.165) - yingnashui * 0.35 - 7160
    else:
	    result = income -(income * 0.165) - yingnashui * 0.45 - 15160

    print('{}:{:.2f}'.format(one,result))

if __name__=='__main__':

    for i in sys.argv[1:]:
        handle_data(i)

想要寫的更規範一點:

# -*- coding: utf-8 -*-
import sys
from collections import namedtuple

# 稅率表條目類,該類由 namedtuple 動態創建,代表一個命名元組
# namedtuple一個爲命名元組的元素名,沒有實際意義,也用不到,下面是命名元組的元素名
IncomeTaxQuickLookupItem = namedtuple(
    'IncomeTaxQuickLookupItem',
    ['start_point', 'tax_rate', 'quick_subtractor']
)

# 起徵點常量
INCOME_TAX_START_POINT = 3500

# 稅率表,裏面的元素類型爲前面創建的 IncomeTaxQuickLookupItem
#這裏沒有考慮到應納稅所得額<0的情況
INCOME_TAX_QUICK_LOOKUP_TABLE = [
    IncomeTaxQuickLookupItem(80000, 0.45, 13505),
    IncomeTaxQuickLookupItem(55000, 0.35, 5505),
    IncomeTaxQuickLookupItem(35000, 0.30, 2755),
    IncomeTaxQuickLookupItem(9000, 0.25, 1005),
    IncomeTaxQuickLookupItem(4500, 0.2, 555),
    IncomeTaxQuickLookupItem(1500, 0.1, 105),
    IncomeTaxQuickLookupItem(0, 0.03, 0)
]

# 各種社保繳費比例常量
SOCIAL_INSURANCE_MONEY_RATE = {
    'endowment_insurance': 0.08,
    'medical_insurance': 0.02,
    'unemployment_insurance': 0.005,
    'employment_injury_insurance': 0,
    'maternity_insurance': 0,
    'public_accumulation_funds': 0.06
}


def calc_income_tax_and_remain(income):
    """
    工資納稅額計算器
    """

    # 計算扣除社保繳費和起徵點之後的應納稅額
    social_insurance_money = income * sum(SOCIAL_INSURANCE_MONEY_RATE.values())
    real_income = income - social_insurance_money
    taxable_part = real_income - INCOME_TAX_START_POINT

    # 從高到低判斷落入的稅率區間,如果找到則用該區間的參數計算納稅額並返回結果
    #返回了tax和real_income
    for item in INCOME_TAX_QUICK_LOOKUP_TABLE:
        if taxable_part > item.start_point:
            tax = taxable_part * item.tax_rate - item.quick_subtractor
            return '{:.2f}'.format(tax), '{:.2f}'.format(real_income - tax)

    # 如果沒有落入任何區間,則返回 0
    return '0.00', '{:.2f}'.format(real_income)


def main():
    """
    對命令行傳入的每一個用戶,依次調用計算器計算納稅額
    """

    # 循環處理每一個用戶
    for item in sys.argv[1:]:
        # 解析用戶 ID 和工資
        employee_id, income_string = item.split(':')
        try:
            income = int(income_string)
        except ValueError:
            print('Parameter Error')
            continue

        # 調用計算器並打印結果
        #這裏的_指的是這個變量以後都用不到了,不想佔用多餘的內存空間,可以直接省略掉,畢竟以後也用不到了,
        _, remain = calc_income_tax_and_remain(income)
        print('{}:{}'.format(employee_id, remain))


if __name__ == '__main__':
    main()

命名元組,namedtuple
如果一個元組爲[1,2,3],元組名爲n1,元素的名爲a,b,c,想獲取具體元素爲,n1[0]、n1[1]、n1[2]
但是命名元組可以爲n1.a n1,b n1,c

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章