第一周挑战2:税后工资计算器
程序员文章站
2024-02-27 12:40:03
...
重新实现上一个挑战中的个税计算器,可以计算并处理多人的工资并打印税后工资。
项目需求改变:
输出税后工资
计算过程需要扣除社会保险费用
支持多人同时计算工资
打印税后工资列表
个税计算公式:
应纳税所得额 = 工资金额 - 各项社会保险费 - 专项扣除 - 起征点(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