日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

挑战:工资计算器读写数据文件

發布時間:2023/12/20 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 挑战:工资计算器读写数据文件 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

重新實現上一個挑戰中的計算器,可以支持從配置文件中讀取社保的稅率,并讀取員工工資數據 CSV 文件,同時將輸出信息寫入員工工資單 CSV 文件中。

計算器執行中包含下面的三個參數:

-c 社保比例配置文件:由于各地的社保比例稍有不同,需要為每個城市提供一個單獨的社保比例的配置,本挑戰假定不考慮各地社保差異,僅提供一份通用配置。 -d 員工工資數據文件(CSV 格式): 指定員工工資數據文件,文件中包含兩列內容,分別為員工工號和工資金額。 -o 員工工資單數據文件(CSV 格式): 輸出內容,將員工繳納的社保、稅前、稅后工資等詳細信息輸出到文件中。 1. 配置文件說明 社保比例配置文件格式示例如下(等號兩邊均有空格): JiShuL = 2193.00 JiShuH = 16446.00 YangLao = 0.08 YiLiao = 0.02 ShiYe = 0.005 GongShang = 0 ShengYu = 0 GongJiJin = 0.06

將以上數據寫入 /home/shiyanlou/test.cfg 文件中。

配置文件中,各類保險以其漢語拼音命名(養老保險 → YangLao,公積金 → GongJiJin 等)。特別需要注意的是:

