重新實現上一個挑戰中的個稅計算器,可以計算並處理多人的工資並打印稅後工資。
項目需求改變:
輸出稅後工資
計算過程需要扣除社會保險費用
支持多人同時計算工資
打印稅後工資列表
個稅計算公式:
應納稅所得額 = 工資金額 - 各項社會保險費 - 專項扣除 - 起徵點(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