介绍

重新实现上一个挑战中的计算器,可以支持从配置文件中读取社保的税率,并读取员工工资数据 CSV 文件,同时将输出信息写入员工工资单 CSV 文件中。

计算器执行中包含下面的三个参数:

  • -c 配置文件:由于各地的社保比例稍有不同,我们为每个城市提供一个社保比例的配置文件。
  • -d 员工工资数据文件(CSV 格式): 指定员工工资数据文件,文件中包含两列内容,分别为员工工号和工资金额。
  • -o 员工工资单数据文件(CSV 格式): 输出内容,将员工缴纳的社保、税前、税后工资等详细信息输出到文件中。

1. 配置文件说明

配置文件格式示例如下:

配置文件中,各类保险以其汉语拼音命名(养老保险 → YangLao,公积金 → GongJiJin 等)。特别需要注意的是

  • JiShuL 为社保缴费基数的下限,即工资低于 JiShuL 的值的时候,需要按照 JiShuL 的数值乘以缴费比例来缴纳社保。
  • JiShuH 为社保缴费基数的上限,即工资高于 JiShuH 的值的时候,需要按照 JiShuH 的数值乘以缴费比例缴纳社保。
  • 当工资在 JiShuLJiShuH 之间的时候,按照你实际的工资金额乘以缴费比例计算社保费用。

例如:当工资为 20000 时,因为社保基数为 2193(JiShuL) ~ 16446(JiShuH),所以是按照社保基数上限 16446(而不是用 20000) 去乘以社保的缴费比例计算实际缴纳的社保数额。

2. 员工工资数据文件说明

员工工资数据文件,即本实验中输入的数据文件。每位员工工资数据单独占一行,文件格式为 工号,税前工资,举例如下:

3. 员工工资单数据文件说明

员工工资单数据文件,即本实验需要输出得到的数据文件。同样,输出的员工工资单数据文件中,每行格式为 工号,税前工资,社保金额,个税金额,税后工资,举例如下:

需要特别注意的是

  • 上面只是示例输出(3 行数据),测试时候用的数据文件可能有更多行,输出的文件行数要与测试文件行数相同,但不需要保持相同的顺序。

  • 程序的执行过程如下,配置文件 test.cfg 和输入的员工数据文件 user.csv 需要自己创建并填入数据(可参考上述内容示例)。文件可以放在任何位置,只要参数中指定文件的路径就可以了,示例如下:

目标

完成任务需要达成的目标:

  1. 程序存放的位置 /home/shiyanlou/calculator.py
  2. 程序必须对文件是否存在,以及是否符合格式要求进行判断,如果有错误需要打印错误信息并退出。
  3. 程序返回的税后工资、个税及社保数字保留两位小数,如果是整数,仍然需要保存为 xxx.00 这种形式。

提示语

下述实现方案仅供参考,会涉及到先前实验中学习到的知识点,如果自己对程序有足够的理解也可以不按照下述提示编写

  • 需要注意社保基数的处理,比如 20000 元工资高于社保基数的上限 JiShuH 的值,就应该用 JiShuH 这个值去乘以比例计算需要缴纳的社保金额。
  • 可以实现一个配置类 Config,来获取并存储配置文件中的信息,Config 类 def __init__(self, configfile) 中定义一个字典 self._config = {} 来存储每个配置项和值,从文件中读取的时候需要注意使用 strip() 去掉空格,并可以使用字符串的 split('=') 将配置项和值切分开。从 Config 对象中获得配置信息的方法可以定义为 def get_config(self),使用类似 config.get_config('JiShuH')
  • 可以实现一个员工数据类 UserData,来获取并存储员工数据,同样 def __init__(self, userdatafile) 中定义一个字典 self.userdata = {} 存储文件中读取的用户 ID及工资,并实现相应的金额计算的方法def calculator(self) 及输出到文件中的方法 def dumptofile(self, outputfile)
  • 需要在上述类中实现文件读取和写入等操作,写入的格式需要保证符合上述描述内容。
  • 处理命令行参数的方式:

    • 首先使用 args = sys.argv[1:] 获得所有的命令行参数列表,即包括 -c test.cfg -d user.csv -o gongzi.csv 这些内容。
    • 使用 index = args.index('-c') 获得 -c 参数的索引,那么配置文件的路径就是 -c 后的参数即 configfile = args[index+1],同样,其他的 -d-o 参数也用这种方法获得。

如果你阅读完提示之后,依旧没有思路。下面给出了一些示例代码。代码仅供参考,你可以按照自己的想法调整类以及类里面包含的函数。

