如题,表格情况类似这样。
image.png
我做一个简要说明:
- 每一行都是一个费用记录。
- 一个部门(department)有多个项目(project),一个项目有多个资源实例(instance),每个实例有若干个按月结算的账单(bill),其计费时长不规律。
大家也看到了,这张表格有5000+行。手工统计保守估计一整天,其机械重复简直不能忍。谁让咱们是码农呢,虽然python是第三职业语言了,该挽起袖子上就上。
Talk is cheap, show everyone the code!
# -*- coding: utf-8 -*-#
# -------------------------------------------------------------------------------
# Name: ${NAME}
# Description:
# Author: ${USER}
# Date: ${DATE}
# -------------------------------------------------------------------------------
import xlrd
import decimal
# 项目类:一个项目包含N个不同类型的资源实例,一个实例包含N个月的账单。
class Project:
def __init__(self, department_name="", project_name=""):
self.__department_name = department_name
self.__project = project_name
self.__instances = []
def set_project(self, project_name=""):
self.__project = project_name
def add_source_instance(self, instance):
if instance is not None:
self.__instances.append(instance)
else:
print("添加了一个空的INSTANCE")
def get_instance_by_id(self, id):
for instance in self.__instances:
if instance.get_instance_id() == id:
return instance
return None
def is_instance_added(self, instance_id):
for instance in self.__instances:
if instance.get_instance_id() == instance_id:
return True
return False
def __str__(self):
# 1.分类计算各种资源实例用量
instance_type_dict = dict()
for i in self.__instances:
type = i.get_type()
if type not in instance_type_dict:
instance_type_dict[type] = 1
else:
instance_type_dict[type] += 1
instance_count_str = "用到资源情况-->"
for k in instance_type_dict:
instance_count_str += (k+":" + str(instance_type_dict[k]) + ",")
# 2.计算所有资源实例的花费
total_bill = 0
max_bill_time = 1
for i in self.__instances:
total_bill += i.get_total_bill()
if i.get_bill_time() > max_bill_time:
max_bill_time = i.get_bill_time()
return r"部门:{0}, 项目{1}。{2}。总共计费:{3}, 最长资源使用{4}个月,月均费用:{5}".format(self.__department_name,
self.__project, instance_count_str, total_bill, max_bill_time,
decimal.Decimal(str(total_bill/max_bill_time)).quantize(decimal.Decimal('0.00'))
)
# 资源实例
class Instance:
def __init__(self, instanc_id="", instance_name="", instance_region="", instance_type="", instance_inuse_time=""):
self.__instance_id = instanc_id
self.__instance_name = instance_name
self.__instance_type = instance_type
self.__instance_region = instance_region
self.__instance_inuse_time = instance_inuse_time
self.__instance_bills = []
def get_instance_id(self):
return self.__instance_id
def get_type(self):
return self.__instance_type
def get_total_bill(self):
total_bill = 0
for b in self.__instance_bills:
total_bill += b.get_price()
return total_bill
# 计费持续了几个月
def get_bill_time(self):
return len(self.__instance_bills)
def add_bill(self, bill):
if bill is not None:
self.__instance_bills.append(bill)
else:
print("添加了一个空的BILL")
# 资源账单
class Bill:
def __init__(self, date="", price=0):
self.__date = date
self.__price = price
def get_price(self):
return self.__price
def get_date(self):
return self.__price
def __str__(self):
return r"{0}的账单为{1}".format(self.__date, self.__price)
def main():
excel_path = r"C:\Users\XXX\PycharmProjects\excelOperations\resouce\计费账单.xls"
work_book = xlrd.open_workbook(excel_path)
work_sheet = work_book.sheets()[0]
print(work_sheet.nrows)
project_dict = dict()
row = work_sheet.nrows
for i in range(row):
# 跳过表头
if i <= 1:
continue
rowdate = work_sheet.row_values(i) # i行的list
# print(rowdate)
# id 部门 项目名称 实例id 实例名称 实例位于区域 产品类型 开通时间 计费月份 资源来源 单月总价 核对状态
# 0 1 2 3 4 5 6 7 8 9 10 11
# 判断资源实例属于哪个项目,如果在就直接追加实例,否则先创建项目再追加项目。
instance_id = rowdate[3]
instance = Instance(rowdate[3], rowdate[4], rowdate[5], rowdate[6], rowdate[7])
# 由于有的项目没有项目名称,所以这里采用“部门+项目”的方式来唯一确定一个项目。
department_name = rowdate[1]
project_name = rowdate[2]
key_in_project_dict = r"{0}+{1}".format(department_name, project_name)
# step1: 判断项目是否已经存在于项目字典,没有就加进去。
if key_in_project_dict not in project_dict:
temp_project = Project(rowdate[1], rowdate[2])
project_dict[key_in_project_dict] = temp_project
else:
temp_project = project_dict[key_in_project_dict]
# step2:判断资源实例还没有被添加到其对应的项目中,没有就添加。否则就什么都不做
if not temp_project.is_instance_added(instance_id):
project_dict[key_in_project_dict].add_source_instance(instance)
# step3:追加账单到对应的资源实例
bill = Bill(rowdate[8], rowdate[10])
temp_instance = temp_project.get_instance_by_id(instance_id)
if temp_instance is None:
print("debug")
else:
temp_instance.add_bill(bill)
for temp_project_name in project_dict:
print(project_dict[temp_project_name])
if __name__ == '__main__':
main()
网友评论