将 CSV 值分配给 class 属性,使用抽象 classes 处理输出到 csv
Assign CSV values to class attributes, process output to csv using abstract classes
这个问题有点令人困惑所以请耐心等待,它也必须使用纯 Python 并且没有第三方模块来完成。
我似乎无法将正确的数据类型分配给 CSV 值并将它们分配给 class 属性。
我已经尝试了所有我知道的方法,四处寻找了几天的答案...
FLOAT赋值给"line[4]"时的值错误,不转换变量时的TypeError。
我也试过将它们分配给新变量并转换数据类型。我认为这是由于 rstrip() 和 strip() 函数输出。
ValueError: could not convert string to float: ''
TypeError: '>' not supported between instances of 'str' and 'int'
预期输出:
------- Resident ID: {self._id} -------
Gross: {self.gross}
Net: {self.net}
Tax: {self.tax}
------- Holiday ID: {self._id} -------
Gross: {self.gross}
Net: {self.net}
Tax: {self.tax}
Visa: {self._visa}
YTD: {self._year_to_date}
from abc import ABC, abstractmethod
from datetime import date #To assign <timestamp> for export_summary()
from typing import List
class PayRecord(ABC):
def __init__(self, id: int, hours:float, rates:float):
self._id = id
self._hours = hours
self._rates = rates
@abstractmethod
def get_details(self):
pass
@property
def id(self):
return self._id
@property
def gross(self):
return (self._hours * self._rates)
@property
@abstractmethod
def tax(self):
return self.tax
@property
def net(self):
return (self.gross - self.tax)
class ResidentPayRecord(PayRecord):
def __init__(self, id: int, hours:float, rates:float):
super().__init__(id, hours, rates)
def get_details(self):
return f"------- Resident ID: {self._id} -------\n\nGross: {self.gross}\nNet: {self.net}\nTax: {self.tax}\n"
@property
def tax(self):
return calc_res_tax(self.gross)
class WorkingHolidayPayRecord(PayRecord):
def __init__(self, id: int, hours:float, rates:float, visa: str, year_to_date:float):
super().__init__(id, hours, rates)
self._visa = visa
self._year_to_date = year_to_date
@property
def visa(self):
return self._visa
@property
def year_to_date(self):
return self._year_to_date
@property
def tax(self):
return calc_wh_tax(self.gross, self._year_to_date)
def get_details(self):
return f"------- Holiday ID: {self._id} -------\n\nGross: {self.gross}\nNet: {self.net}\nTax: {self.tax}\nVisa: {self._visa}\nYTD: {self._year_to_date}"
def calc_res_tax(gross: float):
A_eff = [0.19,0.2342,0.3477,0.345,0.39,0.47]
b_Eff =[0.19,3.213,44.2476,41.7311,103.8657,352.788]
if (gross > -1 and gross <= 72):
resTax = A_eff[0] * gross - b_Eff[0]
return resTax
if (gross > 72 and gross <= 361):
resTax = A_eff[1] * gross - b_Eff[1]
return resTax
if (gross > 361 and gross <= 932):
resTax = A_eff[2] * gross - b_Eff[2]
return resTax
if (gross > 932 and gross <= 1380):
resTax = A_eff[3] * gross - b_Eff[3]
return resTax
if (gross > 1380 and gross <= 3111):
resTax = A_eff[4] * gross - b_Eff[4]
return resTax
if (gross > 3111 and gross <= 999999):
resTax = A_eff[5] * gross - b_Eff[5]
return resTax
def calc_wh_tax(gross:float, year_to_date:float):
rate = [0.15,0.32,0.37,0.45]
if (year_to_date > -1 and year_to_date <= 37000):
whTax = gross * rate[0]
return whTax
if (year_to_date > 37000 and year_to_date <= 90000):
whTax = gross * rate[1]
return whTax
if (year_to_date > 90000 and year_to_date <= 180000):
whTax = gross * rate[2]
return whTax
if (year_to_date > 180000 and year_to_date <= 9999999):
whTax = gross * rate[3]
return whTax
def import_pay_records(file:str):
records = []
with open(file,"r") as f:
next(f)
for line in f:
line = line.rstrip().split(',')
id = int(line[0])
hours = float(line[1])
rates = float(line[2])
visa = str(line[3])
year_to_date = float(line[4])
app = id,hours,rates,visa,year_to_date
rec = [string for string in app if string != '']
records.append(rec)
create_pay_record(id,hours,rates,visa,year_to_date)
return records
def create_pay_record(id:int, hours:float, rates:float, visa:str, year_to_date:float):
r: ResidentPayRecord = ResidentPayRecord(id,hours,rates)
wh: WorkingHolidayPayRecord = WorkingHolidayPayRecord(id,hours,rates,visa,year_to_date)
print(r.get_details())
print(wh.get_details())
def write_summary(file:str, records:List[PayRecord], to_console:bool):
"""The function must accept a list of PayRecord objects and write the Id, Gross, Net, and Tax amounts of a pay record to a comma delimited values (.csv) file"""
pass
def main():
records = import_pay_records("import\employee-payroll-data.csv")
write_summary("export\export-data.csv",records,True)
if __name__ == '__main__':
main()
导入数据:
有更多的重复,但没关系。举个例子。
EmployeeId,Hours,Rate,Visa,YearToDate
1,2,25,,
1,3,25,,
1,4,25,,
1,5,32,,
1,6,32,,
2,2,25,417,47520.0
2,2,25,417,47520.0
2,2,25,417,47520.0
在 .split() 行之后,用一些数字替换空字符串,例如:
line = [string if string else '0' for string in line]
然后每个列表元素都可以转换为浮动。
顺便说一下,CSV 文件也可以用 pythons CSV Reader 模块读取 (Link)
如果某些字段为空并且 float('')
实际上引发的问题 ValueError
因此您应该在尝试转换之前测试空值:
year_to_date = float(line[4]) if line[4].strip() != '' else 0.0
这个问题有点令人困惑所以请耐心等待,它也必须使用纯 Python 并且没有第三方模块来完成。
我似乎无法将正确的数据类型分配给 CSV 值并将它们分配给 class 属性。
我已经尝试了所有我知道的方法,四处寻找了几天的答案...
FLOAT赋值给"line[4]"时的值错误,不转换变量时的TypeError。
我也试过将它们分配给新变量并转换数据类型。我认为这是由于 rstrip() 和 strip() 函数输出。
ValueError: could not convert string to float: ''
TypeError: '>' not supported between instances of 'str' and 'int'
预期输出:
------- Resident ID: {self._id} -------
Gross: {self.gross}
Net: {self.net}
Tax: {self.tax}
------- Holiday ID: {self._id} -------
Gross: {self.gross}
Net: {self.net}
Tax: {self.tax}
Visa: {self._visa}
YTD: {self._year_to_date}
from abc import ABC, abstractmethod
from datetime import date #To assign <timestamp> for export_summary()
from typing import List
class PayRecord(ABC):
def __init__(self, id: int, hours:float, rates:float):
self._id = id
self._hours = hours
self._rates = rates
@abstractmethod
def get_details(self):
pass
@property
def id(self):
return self._id
@property
def gross(self):
return (self._hours * self._rates)
@property
@abstractmethod
def tax(self):
return self.tax
@property
def net(self):
return (self.gross - self.tax)
class ResidentPayRecord(PayRecord):
def __init__(self, id: int, hours:float, rates:float):
super().__init__(id, hours, rates)
def get_details(self):
return f"------- Resident ID: {self._id} -------\n\nGross: {self.gross}\nNet: {self.net}\nTax: {self.tax}\n"
@property
def tax(self):
return calc_res_tax(self.gross)
class WorkingHolidayPayRecord(PayRecord):
def __init__(self, id: int, hours:float, rates:float, visa: str, year_to_date:float):
super().__init__(id, hours, rates)
self._visa = visa
self._year_to_date = year_to_date
@property
def visa(self):
return self._visa
@property
def year_to_date(self):
return self._year_to_date
@property
def tax(self):
return calc_wh_tax(self.gross, self._year_to_date)
def get_details(self):
return f"------- Holiday ID: {self._id} -------\n\nGross: {self.gross}\nNet: {self.net}\nTax: {self.tax}\nVisa: {self._visa}\nYTD: {self._year_to_date}"
def calc_res_tax(gross: float):
A_eff = [0.19,0.2342,0.3477,0.345,0.39,0.47]
b_Eff =[0.19,3.213,44.2476,41.7311,103.8657,352.788]
if (gross > -1 and gross <= 72):
resTax = A_eff[0] * gross - b_Eff[0]
return resTax
if (gross > 72 and gross <= 361):
resTax = A_eff[1] * gross - b_Eff[1]
return resTax
if (gross > 361 and gross <= 932):
resTax = A_eff[2] * gross - b_Eff[2]
return resTax
if (gross > 932 and gross <= 1380):
resTax = A_eff[3] * gross - b_Eff[3]
return resTax
if (gross > 1380 and gross <= 3111):
resTax = A_eff[4] * gross - b_Eff[4]
return resTax
if (gross > 3111 and gross <= 999999):
resTax = A_eff[5] * gross - b_Eff[5]
return resTax
def calc_wh_tax(gross:float, year_to_date:float):
rate = [0.15,0.32,0.37,0.45]
if (year_to_date > -1 and year_to_date <= 37000):
whTax = gross * rate[0]
return whTax
if (year_to_date > 37000 and year_to_date <= 90000):
whTax = gross * rate[1]
return whTax
if (year_to_date > 90000 and year_to_date <= 180000):
whTax = gross * rate[2]
return whTax
if (year_to_date > 180000 and year_to_date <= 9999999):
whTax = gross * rate[3]
return whTax
def import_pay_records(file:str):
records = []
with open(file,"r") as f:
next(f)
for line in f:
line = line.rstrip().split(',')
id = int(line[0])
hours = float(line[1])
rates = float(line[2])
visa = str(line[3])
year_to_date = float(line[4])
app = id,hours,rates,visa,year_to_date
rec = [string for string in app if string != '']
records.append(rec)
create_pay_record(id,hours,rates,visa,year_to_date)
return records
def create_pay_record(id:int, hours:float, rates:float, visa:str, year_to_date:float):
r: ResidentPayRecord = ResidentPayRecord(id,hours,rates)
wh: WorkingHolidayPayRecord = WorkingHolidayPayRecord(id,hours,rates,visa,year_to_date)
print(r.get_details())
print(wh.get_details())
def write_summary(file:str, records:List[PayRecord], to_console:bool):
"""The function must accept a list of PayRecord objects and write the Id, Gross, Net, and Tax amounts of a pay record to a comma delimited values (.csv) file"""
pass
def main():
records = import_pay_records("import\employee-payroll-data.csv")
write_summary("export\export-data.csv",records,True)
if __name__ == '__main__':
main()
导入数据: 有更多的重复,但没关系。举个例子。
EmployeeId,Hours,Rate,Visa,YearToDate
1,2,25,,
1,3,25,,
1,4,25,,
1,5,32,,
1,6,32,,
2,2,25,417,47520.0
2,2,25,417,47520.0
2,2,25,417,47520.0
在 .split() 行之后,用一些数字替换空字符串,例如:
line = [string if string else '0' for string in line]
然后每个列表元素都可以转换为浮动。
顺便说一下,CSV 文件也可以用 pythons CSV Reader 模块读取 (Link)
如果某些字段为空并且 float('')
实际上引发的问题 ValueError
因此您应该在尝试转换之前测试空值:
year_to_date = float(line[4]) if line[4].strip() != '' else 0.0