欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

第一周挑战2:税后工资计算器

程序员文章站 2024-02-27 12:40:03
...

重新实现上一个挑战中的个税计算器,可以计算并处理多人的工资并打印税后工资。

项目需求改变:

输出税后工资
计算过程需要扣除社会保险费用
支持多人同时计算工资
打印税后工资列表
个税计算公式:

应纳税所得额 = 工资金额 - 各项社会保险费 - 专项扣除 - 起征点(5000元)
纳税 = 应纳税所得额 × 税率 - 速算扣除数
其中各项社会保险费我们在本程序中需要计算,计算公式由于各地不一样,我们此处使用国内某一城市的计算比例,占工资金额的比例如下:

养老保险:8%
医疗保险:2%
失业保险:0.5%
工伤保险:0%
生育保险:0%
公积金:6%
注意,此处不考虑社保缴费基数和专项扣除的问题。直接使用工资金额计算社保费用即可。
第一周挑战2:税后工资计算器
例如工资金额为 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

相关标签: 跟宝宝一起学习