# -*- coding: utf-8 -*-
import sys
import csv # 用于写入 csv 文件# 处理命令行参数类
class Args(object):def __init__(self):self.args = sys.argv[1:]"""补充代码:1. 补充参数读取函数,并返回相应的路径.2. 当参数格式出错时,抛出异常."""# 配置文件类
class Config(object):def __init__(self):self.config = self._read_config()# 配置文件读取内部函数def _read_config(self):config = {}"""补充代码:1. 根据参数指定的配置文件路径,读取配置文件信息,并写入到 config 字典中.2. 使用 strip() 和 split() 对读取到的配置文件去掉空格以及切分.3. 当格式出错时,抛出异常."""# 用户数据类
class UserData(object):def __init__(self):self.userdata = self._read_users_data()# 用户数据读取内部函数def _read_users_data(self):userdata = []"""补充代码:1. 根据参数指定的工资文件路径,读取员工 ID 和工资数据.2. 可将员工工号和工资数据设置为元组,并存入 userdata 列表中.3. 当格式出错时,抛出异常."""# 税后工资计算类
class IncomeTaxCalculator(object):# 计算每位员工的税后工资函数def calc_for_all_userdata(self):"""补充代码:1. 计算每位员工的税后工资(扣减个税和社保).2. 注意社保基数的判断.3. 将每位员工的税后工资按指定格式返回."""# 输出 CSV 文件函数def export(self, default='csv'):result = self.calc_for_all_userdata()with open("输出文件的路径,由输入参数获得") as f:writer = csv.writer(f)writer.writerows(result)# 执行
if __name__ == '__main__':"""按实际情况补充代码"""

通过代码:

 1 #!/usr/bin/env python3                           #这个不能漏,告诉用的是Python3
 2 # _*_ coding: utf-8 _*_                          #用的是utf-8编码
 3 import sys                                       #导入系统接口,调用命令行参数
 4 import csv                                       #导入纯文本文件模块
 5 #这个类比较简单,就不加方法了
 6 class Args:                                      #定义一个类,从命令行获得路径的,类的()不是必须的,但必须首字母大写
 7     def __init__(self):                          #定义初始化函数,self就是指向实例的,所以才有后面的 args.c
 8         l = sys.argv[1:]                         #把命令行参数列表放到一个列表里面,从1开始是因为要除掉第一个./calculator.py
 9         self.c = l[l.index('-c')+1]              #获得-c的索引,+1就是路径,./calculator.py -c /home/shiyanlou/test.cfg -d /home/shiyanlou/user.csv -o /tmp/gongzi.csv
10         self.d = l[l.index('-d')+1]
11         self.o = l[l.index('-o')+1]
12
13 args = Args()                                    #实例化一个类对象,才会自动调用__init__初始化函数,执行后面的内容,不实例化就不会执行 __init__,不获得数据
14                                                   args 在文件内相当于全局变量,任何地方都可以直接引用,此时用args代替self就可以调用类的属性,
15 class Config:                                    #定义一个类,从配置路径里面获得配置文件
16
17     def __init__(self):                          #定义初始化函数
18         self.config = self._read_config()        #因为 __init__ 用到了 _read_config ,所以后者也执行了一次19
20     def _read_config(self):
21         d = {'s': 0}                             #s是比例
22         with open(args.c) as f1:                 #只有 'r' 可以省略,其他都不行
23             for line in f1.readlines():          #分行遍历读取f1
24                 m = line.split('=')              #以=分割成列表
25                 a, b = m[0].strip(), m[1].strip()#每一组第一个参数为key,第二个参数为value
26                 if a == 'JiShuL' or a == 'JiShuH':
27                     d[a] = float(b)              #第一个和第二个放入字典
28                 else:
29                     d['s'] += float(b)           #后面的依次放入字典,可以通过 d['s'] 获得比例,上下限也是
30         return d                                 #返回整个字典
31
32 config = Config().config                         #config是字典,通过字典可以获取值,{JiShuL:2193.00,JiShuH:1646.00,‘s':0.165}
33 #print(config1),怕弄混的话,可以后面加1做区分
34
35 def calc_for_all_userdata(salary):
36         salary = int(salary)
37         shebao = salary * config['s']
38         if salary < config['JiShuL']:
39             shebao = config['JiShuL'] * config['s']
40         if salary > config['JiShuH']:
41             shebao = config['JiShuH'] * config["s"]
42         m = salary - shebao - 3500
43         if m <= 0:
44             shui = 0
45         elif m <= 1500:
46             shui = m * 0.03
47         elif m <= 4500:
48             shui = m * 0.1-105
49         elif m <= 9000:
50             shui = m * 0.2-555
51         elif m <= 35000:
52             shui = m * 0.25-1005
53         elif m <= 55000:
54             shui = m * 0.3-2755
55         elif m <= 80000:
56             shui = m * 0.35-5505
57         else:
58             shui = m * 0.45-13505
59         shuihou = salary - shebao - shui
60         return [salary, format(shebao, '.2f'), format(shui, '.2f'), format(shuihou, '.2f')]               #后面三位要求保留两位小数嘛,注意工资并不要求是float
61
62 class Data:                                     #定义工号类
63     def __init__(self):
64         with open(args.d) as f:                 #打开工号和工资csv文件,‘r’可省略
65             l = list(csv.reader(f))             #reader是csv读取文件的方法,把文件内容读取出来成为列表
66         self.value = l                          #实例的 value 值是列表67 data = Data().value                             #这个列表赋值给 data 68   #print(data)                                   #[[101,3500],[203,5000],[309,15000]]
69 #现在我们已经可以获取全部数据了,再写一段把数据放到文件里的代码就完事儿了
70 with open(args.o, 'w') as f:                    #打开args.o路径,没有则新增,w表示删除新增
71     for a, b in data:                           #遍历data工号列表
72         x = calc_for_all_userdata(b)            #把工资代入,返回一个列表[3500,577.50,0.00,2922.50]
73         x.insert(0, a)                          #在x列表索引为0的位置上插入工号a,也就是101
74         csv.writer(f).writerow(x)               #调用csv的写入方法,写入f,也就是输出的args.0里面,row表示一行

