From ca91d2888a4ef0a6e84cb7f5b622938ac7089a98 Mon Sep 17 00:00:00 2001 From: chenzheng06 Date: Wed, 26 Apr 2017 16:55:05 -0400 Subject: [PATCH 01/12] Restructure income_statement class. Create income_statement_table class --- bpfin/financials/financial_lib.py | 95 ++++++++++++++++++++++++++++--- 1 file changed, 87 insertions(+), 8 deletions(-) diff --git a/bpfin/financials/financial_lib.py b/bpfin/financials/financial_lib.py index dcf1358..964ca35 100644 --- a/bpfin/financials/financial_lib.py +++ b/bpfin/financials/financial_lib.py @@ -1,13 +1,13 @@ # import datetime # import calendar -# from bpfin.lib import other as lib +from bpfin.lib import other as lib import bpfin.utilbills.bill_lib as bl from bpfin.tests.testdata import sample_data as db # import pprint def income_statement_single_year(year, income_input, bill_overview): - """calculate income statement for one single year, with inputs from UI and energy bill overview + """calculate income statement for one single year, with some inputs and energy bill overview Args: year (int): the year of this income statement @@ -34,12 +34,7 @@ def income_statement_single_year(year, income_input, bill_overview): net_non_energy_opex = other_utility + non_utility_expense total_opex = energy_opex + net_non_energy_opex noi = revenue - total_opex # net operating income - # energy_debt_service = - # other_debt_service = - # total_debt_service = - # bill_saving = - # energy_DSCR = - # total_DSCR = + income_statement = { 'year': year, @@ -116,6 +111,43 @@ class Income_Statement(): self.net_non_energy_opex = None self.total_opex = None self.noi = None + # energy_debt_service = + # other_debt_service = + # total_debt_service = + # bill_saving = + # energy_DSCR = + # total_DSCR = + + def put_hist(self, year, income_input, annual_bill_table): + """calculate historical income statement for one year, with some inputs and energy bill overview + + Args: + year (int): the year of this income statement + income_input (dictionary): 3 elements of inputs + annual_bill_table (dictionary): annual bill, for 4 utility_types + Returns: + dictionary: historical income statement for one year with standarized items filled + + Description Sample: + income_input = {revenue': 100000, 'utility_expense': 60000,'non_utility_expense': 3000} + annual_bill_table = {'electricity': electricity_bill, 'oil': oil_bill, 'gas': gas_bill, 'water': water_bill} + """ + self.year = year + self.revenue = income_input['revenue'] + self.utility_expense = income_input['utility_expense'] + self.non_utility_expense = income_input['non_utility_expense'] + self.electricity_opex = annual_bill_table['electricity'][self.year] + self.gas_opex = annual_bill_table['gas'][self.year] + self.oil_opex = annual_bill_table['oil'][self.year] + self.water_opex = annual_bill_table['water'][self.year] + self.energy_opex = self.electricity_opex + self.oil_opex + self.gas_opex + self.water_opex + self.other_utility = self.utility_expense - self.energy_opex + self.net_non_energy_opex = self.other_utility + self.non_utility_expense + self.total_opex = self.energy_opex + self.net_non_energy_opex + self.noi = self.revenue - self.total_opex # net operating income + + def put_next(self, income_statement_characters, bill_overview_organized) + def assign_next(self, income_statement_characters, bill_overview_organized): self.electricity_opex = bill_overview_organized['electricity'][self.year] @@ -160,3 +192,50 @@ def convert_income_statement_class(income_statement_class): 'total_opex': income_statement_class.total_opex, 'noi': income_statement_class.noi} return income_statement_dict + + +class Income_Statement_Table(): + def __init__(self, raw_income_input, annual_bill_table): + self.hist_start_year = None + self.hist_end_year = None + self.cagr = 0.00 + self.other_utility_percent = 0.00 + self.non_utility_expense_percent = 0.00 + self.revenue_average = 0.00 # average revenue + + self.income_statement_table = [] + for year in raw_income_input: + current_income_statement = Income_Statement() + current_income_statement.put_hist(year, raw_income_input[year], annual_bill_table) + self.income_statement_table.append(current_income_statement) + + sorted_income_hist_year = sorted(raw_income_input) + self.hist_start_year = sorted_income_hist_year[0] + self.hist_end_year = sorted_income_hist_year[-1] + # if start_year == None: return None + self.cagr = lib.cal_cagr( + raw_income_input[self.hist_start_year]['revenue'], + raw_income_input[self.hist_end_year]['revenue'], + self.hist_end_year - self.hist_start_year) + + revenue_sum = 0 + other_utility_sum = 0 + non_utility_expense_sum = 0 + for current_income_statement in self.income_statement_table: + revenue_sum += current_income_statement.revenue + other_utility_sum += current_income_statement.other_utility + non_utility_expense_sum += current_income_statement.non_utility_expense + + self. + result_dict = { + 'start_year': start_year, + 'end_year': end_year, + 'cagr': cagr, + 'other_utility_percent': other_utility_sum/revenue_sum, + 'non_utility_expense_percent': non_utility_expense_sum/revenue_sum, + 'revenue_average': revenue_sum / (end_year - start_year + 1) # average revenue + } + return result_dict + + +IS_table = Income_Statement_Table(db.raw_income_input, db.bill_overview_organized) -- GitLab From c4824a8c5122c4a72fa0906b182d9a1547fe44c8 Mon Sep 17 00:00:00 2001 From: chenzheng06 Date: Wed, 26 Apr 2017 18:44:16 -0400 Subject: [PATCH 02/12] Create project method in Income_Statement_Table --- bpfin/financials/financial_lib.py | 70 ++++++++++++++++++++++++------- 1 file changed, 54 insertions(+), 16 deletions(-) diff --git a/bpfin/financials/financial_lib.py b/bpfin/financials/financial_lib.py index 964ca35..b56a396 100644 --- a/bpfin/financials/financial_lib.py +++ b/bpfin/financials/financial_lib.py @@ -2,6 +2,7 @@ # import calendar from bpfin.lib import other as lib import bpfin.utilbills.bill_lib as bl +from bpfin.utilbills.bill_lib import form_bill_year from bpfin.tests.testdata import sample_data as db # import pprint @@ -35,7 +36,6 @@ def income_statement_single_year(year, income_input, bill_overview): total_opex = energy_opex + net_non_energy_opex noi = revenue - total_opex # net operating income - income_statement = { 'year': year, 'revenue': revenue, @@ -66,8 +66,8 @@ def organize_bill_overview(bill_overview, analysis_date): Description: analysis_date: {'proforma_start': datetime.date, 'proforma_duration': int} """ - proforma_year = bl.form_bill_year(analysis_date['proforma_start'], - analysis_date['proforma_duration']) + proforma_year = form_bill_year(analysis_date['proforma_start'], + analysis_date['proforma_duration']) bill_dict = {} bill_dict[1] = bill_overview['electricity'] # electricity_bill bill_dict[2] = bill_overview['gas'] # gas_bill @@ -146,9 +146,6 @@ class Income_Statement(): self.total_opex = self.energy_opex + self.net_non_energy_opex self.noi = self.revenue - self.total_opex # net operating income - def put_next(self, income_statement_characters, bill_overview_organized) - - def assign_next(self, income_statement_characters, bill_overview_organized): self.electricity_opex = bill_overview_organized['electricity'][self.year] self.gas_opex = bill_overview_organized['gas'][self.year] @@ -194,6 +191,32 @@ def convert_income_statement_class(income_statement_class): return income_statement_dict +class Income_Statement_Next(): + def __init__(self, year, last_revenue, growth_rate_flag, characters, annual_bill_table): + self.year = year + + if growth_rate_flag == -1.0: # growth_rate_flag == average + current_revenue = characters['revenue_average'] + else: + if growth_rate_flag == -2.0: # growth_rate_flag == cagr + growth_rate = characters['cagr'] + else: + growth_rate = growth_rate_flag # growth_rate_flag == 0.00, 0.01, ... + current_revenue = last_revenue * (1 + growth_rate) + self.revenue = current_revenue + self.electricity_opex = annual_bill_table['electricity'][self.year] + self.gas_opex = annual_bill_table['gas'][self.year] + self.oil_opex = annual_bill_table['oil'][self.year] + self.water_opex = annual_bill_table['water'][self.year] + self.energy_opex = self.electricity_opex + self.gas_opex + self.oil_opex + self.water_opex + self.other_utility = self.revenue * characters['other_utility_percent'] + self.non_utility_expense = self.revenue * characters['non_utility_expense_percent'] + self.utility_expense = self.energy_opex + self.other_utility + self.net_non_energy_opex = self.other_utility + self.non_utility_expense + self.total_opex = self.energy_opex + self.net_non_energy_opex + self.noi = self.revenue - self.total_opex + + class Income_Statement_Table(): def __init__(self, raw_income_input, annual_bill_table): self.hist_start_year = None @@ -202,8 +225,8 @@ class Income_Statement_Table(): self.other_utility_percent = 0.00 self.non_utility_expense_percent = 0.00 self.revenue_average = 0.00 # average revenue - self.income_statement_table = [] + for year in raw_income_input: current_income_statement = Income_Statement() current_income_statement.put_hist(year, raw_income_input[year], annual_bill_table) @@ -226,16 +249,31 @@ class Income_Statement_Table(): other_utility_sum += current_income_statement.other_utility non_utility_expense_sum += current_income_statement.non_utility_expense - self. - result_dict = { - 'start_year': start_year, - 'end_year': end_year, - 'cagr': cagr, - 'other_utility_percent': other_utility_sum/revenue_sum, - 'non_utility_expense_percent': non_utility_expense_sum/revenue_sum, - 'revenue_average': revenue_sum / (end_year - start_year + 1) # average revenue + self.other_utility_percent = other_utility_sum/revenue_sum + self.non_utility_expense_percent = non_utility_expense_sum/revenue_sum + self.revenue_average = revenue_sum / (self.hist_end_year - self.hist_start_year + 1) + + def project(self, growth_rate_flag, analysis_date, annual_bill_table): + characters = { + 'start_year': self.hist_start_year, + 'end_year': self.hist_end_year, + 'cagr': self.cagr, + 'other_utility_percent': self.other_utility_percent, + 'non_utility_expense_percent': self.non_utility_expense_percent, + 'revenue_average': self.revenue_average } - return result_dict + proforma_year = form_bill_year(analysis_date['proforma_start'], + analysis_date['proforma_duration']) + + for year in proforma_year: + last_revenue = self.income_statement_table[-1].revenue + if year <= characters['end_year']: + continue + current_income_statement = Income_Statement_Next( + year, last_revenue, growth_rate_flag, characters, annual_bill_table) + self.income_statement_table.append(current_income_statement) + print(current_income_statement.revenue, current_income_statement.noi) IS_table = Income_Statement_Table(db.raw_income_input, db.bill_overview_organized) +IS_table.project(-1.0, db.analysis_date, db.bill_overview_organized) -- GitLab From ab689f495047bb460a1e559035217d1467c9bdb1 Mon Sep 17 00:00:00 2001 From: chenzheng06 Date: Wed, 26 Apr 2017 19:33:09 -0400 Subject: [PATCH 03/12] Create get_single_year method for Income_Statement_table --- bpfin/financials/financial_lib.py | 39 +++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/bpfin/financials/financial_lib.py b/bpfin/financials/financial_lib.py index b56a396..5137162 100644 --- a/bpfin/financials/financial_lib.py +++ b/bpfin/financials/financial_lib.py @@ -225,12 +225,12 @@ class Income_Statement_Table(): self.other_utility_percent = 0.00 self.non_utility_expense_percent = 0.00 self.revenue_average = 0.00 # average revenue - self.income_statement_table = [] + self.table = [] for year in raw_income_input: current_income_statement = Income_Statement() current_income_statement.put_hist(year, raw_income_input[year], annual_bill_table) - self.income_statement_table.append(current_income_statement) + self.table.append(current_income_statement) sorted_income_hist_year = sorted(raw_income_input) self.hist_start_year = sorted_income_hist_year[0] @@ -244,7 +244,7 @@ class Income_Statement_Table(): revenue_sum = 0 other_utility_sum = 0 non_utility_expense_sum = 0 - for current_income_statement in self.income_statement_table: + for current_income_statement in self.table: revenue_sum += current_income_statement.revenue other_utility_sum += current_income_statement.other_utility non_utility_expense_sum += current_income_statement.non_utility_expense @@ -266,14 +266,39 @@ class Income_Statement_Table(): analysis_date['proforma_duration']) for year in proforma_year: - last_revenue = self.income_statement_table[-1].revenue - if year <= characters['end_year']: + last_revenue = self.table[-1].revenue + if year <= self.table[-1].year: continue current_income_statement = Income_Statement_Next( year, last_revenue, growth_rate_flag, characters, annual_bill_table) - self.income_statement_table.append(current_income_statement) - print(current_income_statement.revenue, current_income_statement.noi) + self.table.append(current_income_statement) + # print(current_income_statement.revenue, current_income_statement.noi) + + def get_average(self): + pass + + def get_single_year(self, year): + for current_income_statement in self.table: + if current_income_statement.year == year: + return { + 'year': current_income_statement.year, + 'revenue': current_income_statement.revenue, + 'utility_expense': current_income_statement.utility_expense, + 'energy_opex': current_income_statement.energy_opex, + 'electricity_opex': current_income_statement.electricity_opex, + 'gas_opex': current_income_statement.gas_opex, + 'oil_opex': current_income_statement.oil_opex, + 'water_opex': current_income_statement.water_opex, + 'other_utility': current_income_statement.other_utility, + 'non_utility_expense': current_income_statement.non_utility_expense, + 'net_non_energy_opex': current_income_statement.net_non_energy_opex, + 'total_opex': current_income_statement.total_opex, + 'noi': current_income_statement.noi} + return None IS_table = Income_Statement_Table(db.raw_income_input, db.bill_overview_organized) IS_table.project(-1.0, db.analysis_date, db.bill_overview_organized) +print(IS_table.get_single_year(2017)) +# for year_id in range(50): +# print(IS_table.table[year_id].year) -- GitLab From 5ccb19a0a2d729b7140dab4507e73f839cc42a31 Mon Sep 17 00:00:00 2001 From: chenzheng06 Date: Wed, 26 Apr 2017 19:53:27 -0400 Subject: [PATCH 04/12] Create Random test, trying to get average calculation --- bpfin/financials/financial_lib.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/bpfin/financials/financial_lib.py b/bpfin/financials/financial_lib.py index 5137162..abe1f56 100644 --- a/bpfin/financials/financial_lib.py +++ b/bpfin/financials/financial_lib.py @@ -264,7 +264,7 @@ class Income_Statement_Table(): } proforma_year = form_bill_year(analysis_date['proforma_start'], analysis_date['proforma_duration']) - + # !!!! need to cut the projection off for year in proforma_year: last_revenue = self.table[-1].revenue if year <= self.table[-1].year: @@ -274,8 +274,10 @@ class Income_Statement_Table(): self.table.append(current_income_statement) # print(current_income_statement.revenue, current_income_statement.noi) - def get_average(self): - pass + # def get_average(self, analysis_date, annual_bill_table): + # average_projection = self.project(-1.0, analysis_date, annual_bill_table) + # # should use copy? + # return average_projection.get_single_year(self.hist_end_year + 1) def get_single_year(self, year): for current_income_statement in self.table: @@ -298,7 +300,10 @@ class Income_Statement_Table(): IS_table = Income_Statement_Table(db.raw_income_input, db.bill_overview_organized) +IS_table.project(-2.0, db.analysis_date, db.bill_overview_organized) +print(IS_table.get_single_year(2017)) IS_table.project(-1.0, db.analysis_date, db.bill_overview_organized) print(IS_table.get_single_year(2017)) +# print(IS_table.get_single_year(2017)) # for year_id in range(50): # print(IS_table.table[year_id].year) -- GitLab From 466fefc10b6e5de6d5725d6e2d0de21810fb61ac Mon Sep 17 00:00:00 2001 From: chenzheng06 Date: Wed, 26 Apr 2017 23:24:48 -0400 Subject: [PATCH 05/12] Improve IS_Table class with a few get func Write down func needed to be developed --- bpfin/financials/financial_lib.py | 73 +++++++++++++++++++++++++------ 1 file changed, 59 insertions(+), 14 deletions(-) diff --git a/bpfin/financials/financial_lib.py b/bpfin/financials/financial_lib.py index abe1f56..0391ccd 100644 --- a/bpfin/financials/financial_lib.py +++ b/bpfin/financials/financial_lib.py @@ -190,6 +190,24 @@ def convert_income_statement_class(income_statement_class): 'noi': income_statement_class.noi} return income_statement_dict +def get_income_statement_single_year(self, year, income_statement_table): + for current_income_statement in income_statement_table: + if current_income_statement.year == year: + return { + 'year': current_income_statement.year, + 'revenue': current_income_statement.revenue, + 'utility_expense': current_income_statement.utility_expense, + 'energy_opex': current_income_statement.energy_opex, + 'electricity_opex': current_income_statement.electricity_opex, + 'gas_opex': current_income_statement.gas_opex, + 'oil_opex': current_income_statement.oil_opex, + 'water_opex': current_income_statement.water_opex, + 'other_utility': current_income_statement.other_utility, + 'non_utility_expense': current_income_statement.non_utility_expense, + 'net_non_energy_opex': current_income_statement.net_non_energy_opex, + 'total_opex': current_income_statement.total_opex, + 'noi': current_income_statement.noi} + return None class Income_Statement_Next(): def __init__(self, year, last_revenue, growth_rate_flag, characters, annual_bill_table): @@ -225,12 +243,13 @@ class Income_Statement_Table(): self.other_utility_percent = 0.00 self.non_utility_expense_percent = 0.00 self.revenue_average = 0.00 # average revenue + self.hist_table = [] self.table = [] for year in raw_income_input: current_income_statement = Income_Statement() current_income_statement.put_hist(year, raw_income_input[year], annual_bill_table) - self.table.append(current_income_statement) + self.hist_table.append(current_income_statement) sorted_income_hist_year = sorted(raw_income_input) self.hist_start_year = sorted_income_hist_year[0] @@ -244,7 +263,7 @@ class Income_Statement_Table(): revenue_sum = 0 other_utility_sum = 0 non_utility_expense_sum = 0 - for current_income_statement in self.table: + for current_income_statement in self.hist_table: revenue_sum += current_income_statement.revenue other_utility_sum += current_income_statement.other_utility non_utility_expense_sum += current_income_statement.non_utility_expense @@ -252,6 +271,17 @@ class Income_Statement_Table(): self.other_utility_percent = other_utility_sum/revenue_sum self.non_utility_expense_percent = non_utility_expense_sum/revenue_sum self.revenue_average = revenue_sum / (self.hist_end_year - self.hist_start_year + 1) + self.table = self.hist_table + + def get_hist_table(self): + return + + def get_cagr(self): + return self.cagr + + def get_average(self): + # current_year = 'Average' + average_income_statement = Income_Statement() def project(self, growth_rate_flag, analysis_date, annual_bill_table): characters = { @@ -264,20 +294,17 @@ class Income_Statement_Table(): } proforma_year = form_bill_year(analysis_date['proforma_start'], analysis_date['proforma_duration']) - # !!!! need to cut the projection off + current_table = self.hist_table for year in proforma_year: - last_revenue = self.table[-1].revenue - if year <= self.table[-1].year: + last_revenue = current_table[-1].revenue + if year <= current_table[-1].year: continue current_income_statement = Income_Statement_Next( year, last_revenue, growth_rate_flag, characters, annual_bill_table) - self.table.append(current_income_statement) + current_table.append(current_income_statement) # print(current_income_statement.revenue, current_income_statement.noi) - - # def get_average(self, analysis_date, annual_bill_table): - # average_projection = self.project(-1.0, analysis_date, annual_bill_table) - # # should use copy? - # return average_projection.get_single_year(self.hist_end_year + 1) + self.table = current_table + return current_table def get_single_year(self, year): for current_income_statement in self.table: @@ -298,12 +325,30 @@ class Income_Statement_Table(): 'noi': current_income_statement.noi} return None + def get_noi_dict(self): + # dictionary of noi, kyes are years + return + IS_table = Income_Statement_Table(db.raw_income_input, db.bill_overview_organized) -IS_table.project(-2.0, db.analysis_date, db.bill_overview_organized) -print(IS_table.get_single_year(2017)) IS_table.project(-1.0, db.analysis_date, db.bill_overview_organized) -print(IS_table.get_single_year(2017)) +# print(IS_table.get_single_year(2017)) +# IS_table.project(-1.0, db.analysis_date, db.bill_overview_organized) +# print(IS_table.get_single_year(2017)) # print(IS_table.get_single_year(2017)) # for year_id in range(50): # print(IS_table.table[year_id].year) + + +# ************ test draft*********** +# class test_stru(): +# def __init__(self, number): +# self.number = number + +# test_1 = test_stru(2.0) +# test_2 = test_stru(3.0) +# test_3 = test_stru(5.0) + +# test_list = [test_1, test_2, test_3] +# form_list = list(ob.number for ob in test_list) +# print(form_list) -- GitLab From 88c3c717221e8f8827d2aa0b93aa6f370ebd002d Mon Sep 17 00:00:00 2001 From: chenzheng06 Date: Thu, 27 Apr 2017 00:49:19 -0400 Subject: [PATCH 06/12] Create Income_Statement_Table class, methods, test file, and sample data Need to replace existing income_statement logics --- bpfin/financials/financial_lib.py | 134 ++++++++++++------ .../test_financials/test_financial_lib.py | 18 +++ bpfin/tests/testdata/sample_data.py | 20 +++ 3 files changed, 129 insertions(+), 43 deletions(-) diff --git a/bpfin/financials/financial_lib.py b/bpfin/financials/financial_lib.py index 0391ccd..207c0be 100644 --- a/bpfin/financials/financial_lib.py +++ b/bpfin/financials/financial_lib.py @@ -4,6 +4,8 @@ from bpfin.lib import other as lib import bpfin.utilbills.bill_lib as bl from bpfin.utilbills.bill_lib import form_bill_year from bpfin.tests.testdata import sample_data as db +from numpy import mean +import copy # import pprint @@ -146,6 +148,20 @@ class Income_Statement(): self.total_opex = self.energy_opex + self.net_non_energy_opex self.noi = self.revenue - self.total_opex # net operating income + def put_average(self, average_revenue, annual_bills, characters): + self.revenue = average_revenue + self.electricity_opex = annual_bills['electricity'] + self.gas_opex = annual_bills['gas'] + self.oil_opex = annual_bills['oil'] + self.water_opex = annual_bills['water'] + self.energy_opex = self.electricity_opex + self.gas_opex + self.oil_opex + self.water_opex + self.other_utility = self.revenue * characters['other_utility_percent'] + self.non_utility_expense = self.revenue * characters['non_utility_expense_percent'] + self.utility_expense = self.energy_opex + self.other_utility + self.net_non_energy_opex = self.other_utility + self.non_utility_expense + self.total_opex = self.energy_opex + self.net_non_energy_opex + self.noi = self.revenue - self.total_opex + def assign_next(self, income_statement_characters, bill_overview_organized): self.electricity_opex = bill_overview_organized['electricity'][self.year] self.gas_opex = bill_overview_organized['gas'][self.year] @@ -190,24 +206,6 @@ def convert_income_statement_class(income_statement_class): 'noi': income_statement_class.noi} return income_statement_dict -def get_income_statement_single_year(self, year, income_statement_table): - for current_income_statement in income_statement_table: - if current_income_statement.year == year: - return { - 'year': current_income_statement.year, - 'revenue': current_income_statement.revenue, - 'utility_expense': current_income_statement.utility_expense, - 'energy_opex': current_income_statement.energy_opex, - 'electricity_opex': current_income_statement.electricity_opex, - 'gas_opex': current_income_statement.gas_opex, - 'oil_opex': current_income_statement.oil_opex, - 'water_opex': current_income_statement.water_opex, - 'other_utility': current_income_statement.other_utility, - 'non_utility_expense': current_income_statement.non_utility_expense, - 'net_non_energy_opex': current_income_statement.net_non_energy_opex, - 'total_opex': current_income_statement.total_opex, - 'noi': current_income_statement.noi} - return None class Income_Statement_Next(): def __init__(self, year, last_revenue, growth_rate_flag, characters, annual_bill_table): @@ -245,6 +243,7 @@ class Income_Statement_Table(): self.revenue_average = 0.00 # average revenue self.hist_table = [] self.table = [] + self.characters = {} for year in raw_income_input: current_income_statement = Income_Statement() @@ -271,41 +270,68 @@ class Income_Statement_Table(): self.other_utility_percent = other_utility_sum/revenue_sum self.non_utility_expense_percent = non_utility_expense_sum/revenue_sum self.revenue_average = revenue_sum / (self.hist_end_year - self.hist_start_year + 1) - self.table = self.hist_table - def get_hist_table(self): - return - - def get_cagr(self): - return self.cagr - - def get_average(self): - # current_year = 'Average' - average_income_statement = Income_Statement() - - def project(self, growth_rate_flag, analysis_date, annual_bill_table): - characters = { + self.table = self.hist_table + self.characters = { 'start_year': self.hist_start_year, 'end_year': self.hist_end_year, 'cagr': self.cagr, 'other_utility_percent': self.other_utility_percent, 'non_utility_expense_percent': self.non_utility_expense_percent, - 'revenue_average': self.revenue_average - } + 'revenue_average': self.revenue_average} + + def project(self, growth_rate_flag, analysis_date, annual_bill_table): + # characters = copy.deepcopy(self.characters) proforma_year = form_bill_year(analysis_date['proforma_start'], analysis_date['proforma_duration']) - current_table = self.hist_table + current_table = copy.deepcopy(self.hist_table) for year in proforma_year: last_revenue = current_table[-1].revenue if year <= current_table[-1].year: continue current_income_statement = Income_Statement_Next( - year, last_revenue, growth_rate_flag, characters, annual_bill_table) + year, last_revenue, growth_rate_flag, self.characters, annual_bill_table) current_table.append(current_income_statement) # print(current_income_statement.revenue, current_income_statement.noi) self.table = current_table return current_table + def get_hist_table(self): + hist_table_dict = {} + for current_income_statement in self.hist_table: + hist_table_dict[current_income_statement.year] = { + 'year': current_income_statement.year, + 'revenue': current_income_statement.revenue, + 'utility_expense': current_income_statement.utility_expense, + 'energy_opex': current_income_statement.energy_opex, + 'electricity_opex': current_income_statement.electricity_opex, + 'gas_opex': current_income_statement.gas_opex, + 'oil_opex': current_income_statement.oil_opex, + 'water_opex': current_income_statement.water_opex, + 'other_utility': current_income_statement.other_utility, + 'non_utility_expense': current_income_statement.non_utility_expense, + 'net_non_energy_opex': current_income_statement.net_non_energy_opex, + 'total_opex': current_income_statement.total_opex, + 'noi': current_income_statement.noi} + return hist_table_dict + + def get_cagr(self): + return self.cagr + + def get_average(self): + # current_year = 'Average' + current_income_statement = Income_Statement() + average_revenue = mean(list(i_s.revenue for i_s in self.hist_table)) + annual_bills = { + 'electricity': mean(list(i_s.electricity_opex for i_s in self.hist_table)), + 'gas': mean(list(i_s.gas_opex for i_s in self.hist_table)), + 'oil': mean(list(i_s.oil_opex for i_s in self.hist_table)), + 'water': mean(list(i_s.water_opex for i_s in self.hist_table)) + } + current_income_statement.put_average(average_revenue, annual_bills, self.characters) + + return convert_income_statement_class(current_income_statement) + def get_single_year(self, year): for current_income_statement in self.table: if current_income_statement.year == year: @@ -326,19 +352,21 @@ class Income_Statement_Table(): return None def get_noi_dict(self): - # dictionary of noi, kyes are years - return + noi_dict = {} + for current_income_statement in self.table: + noi_dict[current_income_statement.year] = current_income_statement.noi + return noi_dict IS_table = Income_Statement_Table(db.raw_income_input, db.bill_overview_organized) IS_table.project(-1.0, db.analysis_date, db.bill_overview_organized) -# print(IS_table.get_single_year(2017)) -# IS_table.project(-1.0, db.analysis_date, db.bill_overview_organized) -# print(IS_table.get_single_year(2017)) -# print(IS_table.get_single_year(2017)) -# for year_id in range(50): -# print(IS_table.table[year_id].year) +#************* ugly tests*********** +assert IS_table.get_hist_table() == db.income_statement_full # test get_hist_table +print('\n cagr =', IS_table.get_cagr()) # test get_cagr +print('\n average hist =', IS_table.get_average()) # test get_average +print('\n noi dict =', IS_table.get_noi_dict()) # test get_noi_dict +print('\n 2017 income statement =', IS_table.get_single_year(2017)) # test get_single_year # ************ test draft*********** # class test_stru(): @@ -352,3 +380,23 @@ IS_table.project(-1.0, db.analysis_date, db.bill_overview_organized) # test_list = [test_1, test_2, test_3] # form_list = list(ob.number for ob in test_list) # print(form_list) + + +# def get_income_statement_single_year(self, year, income_statement_table): +# for current_income_statement in income_statement_table: +# if current_income_statement.year == year: +# return { +# 'year': current_income_statement.year, +# 'revenue': current_income_statement.revenue, +# 'utility_expense': current_income_statement.utility_expense, +# 'energy_opex': current_income_statement.energy_opex, +# 'electricity_opex': current_income_statement.electricity_opex, +# 'gas_opex': current_income_statement.gas_opex, +# 'oil_opex': current_income_statement.oil_opex, +# 'water_opex': current_income_statement.water_opex, +# 'other_utility': current_income_statement.other_utility, +# 'non_utility_expense': current_income_statement.non_utility_expense, +# 'net_non_energy_opex': current_income_statement.net_non_energy_opex, +# 'total_opex': current_income_statement.total_opex, +# 'noi': current_income_statement.noi} +# return None diff --git a/bpfin/tests/test_financials/test_financial_lib.py b/bpfin/tests/test_financials/test_financial_lib.py index b756a24..3d9c6e6 100644 --- a/bpfin/tests/test_financials/test_financial_lib.py +++ b/bpfin/tests/test_financials/test_financial_lib.py @@ -2,6 +2,7 @@ import datetime from bpfin.financials import financial_lib as fl from bpfin.tests.testdata import sample_data as db from bpfin.financials.income_statement_form_hist import form_income_statement_hist +from bpfin.financials.financial_lib import Income_Statement_Table def test_organize_bill_overview(): @@ -20,4 +21,21 @@ def test_income_statement_single_year(): assert output_dict == result_dict +def test_Income_Statement_Table(): + input_raw_income_input = db.raw_income_input + input_annual_bill_table = db.bill_overview_organized + output_cagr = 0.05409255338945984 + output_hist_table = db.income_statement_full + output_average_table = db.income_statement_average + output_noi_dict = db.noi_dict_average + output_single_year = db.income_statement_2017_avg + + IS_table = Income_Statement_Table(input_raw_income_input, input_annual_bill_table) + IS_table.project(-1.0, db.analysis_date, db.bill_overview_organized) + + assert IS_table.get_cagr() == output_cagr # test get_cagr + assert IS_table.get_hist_table() == output_hist_table # test get_hist_table + assert IS_table.get_average() == output_average_table # test get_average + assert IS_table.get_noi_dict() == output_noi_dict # test get_noi_dict + assert IS_table.get_single_year(2017) == output_single_year # test get_single_year diff --git a/bpfin/tests/testdata/sample_data.py b/bpfin/tests/testdata/sample_data.py index b7a8053..45f721a 100644 --- a/bpfin/tests/testdata/sample_data.py +++ b/bpfin/tests/testdata/sample_data.py @@ -192,6 +192,26 @@ income_statement_full = { 'total_opex': 63000.0, 'noi': 37000.0} } +income_statement_average = { + 'year': None, 'revenue': 95000.0, 'utility_expense': 56666.666666666672, 'energy_opex': 35880.343493666973, + 'electricity_opex': 33561.454604778082, 'gas_opex': 1164.4444444444443, 'oil_opex': 1154.4444444444443, + 'water_opex': 0.0, 'other_utility': 20786.323172999699, 'non_utility_expense': 3166.6666666666665, + 'net_non_energy_opex': 23952.989839666367, 'total_opex': 59833.333333333343, 'noi': 35166.666666666657} + +noi_dict_average = { + 2014: 31500.0, 2015: 37000.0, 2016: 37000.0, 2017: 33493.73724516164, 2018: 33165.377210606544, + 2019: 32298.852732150932, 2020: 31450.146124428546, 2021: 30663.261480034096, 2022: 29946.57845606045, + 2023: 29242.418277114877, 2024: 28522.26581429284, 2025: 27777.914231279196, 2026: 26974.67650825437, + 2027: 26110.42490293656, 2028: 25225.108030085234, 2029: 24339.044697870617, 2030: 23452.675696890437, + 2031: 22563.678164016266, 2032: 21664.038064983062, 2033: 20743.76458479633, 2034: 19798.79239963583, + 2035: 18828.088043102543, 2036: 17831.510509478205} + +income_statement_2017_avg = { + 'year': 2017, 'revenue': 95000.0, 'utility_expense': 58339.59608817169, 'energy_opex': 37553.27291517199, + 'electricity_opex': 34523.27291517199, 'gas_opex': 1520, 'oil_opex': 1510, 'water_opex': 0, + 'other_utility': 20786.3231729997, 'non_utility_expense': 3166.6666666666665, + 'net_non_energy_opex': 23952.989839666367, 'total_opex': 61506.26275483836, 'noi': 33493.73724516164} + # income_input_next = { # 'year': 2017, 'revenue': 105409.25533894598, 'utility_expense': 60617.176566756985, 'energy_opex': 37553.27291517199, # 'electricity_opex': 34523.27291517199, 'gas_opex': 1520, 'oil_opex': 1510, 'water_opex': 0, -- GitLab From 43786afab1eb24a93b50e96addf1028e3e1d0d4c Mon Sep 17 00:00:00 2001 From: chenzheng06 Date: Thu, 27 Apr 2017 10:28:44 -0400 Subject: [PATCH 07/12] Remove ugliy tests to comments --- bpfin/financials/financial_lib.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/bpfin/financials/financial_lib.py b/bpfin/financials/financial_lib.py index 207c0be..4532962 100644 --- a/bpfin/financials/financial_lib.py +++ b/bpfin/financials/financial_lib.py @@ -358,15 +358,14 @@ class Income_Statement_Table(): return noi_dict -IS_table = Income_Statement_Table(db.raw_income_input, db.bill_overview_organized) -IS_table.project(-1.0, db.analysis_date, db.bill_overview_organized) - -#************* ugly tests*********** -assert IS_table.get_hist_table() == db.income_statement_full # test get_hist_table -print('\n cagr =', IS_table.get_cagr()) # test get_cagr -print('\n average hist =', IS_table.get_average()) # test get_average -print('\n noi dict =', IS_table.get_noi_dict()) # test get_noi_dict -print('\n 2017 income statement =', IS_table.get_single_year(2017)) # test get_single_year +# ************ ugly tests*********** +# IS_table = Income_Statement_Table(db.raw_income_input, db.bill_overview_organized) +# IS_table.project(-1.0, db.analysis_date, db.bill_overview_organized) +# assert IS_table.get_hist_table() == db.income_statement_full # test get_hist_table +# print('\n cagr =', IS_table.get_cagr()) # test get_cagr +# print('\n average hist =', IS_table.get_average()) # test get_average +# print('\n noi dict =', IS_table.get_noi_dict()) # test get_noi_dict +# print('\n 2017 income statement =', IS_table.get_single_year(2017)) # test get_single_year # ************ test draft*********** # class test_stru(): -- GitLab From 82dbb5c56fd76c23f97cf9e9e56412b0a13bb82e Mon Sep 17 00:00:00 2001 From: chenzheng06 Date: Thu, 27 Apr 2017 19:24:42 -0400 Subject: [PATCH 08/12] Add func discription --- bpfin/financials/financial_lib.py | 58 +++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/bpfin/financials/financial_lib.py b/bpfin/financials/financial_lib.py index 4532962..d7813dc 100644 --- a/bpfin/financials/financial_lib.py +++ b/bpfin/financials/financial_lib.py @@ -149,6 +149,28 @@ class Income_Statement(): self.noi = self.revenue - self.total_opex # net operating income def put_average(self, average_revenue, annual_bills, characters): + """ + Calculate and create average income statement. + Revenue, energy bills are average of historical data. + Other itmers are calculated by historical characters. + Args: + average_revenue (float): average revenue calculated from historical income statements + annual_bill_table (dictionary): dictionary of dictionary of annual bills, for 4 utility_types + characters (dictionary): 6 characters calculated from historical income statements + Final instance is a single year income statement without named year + + Description: + characters = { + 'start_year': 2014, + 'end_year': 2016, + 'cagr': 0.054, + 'other_utility_percent': 0.02, + 'non_utility_expense_percent': 0.03, + 'revenue_average': 3000 + } + annual_bill_table = {'electricity': electricity_bill, 'oil': oil_bill, 'gas': gas_bill, 'water': water_bill} + electricity_bill = {2014: 100, 2015:200, ...} + """ self.revenue = average_revenue self.electricity_opex = annual_bills['electricity'] self.gas_opex = annual_bills['gas'] @@ -163,6 +185,9 @@ class Income_Statement(): self.noi = self.revenue - self.total_opex def assign_next(self, income_statement_characters, bill_overview_organized): + """ + this function will be deleted in the next version + """ self.electricity_opex = bill_overview_organized['electricity'][self.year] self.gas_opex = bill_overview_organized['gas'][self.year] self.oil_opex = bill_overview_organized['oil'][self.year] @@ -190,6 +215,13 @@ class Income_Statement(): def convert_income_statement_class(income_statement_class): + """ + Convert single year income statement objective into a dictionary format + Args: + income_statement_class (objective): single year income statement objective + Return: + income_statement_dict (dictionary) + """ income_statement_dict = { 'year': income_statement_class.year, 'revenue': income_statement_class.revenue, @@ -208,7 +240,33 @@ def convert_income_statement_class(income_statement_class): class Income_Statement_Next(): + """ + Create single year income_statement objective, + with input of last year data, income statement characters, and projected annual bill + """ def __init__(self, year, last_revenue, growth_rate_flag, characters, annual_bill_table): + """ + Calculation is done in initiation. + Args: + year (int): the year that will be projected on + last_revenue (float): last year revenue + growth_rate_flag (float): indicating assumed growth rate, -2.0 == cagr, -1.0 == historical average + characters (dictionary): 6 characters calculated from historical income statements + annual_bill_table (dictionary): dictionary of dictionary of annual bills, for 4 utility_types + Final instance is a single year income_statement objective + + Description: + characters = { + 'start_year': 2014, + 'end_year': 2016, + 'cagr': 0.054, + 'other_utility_percent': 0.02, + 'non_utility_expense_percent': 0.03, + 'revenue_average': 3000 + } + annual_bill_table = {'electricity': electricity_bill, 'oil': oil_bill, 'gas': gas_bill, 'water': water_bill} + electricity_bill = {2014: 100, 2015:200, ...} + """ self.year = year if growth_rate_flag == -1.0: # growth_rate_flag == average -- GitLab From fabaf9be947d58fb2c6af5fe8f1d18214741b4ee Mon Sep 17 00:00:00 2001 From: chenzheng06 Date: Thu, 27 Apr 2017 22:54:22 -0400 Subject: [PATCH 09/12] Add func description for Income_Statement and Income_Statement_Table Add comments on functions that will be replaced by class func --- bpfin/financials/financial_lib.py | 112 +++++++++++++++--- .../financials/income_statement_form_hist.py | 2 + bpfin/financials/income_statement_next.py | 1 + .../financials/income_statement_projection.py | 1 + 4 files changed, 98 insertions(+), 18 deletions(-) diff --git a/bpfin/financials/financial_lib.py b/bpfin/financials/financial_lib.py index d7813dc..2b68015 100644 --- a/bpfin/financials/financial_lib.py +++ b/bpfin/financials/financial_lib.py @@ -155,21 +155,20 @@ class Income_Statement(): Other itmers are calculated by historical characters. Args: average_revenue (float): average revenue calculated from historical income statements - annual_bill_table (dictionary): dictionary of dictionary of annual bills, for 4 utility_types + annual_bills (dictionary): dictionary of float value of average annual bills, for 4 utility_types characters (dictionary): 6 characters calculated from historical income statements Final instance is a single year income statement without named year Description: - characters = { - 'start_year': 2014, - 'end_year': 2016, - 'cagr': 0.054, - 'other_utility_percent': 0.02, - 'non_utility_expense_percent': 0.03, - 'revenue_average': 3000 - } - annual_bill_table = {'electricity': electricity_bill, 'oil': oil_bill, 'gas': gas_bill, 'water': water_bill} - electricity_bill = {2014: 100, 2015:200, ...} + characters = { + 'start_year': (int) 2014, + 'end_year': (int) 2016, + 'cagr': (float) 0.054, + 'other_utility_percent': (float) 0.02, + 'non_utility_expense_percent': (float) 0.03, + 'revenue_average': (float) 3000.00 + } + annual_bills = {'electricity': 100.0, 'oil': 200.0, 'gas': 300.0, 'water': 400.0} """ self.revenue = average_revenue self.electricity_opex = annual_bills['electricity'] @@ -257,12 +256,12 @@ class Income_Statement_Next(): Description: characters = { - 'start_year': 2014, - 'end_year': 2016, - 'cagr': 0.054, - 'other_utility_percent': 0.02, - 'non_utility_expense_percent': 0.03, - 'revenue_average': 3000 + 'start_year': (int) 2014, + 'end_year': (int) 2016, + 'cagr': (float) 0.054, + 'other_utility_percent': (float) 0.02, + 'non_utility_expense_percent': (float) 0.03, + 'revenue_average': (float) 3000.00 } annual_bill_table = {'electricity': electricity_bill, 'oil': oil_bill, 'gas': gas_bill, 'water': water_bill} electricity_bill = {2014: 100, 2015:200, ...} @@ -292,7 +291,40 @@ class Income_Statement_Next(): class Income_Statement_Table(): + """ + Create a income statement table, containing multiple years, including historical and projected data + Key Attributes are: + hist_table (list): list of single year income_statement objectives, containing historical data + table(list): list of single year income_statement objectives, containing historical and projected data + """ def __init__(self, raw_income_input, annual_bill_table): + """ + Create hist_table to store historical income statement data, and calculate some key characters. + Args: + raw_income_input (dictionary): dict of dict of incomplete income statement, for historical years. Key = year + annual_bill_table (dictionary): dictionary of dictionary of annual bills, for 4 utility_types + + Key Attributes: + cagr (float): compound annual growth rate + other_utility_percent (float): percentage, (average other_utility / average revenue) + non_utility_expense_percent (float): percentage, (average non_utility_expense_percent / average revenue) + hist_table (list): list of single year income_statement objectives, containing historical data + table(list): list of single year income_statement objectives, containing historical and projected data + characters (dictionary): contains key characters determined from historical data. Is used to project + + Description: + raw_income_input = {2014: {'revenue': 90.0, 'utility_expense': 55.0, 'non_utility_expense': 35.0}, 2015:{},} + annual_bill_table = {'electricity': electricity_bill, 'oil': oil_bill, 'gas': gas_bill, 'water': water_bill} + electricity_bill = {2014: 100, 2015:200, ...} + characters = { + 'start_year': (int) 2014, + 'end_year': (int) 2016, + 'cagr': (float) 0.054, + 'other_utility_percent': (float) 0.02, + 'non_utility_expense_percent': (float) 0.03, + 'revenue_average': (float) 3000.00 + } + """ self.hist_start_year = None self.hist_end_year = None self.cagr = 0.00 @@ -339,6 +371,17 @@ class Income_Statement_Table(): 'revenue_average': self.revenue_average} def project(self, growth_rate_flag, analysis_date, annual_bill_table): + """ + Project future income statement. Append multiple single year income_statement objectives to self.table + Args: + growth_rate_flag (float): indicating assumed growth rate, -2.0 == cagr, -1.0 == historical average + analysis_date (dictionary): proforma's starting date and the years of proforma + annual_bill_table (dictionary): dictionary of dictionary of annual bills, for 4 utility_types + Return: + list: list of single year income_statement objectives, containing historical and projection + Note: + project() overwrites existing projection data + """ # characters = copy.deepcopy(self.characters) proforma_year = form_bill_year(analysis_date['proforma_start'], analysis_date['proforma_duration']) @@ -355,6 +398,13 @@ class Income_Statement_Table(): return current_table def get_hist_table(self): + """ + Get historical table, in dictionary formatting + Return: + dictionary: dict of dict of income statement. Key is year + Description: + hist_table_dict = {2014: {'year': 2014, 'revenue': 100.0, ..., 'not': 5.0}, ... , 2016:{}} + """ hist_table_dict = {} for current_income_statement in self.hist_table: hist_table_dict[current_income_statement.year] = { @@ -374,9 +424,21 @@ class Income_Statement_Table(): return hist_table_dict def get_cagr(self): - return self.cagr + """ + Get compound annual growth rate + Return: + float: compound annual growth rate + """ + return copy.deepcopy(self.cagr) def get_average(self): + """ + Get average income statement. Only need initialized Income_Statement_Table + Return: + dictionary: dict of average income statement, Keys are income statement items. + Description: + output_dict = {'year': None, 'revenue': 95000.0, ... ,'noi': 35166.666666666657} + """ # current_year = 'Average' current_income_statement = Income_Statement() average_revenue = mean(list(i_s.revenue for i_s in self.hist_table)) @@ -391,6 +453,15 @@ class Income_Statement_Table(): return convert_income_statement_class(current_income_statement) def get_single_year(self, year): + """ + Get single year income statement from self.table. Table can either contain or not contain projection + Args: + year (int): the year that need to be extracted + Return: + dict: single year income statement. Keys are income statement items. + Note: + if the target year is not in self.table, then return None. + """ for current_income_statement in self.table: if current_income_statement.year == year: return { @@ -410,6 +481,11 @@ class Income_Statement_Table(): return None def get_noi_dict(self): + """ + Get a dictionary of net operating income. + Return: + dictionary: net operating income for each year in income statement table. Key is year + """ noi_dict = {} for current_income_statement in self.table: noi_dict[current_income_statement.year] = current_income_statement.noi diff --git a/bpfin/financials/income_statement_form_hist.py b/bpfin/financials/income_statement_form_hist.py index 65ba995..8e63bba 100644 --- a/bpfin/financials/income_statement_form_hist.py +++ b/bpfin/financials/income_statement_form_hist.py @@ -4,6 +4,7 @@ from bpfin.lib import other as lib def income_statement_character(income_statement_hist): """Determine annual growth rate, other_utility_percentage, non_utility_expense_percentage + !!!! This function should be deleted or rephrased in next version !! Args: income_statement_hist (dictionary): full income statement, with all items filled, for available years Return: @@ -43,6 +44,7 @@ def income_statement_character(income_statement_hist): def form_income_statement_hist(raw_income_input, bill_overview_organized, analysis_date): """ form income statement table with raw inputs from UI, and organized bill_overview. NO projection + !!!! This function should be deleted or rephrased in next version !! Args: raw_income_input (dictionary): dictionary of dictionary. raw inputs for income statement for available years bill_overview_organized (dictionary): dict of dict, 4 utility types, with blank charge filled with average diff --git a/bpfin/financials/income_statement_next.py b/bpfin/financials/income_statement_next.py index d46c4ab..b619049 100644 --- a/bpfin/financials/income_statement_next.py +++ b/bpfin/financials/income_statement_next.py @@ -7,6 +7,7 @@ from bpfin.financials.income_statement_form_hist import income_statement_charact def income_statement_next(income_statement_hist, bill_overview_organized, growth_rate_flag): """Project income statement for UI input. inputs are whatever bill and financial statements are available + !!!! This function should be deleted or rephrased in next version !! Args: income_statement_hist (dictionary): historical income statement, with all items filled, for available years bill_overview_organized (dictionary): annual bills for 4 utility types, with blank cells filled diff --git a/bpfin/financials/income_statement_projection.py b/bpfin/financials/income_statement_projection.py index ac4d589..221225d 100644 --- a/bpfin/financials/income_statement_projection.py +++ b/bpfin/financials/income_statement_projection.py @@ -8,6 +8,7 @@ import pprint def income_statement_projection(income_statement_hist, bill_overview_organized, growth_rate_flag, analysis_date): """ + !!!! This function should be deleted or rephrased in next version !! Project income statement tp future multiple years. inputs are historical income statements and annual bills. Args: income_statement_hist (dictionary): historical income statement, with all items filled, for available years -- GitLab From 87cc04edb4d452e40afe781445246ac3ef1ec1bd Mon Sep 17 00:00:00 2001 From: chenzheng06 Date: Thu, 27 Apr 2017 22:55:55 -0400 Subject: [PATCH 10/12] Minor comment change --- bpfin/financials/financial_lib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bpfin/financials/financial_lib.py b/bpfin/financials/financial_lib.py index 2b68015..6962a77 100644 --- a/bpfin/financials/financial_lib.py +++ b/bpfin/financials/financial_lib.py @@ -185,7 +185,7 @@ class Income_Statement(): def assign_next(self, income_statement_characters, bill_overview_organized): """ - this function will be deleted in the next version + !!! this function will be deleted in the next version!! """ self.electricity_opex = bill_overview_organized['electricity'][self.year] self.gas_opex = bill_overview_organized['gas'][self.year] -- GitLab From 53676b9f54d049c44fbb222ec2b415e8acfde093 Mon Sep 17 00:00:00 2001 From: chenzheng06 Date: Thu, 27 Apr 2017 22:59:54 -0400 Subject: [PATCH 11/12] Clean import file for financial_lib --- bpfin/financials/financial_lib.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bpfin/financials/financial_lib.py b/bpfin/financials/financial_lib.py index 6962a77..9470af0 100644 --- a/bpfin/financials/financial_lib.py +++ b/bpfin/financials/financial_lib.py @@ -1,11 +1,11 @@ # import datetime # import calendar +import copy from bpfin.lib import other as lib -import bpfin.utilbills.bill_lib as bl from bpfin.utilbills.bill_lib import form_bill_year -from bpfin.tests.testdata import sample_data as db from numpy import mean -import copy +# from bpfin.tests.testdata import sample_data as db +# import bpfin.utilbills.bill_lib as bl # import pprint -- GitLab From 3e5ea373c6ed3d8ecd306af6b808a40a740ee70f Mon Sep 17 00:00:00 2001 From: chenzheng06 Date: Fri, 28 Apr 2017 10:18:51 -0400 Subject: [PATCH 12/12] Fix description for Income_Statement put_hist(). Add clarification comment for percentage values --- bpfin/financials/financial_lib.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/bpfin/financials/financial_lib.py b/bpfin/financials/financial_lib.py index 9470af0..9245521 100644 --- a/bpfin/financials/financial_lib.py +++ b/bpfin/financials/financial_lib.py @@ -121,14 +121,15 @@ class Income_Statement(): # total_DSCR = def put_hist(self, year, income_input, annual_bill_table): - """calculate historical income statement for one year, with some inputs and energy bill overview + """ + Put historical income statement data and generate a single year income statement + Inputs are incomplete income statement items, and energy bill overview + Final output is an single year income_statement objectvie with standarized items filled Args: year (int): the year of this income statement income_input (dictionary): 3 elements of inputs annual_bill_table (dictionary): annual bill, for 4 utility_types - Returns: - dictionary: historical income statement for one year with standarized items filled Description Sample: income_input = {revenue': 100000, 'utility_expense': 60000,'non_utility_expense': 3000} @@ -152,7 +153,7 @@ class Income_Statement(): """ Calculate and create average income statement. Revenue, energy bills are average of historical data. - Other itmers are calculated by historical characters. + Other items are calculated by historical characters. Args: average_revenue (float): average revenue calculated from historical income statements annual_bills (dictionary): dictionary of float value of average annual bills, for 4 utility_types @@ -164,8 +165,8 @@ class Income_Statement(): 'start_year': (int) 2014, 'end_year': (int) 2016, 'cagr': (float) 0.054, - 'other_utility_percent': (float) 0.02, - 'non_utility_expense_percent': (float) 0.03, + 'other_utility_percent': (float) 0.020 == 2.0% + 'non_utility_expense_percent': (float) 0.030 == 3.0% 'revenue_average': (float) 3000.00 } annual_bills = {'electricity': 100.0, 'oil': 200.0, 'gas': 300.0, 'water': 400.0} @@ -259,8 +260,8 @@ class Income_Statement_Next(): 'start_year': (int) 2014, 'end_year': (int) 2016, 'cagr': (float) 0.054, - 'other_utility_percent': (float) 0.02, - 'non_utility_expense_percent': (float) 0.03, + 'other_utility_percent': (float) 0.020 == 2.0% + 'non_utility_expense_percent': (float) 0.035 == 3.5% 'revenue_average': (float) 3000.00 } annual_bill_table = {'electricity': electricity_bill, 'oil': oil_bill, 'gas': gas_bill, 'water': water_bill} -- GitLab