JiShuL 為社保繳費基數的下限,即工資低于 JiShuL 的值的時候,需要按照 JiShuL 的數值乘以繳費比例來繳納社保。
JiShuH 為社保繳費基數的上限,即工資高于 JiShuH 的值的時候,需要按照 JiShuH 的數值乘以繳費比例繳納社保。
當工資在 JiShuL 和 JiShuH 之間的時候,按照你實際的工資金額乘以繳費比例計算社保費用。
例如:當工資為 20000 時,因為社保基數為 2193(JiShuL)~ 16446(JiShuH),所以是按照社保基數上限 16446(而不是用 20000) 去乘以社保的繳費比例計算實際繳納的社保數額。

  • 員工工資數據文件說明
    員工工資數據文件,即本實驗中輸入的數據文件。每位員工工資數據單獨占一行,文件格式為 工號,稅前工資,舉例如下:
  • 101,5000 203,6500 309,15000

    將以上數據寫入 /home/shiyanlou/user.csv 文件中。

  • 員工工資單數據文件說明
    員工工資單數據文件,即本實驗需要輸出得到的數據文件。同樣,輸出的員工工資單數據文件中,每行各項數據用逗號隔開,各項數據為 工號,稅前工資,社保金額,個稅金額,稅后工資,舉例如下:
  • 101,5000,825.00,0.00,4175.00 203,6500,1072.50,12.82,5414.68 309,15000,2475.00,542.50,11982.50

    需要特別注意的是:

    上面只是示例輸出(3 行數據),測試時候用的數據文件可能有更多行,輸出的文件行數要與測試文件行數相同,但不需要保持相同的順序。

    程序的執行過程如下,配置文件 test.cfg 和輸入的員工數據文件 user.csv 需要自己創建并填入數據(可參考上述內容示例)。文件可以放在任何位置,只要參數中指定文件的路徑就可以了,示例如下:

    $ ./calculator.py -c /home/shiyanlou/test.cfg -d /home/shiyanlou/user.csv -o /tmp/gongzi.csv

    執行成功不需要輸出信息到屏幕,執行失敗或有異常出現則將錯誤信息輸出到屏幕。

    import sys import csv from collections import namedtuple# 稅率表條目類,該類由 namedtuple 動態創建,代表一個命名元組 IncomeTaxQuickLookupItem = namedtuple('IncomeTaxQuickLookupItem',['start_point', 'tax_rate', 'quick_subtractor'] )# 起征點常量 INCOME_TAX_START_POINT = 5000# 稅率表,里面的元素類型為前面創建的 IncomeTaxQuickLookupItem INCOME_TAX_QUICK_LOOKUP_TABLE = [IncomeTaxQuickLookupItem(80000, 0.45, 15160),IncomeTaxQuickLookupItem(55000, 0.35, 7160),IncomeTaxQuickLookupItem(35000, 0.30, 4410),IncomeTaxQuickLookupItem(25000, 0.25, 2660),IncomeTaxQuickLookupItem(12000, 0.2, 1410),IncomeTaxQuickLookupItem(3000, 0.1, 210),IncomeTaxQuickLookupItem(0, 0.03, 0) ]class Args(object):"""命令行參數處理類"""def __init__(self):# 保存命令行參數列表self.args = sys.argv[1:]def _value_after_option(self, option):"""內部函數,用來獲取跟在選項后面的值"""try:# 獲得選項位置index = self.args.index(option)# 下一位置即為選項值return self.args[index + 1]except (ValueError, IndexError):print('Parameter Error')exit()@propertydef config_path(self):"""配置文件路徑"""return self._value_after_option('-c')@propertydef userdata_path(self):"""用戶工資文件路徑"""return self._value_after_option('-d')@propertydef export_path(self):"""稅后工資文件路徑"""return self._value_after_option('-o')# 創建一個全局參數類對象供后續使用 args = Args()class Config(object):"""配置文件處理類"""def __init__(self):# 讀取配置文件self.config = self._read_config()def _read_config(self):"""內部函數,用來讀取配置文件中的配置項"""config = {}with open(args.config_path) as f:# 依次讀取配置文件里的每一行并解析得到配置項名稱和值for line in f.readlines():key, value = line.strip().split('=')try:# 去掉前后可能出現的空格config[key.strip()] = float(value.strip())except ValueError:print('Parameter Error')exit()return configdef _get_config(self, key):"""內部函數,用來獲得配置項的值"""try:return self.config[key]except KeyError:print('Config Error')exit()@propertydef social_insurance_baseline_low(self):"""獲取社保基數下限"""return self._get_config('JiShuL')@propertydef social_insurance_baseline_high(self):"""獲取社保基數上限"""return self._get_config('JiShuH')@propertydef social_insurance_total_rate(self):"""獲取社保總費率"""return sum([self._get_config('YangLao'),self._get_config('YiLiao'),self._get_config('ShiYe'),self._get_config('GongShang'),self._get_config('ShengYu'),self._get_config('GongJiJin')])# 創建一個全局的配置文件處理對象供后續使用 config = Config()class UserData(object):"""用戶工資文件處理類"""def __init__(self):# 讀取用戶工資文件self.userlist = self._read_users_data()def _read_users_data(self):"""內部函數,用來讀取用戶工資文件"""userlist = []with open(args.userdata_path) as f:# 依次讀取用戶工資文件中的每一行并解析得到用戶 ID 和工資for line in f.readlines():employee_id, income_string = line.strip().split(',')try:income = int(income_string)except ValueError:print('Parameter Error')exit()userlist.append((employee_id, income))return userlistdef get_userlist(self):"""獲取用戶數據列表"""# 直接返回屬性 userlist 列表對象return self.userlistclass IncomeTaxCalculator(object):"""稅后工資計算類"""def __init__(self, userdata):# 初始化時接收一個 UserData 對象self.userdata = userdata@classmethoddef calc_social_insurance_money(cls, income):"""計算社保金額"""if income < config.social_insurance_baseline_low:return config.social_insurance_baseline_low * \config.social_insurance_total_rateelif income > config.social_insurance_baseline_high:return config.social_insurance_baseline_high * \config.social_insurance_total_rateelse:return income * config.social_insurance_total_rate@classmethoddef calc_income_tax_and_remain(cls, income):"""計算稅后工資"""# 計算社保金額social_insurance_money = cls.calc_social_insurance_money(income)# 計算應納稅額real_income = income - social_insurance_moneytaxable_part = real_income - INCOME_TAX_START_POINT# 從高到低判斷落入的稅率區間,如果找到則用該區間的參數計算納稅額并返回結果for item in INCOME_TAX_QUICK_LOOKUP_TABLE:if taxable_part > item.start_point:tax = taxable_part * item.tax_rate - item.quick_subtractorreturn '{:.2f}'.format(tax), '{:.2f}'.format(real_income - tax)# 如果沒有落入任何區間,則返回 0return '0.00', '{:.2f}'.format(real_income)def calc_for_all_userdata(self):"""計算所有用戶的稅后工資"""result = []# 循環計算每一個用戶的稅后工資,并將結果匯總到結果集中for employee_id, income in self.userdata.get_userlist():# 計算社保金額social_insurance_money = '{:.2f}'.format(self.calc_social_insurance_money(income))# 計算稅后工資tax, remain = self.calc_income_tax_and_remain(income)# 添加到結果集result.append([employee_id, income, social_insurance_money, tax, remain])return resultdef export(self):"""導出所有用戶的稅后工資到文件"""# 計算所有用戶的稅后工資result = self.calc_for_all_userdata()with open(args.export_path, 'w', newline='') as f:# 創建 csv 文件寫入對象writer = csv.writer(f)# 寫入多行數據writer.writerows(result)if __name__ == '__main__':# 創建稅后工資計算器calculator = IncomeTaxCalculator(UserData())# 調用 export 方法導出稅后工資到文件calculator.export() 需要注意社保基數的處理,比如 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 參數也用這種方法獲得。 在 Windows 系統中使用 Python 代碼寫入 csv 文件會出現空行,加個參數 newline='' 即可解決:>>> with open('xxx.csv', 'w', newline='') as f: ... csv.writer(f).writerows(data) ... 深入理解python @classmethod被@classmethod裝飾的方法 1. 強制帶個參數,cls,cls代表這個類本身 2. 不用實例化,和靜態方法一樣,直接 類().方法() 即可調用 3. cls是個位置參數,可隨意換成其他詞,如this如想獲取類屬性x的值,可直接cls.x,等價于A.x class A():x = 1@classmethoddef B(cls):print(cls.x)>> A.B() 1已知cls代表類本身,那么cls(123),就等價于A(123),調用init初始化,實例化為x cls(123) 等價于 x = A(123)class A():def __init__(self, q):self.q = q@classmethoddef B(cls):return cls(123)>> x = A.B() >> print(x.q) 123 運行邏輯:A() - B() - cls(123) - x = A(123)

    也許:https://blog.csdn.net/qq_39698985/article/details/106729710?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.nonecase

    使用Python內置的@property裝飾器就是負責把一個方法變成屬性調用:
    https://www.cnblogs.com/phpper/p/10618775.html

    總結

    以上是生活随笔為你收集整理的挑战:工资计算器读写数据文件的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。