转载于:https://www.cnblogs.com/LifeIsHardIUsePyhon/p/9062149.html

工资计算器读写数据文件相关推荐

  1. python实验楼工资计算器_挑战:工资计算器读写数据文件

    待完善 # -*- coding: utf-8 -*- import sys import csv # 用于写入 csv 文件 # 处理命令行参数类 class Args(object): def _ ...

  2. c语言打开关闭文件的顺序,C语言1-文件概述、文件的打开与关闭、顺序读写数据文件(1).docx...

    C语言程序设计教案 章节名称 文件概述.文件的打开与关闭.顺序读写数据文件(1) 授课类型 □理论 □实验 ?理实一体 □实训 □实习 班级 地点 周次 星期 节次 授课进度 ?符合 □超前 □滞后 ...

  3. python 读写数据文件的6种常用方式

    本文主要介绍python读写数据文件的6种常用方式. 1. python内置方法 with open(r'test.xlsx') as f:a = f.read() 一般,在应用上述上下文管理器后,可 ...

  4. python调用文件对象所提供的读取数据的函数_python读写数据文件

    1. read.readline.readlines (1)open函数 如果你想用python读取文件(如txt.csv等),第一步要用open函数打开文件. open()是python的内置函数, ...

  5. python读取数据文件-python多种读写excel等数据文件的方式(收藏篇)

    前言: python处理数据文件的途径有很多种,可以操作的文件类型主要包括文本文件(csv.txt.json等).excel文件.数据库文件.api等其他数据文件.下面小编整理下python到底有哪些 ...

  6. Python数据分析之Pandas读写外部数据文件

    点击上方"Datawhale",选择"星标"公众号 第一时间获取价值内容 阅读目录 1 引言 2 文本文件(txt.csv) 2.1 读取数据 2.2 写入数据 ...

  7. python变量存为matlab,详解如何在python中读写和存储matlab的数据文件(*.mat)

    背景 在做deeplearning过程中,使用caffe的框架,一般使用matlab来处理图片(matlab处理图片相对简单,高效),用python来生成需要的lmdb文件以及做test产生结果.所以 ...

  8. python里读写excel等数据文件的6种常用方式

    下面整理下python有哪些方式可以读取数据文件. 1. python内置方法(read.readline.readlines) read() : 一次性读取整个文件内容.推荐使用read(size) ...

  9. < Android数据存储> 任务二 应用程序数据文件夹里的文件读写

    :zh]Android中提供了两个方法用来打开应用程序的数据文件夹IO流. 1.FileInputStream openFileInput(String name):参数name表示某个文件名,该方法 ...

最新文章

  1. 这道「传说级」的数学题,为什么有 3 个正确答案?
  2. 自建Yum源并与科大开源镜像站进行同步
  3. 2019年6月SAP发布的未来ABAP平台的发展方向
  4. 使用cookies查询商品详情
  5. flashmx action画线方法(下)
  6. 测试工程师常见的算法面试题
  7. 让MAC在TouchBar显示网速
  8. RK3399 修改android桌面图标默认大小
  9. php表白情话,唯美表白情话短句 八字古风情话
  10. 『幽默』网络经典语录1600条~~(可累死我了)
  11. 【行业秘密公开】所谓的QQ刷钻业务
  12. cv2 EigenFace(特征脸)
  13. 如何在word里面打对勾
  14. 万龙链——广应用场景,强价值背书,催生无限可能
  15. 【微信小程序经验】各类图表相关组件+Demo源码(折线图,柱状图,K线,分时图)
  16. Oracle数据库全备份和增量备份Windows
  17. 传智播客武汉校区校长焦宁波:我和传智播客的那些事儿
  18. 国内外主要黑苹果论坛一览(修正版)
  19. husky + lint-staged 使用备忘
  20. 操作系统学习总结(上)

热门文章

  1. android 系统/本地日志打印
  2. MybatisX idea 快速开发插件
  3. 笔趣阁小说-圣墟-爬虫源代码
  4. java提取word中的图片
  5. 103个后台PSD源文件、素材网站
  6. mysql多表查询注意事项_MySQL的多表查询
  7. C#--Link to sql语法大全
  8. SQL简明数据分析教程
  9. 想要写好文案,就要学习这八种动物
  10. 清华大学赵志磊--基于thinkPHP6框架的Excel表格导入和导出