From 5b4436f22d74e8b89dc890da3676b753cb5712f8 Mon Sep 17 00:00:00 2001 From: chen Date: Wed, 27 Feb 2019 15:20:40 -0500 Subject: [PATCH 1/7] add test_Income_Statement_Next in test_financials --- .../test_financials/test_financial_income.py | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/bpfin/tests/test_financials/test_financial_income.py b/bpfin/tests/test_financials/test_financial_income.py index f92f427..2fba54f 100644 --- a/bpfin/tests/test_financials/test_financial_income.py +++ b/bpfin/tests/test_financials/test_financial_income.py @@ -1,6 +1,6 @@ from bpfin.lib.other import UTILITY_TYPE_LIST from bpfin.tests.testdata import feature_data as db -from bpfin.financials.financial_income import validate_growth_rate_flag +from bpfin.financials.financial_income import validate_growth_rate_flag, Income_Statement_Next def test_validate_growth(): @@ -9,6 +9,36 @@ def test_validate_growth(): for (growth, validation) in zip(input_list, output_list): assert validation == validate_growth_rate_flag(growth) + +def test_Income_Statement_Next(): + characters = { + 'start_year': 2014, + 'end_year': 2016, + 'cagr': 0.05, + 'other_utility_percent': 0.020, # == 2.0% + 'non_utility_expense_percent': 0.035, # == 3.5% + 'revenue_average': 10005.00, + } + annual_bill_table = { + UTILITY_TYPE_LIST[0]: {2014: 1000, 2015: 1000, 2016: 1000, 2017: 1000}, + UTILITY_TYPE_LIST[1]: {2014: 2000, 2015: 2000, 2016: 2000, 2017: 2000}, + UTILITY_TYPE_LIST[2]: {2014: 500, 2015: 500, 2016: 500, 2017: 500}, + UTILITY_TYPE_LIST[3]: {2014: 500, 2015: 500, 2016: 500, 2017: 500}, + } + output_income_statement = Income_Statement_Next( + year = 2017, + last_revenue = 10000, + growth_rate_flag = 1.0, + characters = characters, + annual_bill_table = annual_bill_table, + ) + print('\n next income statament ========= ') + print('\n year = ',output_income_statement.year) + print('\n revenue = ',output_income_statement.revenue) + print('\n noi = ',output_income_statement.noi) + assert 1==1 + + # Income_Statement_Table is tested in test_back_end_call.py # def test_Income_Statement_Table(): # input_raw_income_input = db.raw_income_input -- GitLab From 0619aca8dc50e6efd01a6ff0a9989704732b70df Mon Sep 17 00:00:00 2001 From: chen Date: Wed, 27 Feb 2019 18:09:30 -0500 Subject: [PATCH 2/7] write test files for financial_income.py --- .../test_financials/test_financial_income.py | 174 ++++++++++++++---- 1 file changed, 141 insertions(+), 33 deletions(-) diff --git a/bpfin/tests/test_financials/test_financial_income.py b/bpfin/tests/test_financials/test_financial_income.py index 2fba54f..f61f654 100644 --- a/bpfin/tests/test_financials/test_financial_income.py +++ b/bpfin/tests/test_financials/test_financial_income.py @@ -1,6 +1,7 @@ from bpfin.lib.other import UTILITY_TYPE_LIST +from datetime import date from bpfin.tests.testdata import feature_data as db -from bpfin.financials.financial_income import validate_growth_rate_flag, Income_Statement_Next +from bpfin.financials.financial_income import validate_growth_rate_flag, Income_Statement_Next, Income_Statement_Table, convert_income_statement_class def test_validate_growth(): @@ -10,13 +11,13 @@ def test_validate_growth(): assert validation == validate_growth_rate_flag(growth) -def test_Income_Statement_Next(): +def test_Income_Statement_Next_average(): characters = { 'start_year': 2014, 'end_year': 2016, 'cagr': 0.05, 'other_utility_percent': 0.020, # == 2.0% - 'non_utility_expense_percent': 0.035, # == 3.5% + 'non_utility_expense_percent': 0.15, # == 3.5% 'revenue_average': 10005.00, } annual_bill_table = { @@ -28,40 +29,147 @@ def test_Income_Statement_Next(): output_income_statement = Income_Statement_Next( year = 2017, last_revenue = 10000, - growth_rate_flag = 1.0, + growth_rate_flag = -1, characters = characters, annual_bill_table = annual_bill_table, ) - print('\n next income statament ========= ') - print('\n year = ',output_income_statement.year) - print('\n revenue = ',output_income_statement.revenue) - print('\n noi = ',output_income_statement.noi) - assert 1==1 + output_statement = convert_income_statement_class(output_income_statement) + result_statement = { + 'year': 2017, + 'revenue': 10005.0, + 'utility_expense': 4200.1, + 'energy_opex': 4000, + 'electric_opex': 1000, + 'gas_opex': 2000, + 'oil_opex': 500, + 'water_opex': 500, + 'other_utility': 200.1, + 'non_utility_expense': 1500.75, + 'net_non_energy_opex': 1700.85, + 'total_opex': 5700.85, + 'noi': 4304.15, + } + assert output_statement == result_statement -# Income_Statement_Table is tested in test_back_end_call.py -# 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 -# output_first_year_noi = 33165.377210606544 - -# IS_table = Income_Statement_Table( -# input_raw_income_input, -# input_annual_bill_table, -# db.analysis_date) -# IS_table.project(-1.0, db.bill_overview_organized) +def test_Income_Statement_Table_1(): + raw_income_input = { + 2014: { + 'revenue': 9523.8095238095, + 'utility_expense': 4190.4761904762, + 'non_utility_expense': 1426.5714285714, + }, + 2015: { + 'revenue': 9991.1904761905, + 'utility_expense': 4199.8238095238, + 'non_utility_expense': 1498.6785714286, + }, + 2016: { + 'revenue': 10500.0000000000, + 'utility_expense': 4210.0000000000, + 'non_utility_expense': 1577.0000000000, + } + } + annual_bill_table = { + UTILITY_TYPE_LIST[0]: {2014: 1000, 2015: 1000, 2016: 1000, 2017: 1000, 2018: 1000, 2019: 1000}, + UTILITY_TYPE_LIST[1]: {2014: 2000, 2015: 2000, 2016: 2000, 2017: 2000, 2018: 2000, 2019: 2000}, + UTILITY_TYPE_LIST[2]: {2014: 500, 2015: 500, 2016: 500, 2017: 500, 2018: 500, 2019: 500}, + UTILITY_TYPE_LIST[3]: {2014: 500, 2015: 500, 2016: 500, 2017: 500, 2018: 500, 2019: 500}, + } + output_table = Income_Statement_Table( + raw_income_input=raw_income_input, + annual_bill_table = annual_bill_table, + analysis_date = { + 'proforma_start': date(2014, 1, 1), + 'proforma_duration': 6}, + ) + output_table.project( + growth_rate_flag = 0.02, + annual_bill_table = annual_bill_table, + ) + result_characters = { + 'start_year': 2014, + 'end_year': 2016, + 'cagr': 0.05000000000000138, + 'other_utility_percent': 0.020000000000000007, + 'non_utility_expense_percent': 0.15, + 'revenue_average': 10005.0} + assert output_table.characters == result_characters + result_table_2019 = { + 'electric_opex': 1000, + 'energy_opex': 4000, + 'gas_opex': 2000, + 'net_non_energy_opex': 1894.2562800000003, + 'noi': 5248.427720000001, + 'non_utility_expense': 1671.4026000000001, + 'oil_opex': 500, + 'other_utility': 222.8536800000001, + 'revenue': 11142.684000000001, + 'total_opex': 5894.2562800000005, + 'utility_expense': 4222.85368, + 'water_opex': 500, + 'year': 2019 + } + assert output_table.get_single_year(2019) == result_table_2019 -# 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 -# print(IS_table.get_single_year(2018)) -# assert IS_table.get_first_year_noi(datetime.date(2017, 3, 14)) == output_first_year_noi +def test_Income_Statement_Table_2(): + raw_income_input = { + 2014: { + 'revenue': 9523.8095238095, + 'utility_expense': 4190.4761904762, + 'non_utility_expense': 1426.5714285714, + }, + 2015: { + 'revenue': 9991.1904761905, + 'utility_expense': 4199.8238095238, + 'non_utility_expense': 1498.6785714286, + }, + 2016: { + 'revenue': 10500.0000000000, + 'utility_expense': 4210.0000000000, + 'non_utility_expense': 1577.0000000000, + } + } + annual_bill_table = { + UTILITY_TYPE_LIST[0]: {2014: 1000, 2015: 1000, 2016: 1000, 2017: 1000, 2018: 1000, 2019: 1000}, + UTILITY_TYPE_LIST[1]: {2014: 2000, 2015: 2000, 2016: 2000, 2017: 2000, 2018: 2000, 2019: 2000}, + UTILITY_TYPE_LIST[2]: {2014: 500, 2015: 500, 2016: 500, 2017: 500, 2018: 500, 2019: 500}, + UTILITY_TYPE_LIST[3]: {2014: 500, 2015: 500, 2016: 500, 2017: 500, 2018: 500, 2019: 500}, + } + output_table = Income_Statement_Table( + raw_income_input=raw_income_input, + annual_bill_table = annual_bill_table, + analysis_date = { + 'proforma_start': date(2014, 1, 1), + 'proforma_duration': 6}, + ) + output_table.project( + growth_rate_flag = -2, + annual_bill_table = annual_bill_table, + ) + result_characters = { + 'start_year': 2014, + 'end_year': 2016, + 'cagr': 0.05000000000000138, + 'other_utility_percent': 0.020000000000000007, + 'non_utility_expense_percent': 0.15, + 'revenue_average': 10005.0} + assert output_table.characters == result_characters + result_table_2019 = { + 'year': 2019, + 'revenue': 12155.06250000005, + 'utility_expense': 4243.1012500000015, + 'energy_opex': 4000, + 'electric_opex': 1000, + 'oil_opex': 500, + 'gas_opex': 2000, + 'water_opex': 500, + 'other_utility': 243.10125000000107, + 'non_utility_expense': 1823.2593750000074, + 'net_non_energy_opex': 2066.3606250000084, + 'total_opex': 6066.360625000008, + 'noi': 6088.701875000041, + } + assert output_table.get_single_year(2019) == result_table_2019 +# Income_Statement_Table is also tested in test_back_end_call.py -- GitLab From c0d5d3c4c3d7274e9c5bfc6ca9b44997b80b683f Mon Sep 17 00:00:00 2001 From: chen Date: Wed, 27 Feb 2019 18:10:28 -0500 Subject: [PATCH 3/7] change financial_income growth rate calculation. --- bpfin/financials/financial_income.py | 2 +- bpfin/tests/test_financials/test_financial_income.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bpfin/financials/financial_income.py b/bpfin/financials/financial_income.py index e5d193d..9d6f171 100644 --- a/bpfin/financials/financial_income.py +++ b/bpfin/financials/financial_income.py @@ -167,7 +167,7 @@ class Income_Statement_Next(): 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, ... + growth_rate = growth_rate_flag/100 # growth_rate_flag == 0.00, 1.0, 2.0 ... current_revenue = last_revenue * (1 + growth_rate) self.revenue = current_revenue self.electric_opex = annual_bill_table[UTILITY_TYPE_LIST[0]][self.year] diff --git a/bpfin/tests/test_financials/test_financial_income.py b/bpfin/tests/test_financials/test_financial_income.py index f61f654..89b2e51 100644 --- a/bpfin/tests/test_financials/test_financial_income.py +++ b/bpfin/tests/test_financials/test_financial_income.py @@ -84,7 +84,7 @@ def test_Income_Statement_Table_1(): 'proforma_duration': 6}, ) output_table.project( - growth_rate_flag = 0.02, + growth_rate_flag = 2, annual_bill_table = annual_bill_table, ) result_characters = { -- GitLab From 38b97908087e24b054e837baf0c0c5c9c431a722 Mon Sep 17 00:00:00 2001 From: chen Date: Wed, 27 Feb 2019 18:12:35 -0500 Subject: [PATCH 4/7] update bpfin v0.2.4 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index ac4123d..135817d 100644 --- a/setup.py +++ b/setup.py @@ -12,7 +12,7 @@ reqs = [str(req.req) for req in install_reqs] setup( name='bpfin', - version='0.2.3', + version='0.2.4', description='Finance models and utilites', author='BlocPower', author_email='admin@blocpower.org', -- GitLab From aa52407261163198118fc7d1a1b190b55af50cb7 Mon Sep 17 00:00:00 2001 From: chen Date: Fri, 1 Mar 2019 12:16:47 -0500 Subject: [PATCH 5/7] remove a wrong function get_utility_opex_dict() from financial_income. --- bpfin/financials/financial_income.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/bpfin/financials/financial_income.py b/bpfin/financials/financial_income.py index 9d6f171..ef3c8b2 100644 --- a/bpfin/financials/financial_income.py +++ b/bpfin/financials/financial_income.py @@ -478,15 +478,6 @@ class Income_Statement_Table(): total_energy_dict[year] += self.annual_bill_table[utility][year] return total_energy_dict - # what is this??? no description, and it calls wrong attribute - # def get_utility_opex_dict(self, energy_utility_opex): - # bill_dict = {} - # for current_income_statement in self.table: - # bill_dict[current_income_statement. - # year] = current_income_statement.energy_utility_opex - - # return bill_dict - def validate_growth_rate_flag(growth_rate_flag): """ -- GitLab From 4337f598362428fe07bfe48003a6b46334f1818c Mon Sep 17 00:00:00 2001 From: chen Date: Fri, 1 Mar 2019 12:22:09 -0500 Subject: [PATCH 6/7] move loan ugly test to test_loan --- bpfin/financials/loan.py | 10 ---------- bpfin/tests/test_financials/test_loan.py | 11 +++++++++++ 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/bpfin/financials/loan.py b/bpfin/financials/loan.py index 3273712..7f81b87 100644 --- a/bpfin/financials/loan.py +++ b/bpfin/financials/loan.py @@ -207,13 +207,3 @@ class Loan_List(): def get_downpayment(self): return self.downpayment - -# ****** ugly tests Loan and Loan_List class ********** -# loan_list = Loan_List(db.loan_input_list) -# allocated = loan_list.get_schedule( -# db.customer_preference, -# db.scenario, -# db.req_dscr, -# datetime.date(2017, 1, 12)) -# print(allocated[0].terms) -# print(allocated[0].principal_end_balance) diff --git a/bpfin/tests/test_financials/test_loan.py b/bpfin/tests/test_financials/test_loan.py index cbfa0a0..ed43dd8 100644 --- a/bpfin/tests/test_financials/test_loan.py +++ b/bpfin/tests/test_financials/test_loan.py @@ -24,3 +24,14 @@ def test_Loan_List(): 28000.0, 100000.0) assert output_loan1_end_balance == result_loan_list[0].principal_end_balance + + +# ****** ugly tests Loan and Loan_List class ********** +# loan_list = Loan_List(db.loan_input_list) +# allocated = loan_list.get_schedule( +# db.customer_preference, +# db.scenario, +# db.req_dscr, +# datetime.date(2017, 1, 12)) +# print(allocated[0].terms) +# print(allocated[0].principal_end_balance) -- GitLab From adaf5b192a438e84d2cbfe065a030a47af3f07b6 Mon Sep 17 00:00:00 2001 From: chen Date: Fri, 1 Mar 2019 12:28:27 -0500 Subject: [PATCH 7/7] update ugly test case --- bpfin/tests/test_financials/test_loan.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/bpfin/tests/test_financials/test_loan.py b/bpfin/tests/test_financials/test_loan.py index c403a62..4fbcb01 100644 --- a/bpfin/tests/test_financials/test_loan.py +++ b/bpfin/tests/test_financials/test_loan.py @@ -100,11 +100,15 @@ def test_Loan_List_2(): # ****** ugly tests Loan and Loan_List class ********** -# loan_list = Loan_List(db.loan_input_list) +# loan_list = Loan_List(db.raw_loan_input_list) # allocated = loan_list.get_schedule( # db.customer_preference, -# db.scenario, +# db.cost_estimation, # db.req_dscr, -# datetime.date(2017, 1, 12)) +# datetime.date(2017, 1, 12), +# 28000.0, +# 28000.0, +# 100000.0 +# ) # print(allocated[0].terms) # print(allocated[0].principal_end_balance) -- GitLab