From cbe31d72417e4469fa8885e1f20a5d598d7d961e Mon Sep 17 00:00:00 2001 From: Sarey Hamarneh Date: Mon, 15 May 2017 13:15:20 -0400 Subject: [PATCH 01/10] Push changes for cash balance test --- bpfin/financials/cash_balance.py | 3 +-- bpfin/tests/test_financials/test_cash_balance.py | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/bpfin/financials/cash_balance.py b/bpfin/financials/cash_balance.py index 6b43215..1076083 100644 --- a/bpfin/financials/cash_balance.py +++ b/bpfin/financials/cash_balance.py @@ -38,8 +38,7 @@ def cash_balance(analysis_date, cash_dictionary): if year in cash_balance_dictionary: final_dict[year] = cash_balance_dictionary[year] if year < min(cash_balance_dictionary): - min_value = min(cash_balance_dictionary) - final_dict[year] = cash_balance_dictionary[min_value] + final_dict[year] = cash_average if year > min(cash_balance_dictionary) and year < max(cash_balance_dictionary): if year not in cash_balance_dictionary: final_dict[year] = cash_average diff --git a/bpfin/tests/test_financials/test_cash_balance.py b/bpfin/tests/test_financials/test_cash_balance.py index 2f27f7b..cddafb8 100644 --- a/bpfin/tests/test_financials/test_cash_balance.py +++ b/bpfin/tests/test_financials/test_cash_balance.py @@ -29,8 +29,8 @@ def test_cash_balance(): input_dictionary = { date(2014, 11, 1): (500, False), date(2015, 12, 31): (600, True), - date(2016, 11, 11): (500, False), - date(2016, 10, 10): (400, False) + date(2016, 11, 11): (300, False), + date(2016, 10, 10): (500, False) } input_analysis_date = { 'proforma_start': date(2006, 5, 3), @@ -47,7 +47,7 @@ def test_cash_balance(): 2013: 500, 2014: 500.0, 2015: 600, - 2016: 450.0 + 2016: 400.0 } result = cash_balance(input_analysis_date, input_dictionary) -- GitLab From 607a16f8a83e56ca82348ff545bf25205b6ec69b Mon Sep 17 00:00:00 2001 From: Sarey Hamarneh Date: Wed, 31 May 2017 14:39:52 -0400 Subject: [PATCH 02/10] Fixed balance sheet --- bpfin/financials/financial_balance.py | 149 ++++++++++++++++++++++++++ bpfin/financials/financial_lib.py | 144 ------------------------- 2 files changed, 149 insertions(+), 144 deletions(-) create mode 100644 bpfin/financials/financial_balance.py diff --git a/bpfin/financials/financial_balance.py b/bpfin/financials/financial_balance.py new file mode 100644 index 0000000..b33ecc3 --- /dev/null +++ b/bpfin/financials/financial_balance.py @@ -0,0 +1,149 @@ +import copy +from bpfin.lib import other as lib +from bpfin.utilbills.bill_lib import form_bill_year +from numpy import mean + + +class Balance_Sheet(): + def __init__(self): + self.year = None + self.cash = None + # self.current_assets = None + # self.fixed_assets = None + self.other_debt_service = None + # self.current_liabilities = None + # self.fixed_liablities = None + # self.bop_equity = None + # self.cap_holdings = None + self.net_income = None + # self.eop_equity = None + + def put_hist_balance_sheet(self, year, cash, other_debt_service, net_income): + """Put historical data values into balance sheet based on the cash balance years. + Args: + year (int): year + balance_sheet_input (dictionary): dictionary of balance sheet items: cash, noi, debt_service + Returns: + dictionary: filled in balance sheet + """ + self.year = year + self.cash = cash + self.other_debt_service = other_debt_service + self.net_income = net_income + + +def convert_balance_sheet_class(balance_sheet_class): + balance_sheet_dict = { + 'year': balance_sheet_class.year, + 'cash': balance_sheet_class.cash, + 'other_debt_service': balance_sheet_class.other_debt_service, + 'net_income': balance_sheet_class.net_income + } + return balance_sheet_dict + + +class Balance_Sheet_Next(): + def __init__(self, year, last_year_cash, other_debt_service, net_income): + + self.year = year + self.other_debt_service = other_debt_service + self.net_income = net_income + self.cash = last_year_cash - self.other_debt_service + self.net_income + + +class Balance_Sheet_Table(): + def __init__(self, liability, other_debt_service, cash_balance, net_income): + + self.hist_start_year = None + self.hist_end_year = None + self.hist_balance_sheet_table = [] + self.bs_table = [] + # entire table, not just historical + + for year in cash_balance: + + current_balance_sheet = Balance_Sheet() + current_balance_sheet.put_hist_balance_sheet( + year, cash_balance, other_debt_service, net_income) + self.hist_balance_sheet_table.append(current_balance_sheet) + + sorted_balance_sheet_hist_year = sorted(cash_balance) + self.hist_start_year = sorted_balance_sheet_hist_year[0] + self.hist_end_year = sorted_balance_sheet_hist_year[-1] + + self.bs_table = self.hist_balance_sheet_table + + def project_balance_sheet(self, analysis_date, other_debt_service, + net_income_dictionary): + """Create balance sheet projection. + Args: + analysis_date (dict): {pro_forma date: duration (years)} + other_debt_service (dict): dictionary of debt service values per year + net_income_dictionary (dict): dictionary of net income values per years + Returns: + dictionary: full dictionary of dictionaries of balance sheet entries + """ + + proforma_year = form_bill_year(analysis_date['proforma_start'], + analysis_date['proforma_duration']) + current_table = copy.deepcopy(self.hist_balance_sheet_table) + for year in proforma_year: + last_year_cash = current_table[-1].cash + if year <= current_table[-1].year: + continue + current_other_debt_service = 0.00 + current_net_income = 0.00 + if year in other_debt_service: + current_other_debt_service = other_debt_service[year] + if year in net_income_dictionary: + current_net_income = net_income_dictionary[year] + current_balance_sheet = Balance_Sheet_Next( + year, last_year_cash, current_other_debt_service, + current_net_income) + current_table.append(current_balance_sheet) + self.bs_table = current_table + # return current_table + + def get_hist_balance_sheet_table(self): + hist_balance_sheet_dict = {} + for current_balance_sheet in self.hist_balance_sheet_table: + hist_balance_sheet_dict[current_balance_sheet.year] = { + 'other_debt_service': current_balance_sheet.other_debt_service, + 'net_income': current_balance_sheet.net_income, + 'cash': current_balance_sheet.cash + } + return hist_balance_sheet_dict + + def get_single_year_balance_sheet(self, year): + + for current_balance_sheet in self.bs_table: + if current_balance_sheet.year == year: + return { + current_balance_sheet.year: { + 'other_debt_service': + current_balance_sheet.other_debt_service, + 'net_income': + current_balance_sheet.net_income, + 'cash': + current_balance_sheet.cash + } + } + return None + + def get_first_year_cash(self, commission_date): + + first_year = commission_date.year+1 + for current_balance_sheet in self.bs_table: + if current_balance_sheet.year == first_year: + return current_balance_sheet.cash + + def get_cash_dict(self): + """ + Get a dictionary of cash. + Return: + dictionary: cash for each year in balance sheet table. Key is year + """ + cash_dict = {} + for current_balance_sheet in self.bs_table: + cash_dict[current_balance_sheet.year] = current_balance_sheet.cash + return cash_dict diff --git a/bpfin/financials/financial_lib.py b/bpfin/financials/financial_lib.py index 253c1ec..726fa09 100644 --- a/bpfin/financials/financial_lib.py +++ b/bpfin/financials/financial_lib.py @@ -533,150 +533,6 @@ class Income_Statement_Table(): return total_energy_dict -class Balance_Sheet(): - def __init__(self): - self.year = None - self.cash = None - # self.current_assets = None - # self.fixed_assets = None - self.other_debt_service = None - # self.current_liabilities = None - # self.fixed_liablities = None - # self.bop_equity = None - # self.cap_holdings = None - self.net_income = None - # self.eop_equity = None - - def put_hist_balance_sheet(self, year, balance_sheet_input): - """Put historical data values into balance sheet based on the cash balance years. - Args: - year (int): year - balance_sheet_input (dictionary): dictionary of balance sheet items: cash, noi, debt_service - Returns: - dictionary: filled in balance sheet - """ - self.year = year - self.cash = balance_sheet_input['cash'][year] - self.other_debt_service = balance_sheet_input['other_debt_service'][ - year] - self.net_income = balance_sheet_input['net_income'][year] - - -def convert_balance_sheet_class(balance_sheet_class): - balance_sheet_dict = { - 'year': balance_sheet_class.year, - 'cash': balance_sheet_class.cash, - 'other_debt_service': balance_sheet_class.other_debt_service, - 'net_income': balance_sheet_class.net_income - } - return balance_sheet_dict - - -class Balance_Sheet_Next(): - def __init__(self, year, last_year_cash, other_debt_service, net_income): - - self.year = year - self.other_debt_service = other_debt_service - self.net_income = net_income - self.cash = last_year_cash - self.other_debt_service + self.net_income - - -class Balance_Sheet_Table(): - def __init__(self, balance_sheet_input): - - self.hist_start_year = None - self.hist_end_year = None - self.hist_balance_sheet_table = [] - self.bs_table = [] - # entire table, not just historical - - for year in balance_sheet_input['cash']: - - current_balance_sheet = Balance_Sheet() - current_balance_sheet.put_hist_balance_sheet( - year, balance_sheet_input) - self.hist_balance_sheet_table.append(current_balance_sheet) - - sorted_balance_sheet_hist_year = sorted(balance_sheet_input['cash']) - self.hist_start_year = sorted_balance_sheet_hist_year[0] - self.hist_end_year = sorted_balance_sheet_hist_year[-1] - - self.bs_table = self.hist_balance_sheet_table - - def project_balance_sheet(self, analysis_date, other_debt_service, - net_income_dictionary): - """Create balance sheet projection. - Args: - analysis_date (dict): {pro_forma date: duration (years)} - other_debt_service (dict): dictionary of debt service values per year - net_income_dictionary (dict): dictionary of net income values per years - Returns: - dictionary: full dictionary of dictionaries of balance sheet entries - """ - - proforma_year = form_bill_year(analysis_date['proforma_start'], - analysis_date['proforma_duration']) - current_table = copy.deepcopy(self.hist_balance_sheet_table) - for year in proforma_year: - last_year_cash = current_table[-1].cash - if year <= current_table[-1].year: - continue - current_other_debt_service = 0.00 - current_net_income = 0.00 - if year in other_debt_service: - current_other_debt_service = other_debt_service[year] - if year in net_income_dictionary: - current_net_income = net_income_dictionary[year] - current_balance_sheet = Balance_Sheet_Next( - year, last_year_cash, current_other_debt_service, - current_net_income) - current_table.append(current_balance_sheet) - self.bs_table = current_table - # return current_table - - def get_hist_balance_sheet_table(self): - hist_balance_sheet_dict = {} - for current_balance_sheet in self.hist_balance_sheet_table: - hist_balance_sheet_dict[current_balance_sheet.year] = { - 'other_debt_service': current_balance_sheet.other_debt_service, - 'net_income': current_balance_sheet.net_income, - 'cash': current_balance_sheet.cash - } - return hist_balance_sheet_dict - - def get_single_year_balance_sheet(self, year): - - for current_balance_sheet in self.bs_table: - if current_balance_sheet.year == year: - return { - current_balance_sheet.year: { - 'other_debt_service': - current_balance_sheet.other_debt_service, - 'net_income': - current_balance_sheet.net_income, - 'cash': - current_balance_sheet.cash - } - } - return None - - def get_first_year_cash(self, commission_date): - - first_year = commission_date.year+1 - for current_balance_sheet in self.bs_table: - if current_balance_sheet.year == first_year: - return current_balance_sheet.cash - - def get_cash_dict(self): - """ - Get a dictionary of cash. - Return: - dictionary: cash for each year in balance sheet table. Key is year - """ - cash_dict = {} - for current_balance_sheet in self.bs_table: - cash_dict[current_balance_sheet.year] = current_balance_sheet.cash - return cash_dict # # ************ guide for front end dev *********** # # First, fill in bill overview, save it. -- GitLab From e6a5b65aa2ce8e568b0050e0763a017838e1e350 Mon Sep 17 00:00:00 2001 From: Sarey Hamarneh Date: Wed, 31 May 2017 16:57:50 -0400 Subject: [PATCH 03/10] Changes --- bpfin/financials/financial_balance.py | 2 +- .../test_financials/test_financial_balance.py | 29 +++++++++++++++++++ .../test_financials/test_financial_lib.py | 25 ---------------- bpfin/tests/testdata/sample_data.py | 10 +++++++ 4 files changed, 40 insertions(+), 26 deletions(-) create mode 100644 bpfin/tests/test_financials/test_financial_balance.py diff --git a/bpfin/financials/financial_balance.py b/bpfin/financials/financial_balance.py index b33ecc3..1477707 100644 --- a/bpfin/financials/financial_balance.py +++ b/bpfin/financials/financial_balance.py @@ -52,7 +52,7 @@ class Balance_Sheet_Next(): class Balance_Sheet_Table(): - def __init__(self, liability, other_debt_service, cash_balance, net_income): + def __init__(self, cash_balance, other_debt_service, net_income): self.hist_start_year = None self.hist_end_year = None diff --git a/bpfin/tests/test_financials/test_financial_balance.py b/bpfin/tests/test_financials/test_financial_balance.py new file mode 100644 index 0000000..eebffa3 --- /dev/null +++ b/bpfin/tests/test_financials/test_financial_balance.py @@ -0,0 +1,29 @@ +from bpfin.financials.financial_balance import Balance_Sheet_Table +from bpfin.tests.testdata import sample_data as db + + +def test_Balance_Sheet_Table(): + input_raw_cash_balance = db.cash_balance + input_raw_other_debt_service = db.liability_dictionary + input_raw_net_income = db.noi_dictionary + + output_hist_balance_sheet_table = db.hist_balance_sheet + # output_single_year_bs_2018 = db.balance_sheet_2018 + # output_single_year_bs_2025 = db.balance_sheet_2025 + # output_single_year_bs_2030 = db.balance_sheet_2030 + # output_first_year_cash = db.hist_balance_sheet[2016]['cash'] + + BS_table = Balance_Sheet_Table(input_raw_cash_balance, input_raw_other_debt_service, input_raw_net_income) + + BS_table.project_balance_sheet(db.analysis_date, db.liability_dictionary, + db.noi_dictionary) + + assert BS_table.get_hist_balance_sheet_table == output_hist_balance_sheet_table + # assert BS_table.get_single_year_balance_sheet( + # 2018) == output_single_year_bs_2018 + # assert BS_table.get_single_year_balance_sheet( + # 2025) == output_single_year_bs_2025 + # assert BS_table.get_single_year_balance_sheet( + # 2030) == output_single_year_bs_2030 + # assert BS_table.get_first_year_cash( + # datetime.date(2015, 10, 1)) == output_first_year_cash diff --git a/bpfin/tests/test_financials/test_financial_lib.py b/bpfin/tests/test_financials/test_financial_lib.py index e24e1b6..8d5f6ec 100644 --- a/bpfin/tests/test_financials/test_financial_lib.py +++ b/bpfin/tests/test_financials/test_financial_lib.py @@ -2,7 +2,6 @@ import datetime import bpfin.financials.financial_lib as fl from bpfin.tests.testdata import sample_data as db from bpfin.financials.financial_lib import Income_Statement_Table -from bpfin.financials.financial_lib import Balance_Sheet_Table def test_organize_bill_overview(): @@ -38,27 +37,3 @@ def test_Income_Statement_Table(): 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_Balance_Sheet_Table(): - input_raw_balance_sheet = db.raw_balance_sheet - output_hist_balance_sheet_table = db.hist_balance_sheet - output_single_year_bs_2018 = db.balance_sheet_2018 - output_single_year_bs_2025 = db.balance_sheet_2025 - output_single_year_bs_2030 = db.balance_sheet_2030 - output_first_year_cash = db.hist_balance_sheet[2016]['cash'] - - BS_table = Balance_Sheet_Table(input_raw_balance_sheet) - BS_table.project_balance_sheet(db.analysis_date, db.liability_dictionary, - db.noi_dictionary) - - assert BS_table.get_hist_balance_sheet_table( - ) == output_hist_balance_sheet_table - assert BS_table.get_single_year_balance_sheet( - 2018) == output_single_year_bs_2018 - assert BS_table.get_single_year_balance_sheet( - 2025) == output_single_year_bs_2025 - assert BS_table.get_single_year_balance_sheet( - 2030) == output_single_year_bs_2030 - assert BS_table.get_first_year_cash( - datetime.date(2015, 10, 1)) == output_first_year_cash diff --git a/bpfin/tests/testdata/sample_data.py b/bpfin/tests/testdata/sample_data.py index 4a86f35..25ddfe0 100644 --- a/bpfin/tests/testdata/sample_data.py +++ b/bpfin/tests/testdata/sample_data.py @@ -3026,3 +3026,13 @@ raw_income_input_demo = {2014: {'total_revenue': 200000, 'other_utility_expenses raw_balance_sheet_demo = {2014: {'cash': 60000, 'other_debt_service': 1000, 'noi': 18000}, 2015: {'cash': 62000, 'other_debt_service': 1000, 'noi': 14600}, 2016: {'cash': 52000, 'other_debt_service': 1000, 'noi': -3100}} + +liability_dictionary = { + 2012: 650, + 2013: 2550, + 2014: 100, + 2015: 6000, + 2016: 15000, + 2017: 10000, + 2018: 5000 + } -- GitLab From 8213ee5df42832a21a5728bf8714baf19eac264f Mon Sep 17 00:00:00 2001 From: Sarey Hamarneh Date: Wed, 31 May 2017 23:29:31 -0400 Subject: [PATCH 04/10] Finalize balance sheet --- bpfin/financials/financial_balance.py | 38 ++++++++++++++----- .../test_financials/test_financial_balance.py | 23 +++++------ 2 files changed, 38 insertions(+), 23 deletions(-) diff --git a/bpfin/financials/financial_balance.py b/bpfin/financials/financial_balance.py index 1477707..4898d09 100644 --- a/bpfin/financials/financial_balance.py +++ b/bpfin/financials/financial_balance.py @@ -22,9 +22,11 @@ class Balance_Sheet(): """Put historical data values into balance sheet based on the cash balance years. Args: year (int): year - balance_sheet_input (dictionary): dictionary of balance sheet items: cash, noi, debt_service + cash (float): cash value + other_debt_service (float): other debt service value + net_income (float): net income value Returns: - dictionary: filled in balance sheet + dictionary: filled in historical balance sheet """ self.year = year self.cash = cash @@ -44,6 +46,13 @@ def convert_balance_sheet_class(balance_sheet_class): class Balance_Sheet_Next(): def __init__(self, year, last_year_cash, other_debt_service, net_income): + """Create next year value of balance sheet + Args: + year (int): + last_year_cash (float): cash + other_debt_service (float): liability + net_income (float): net income + """ self.year = year self.other_debt_service = other_debt_service @@ -52,7 +61,16 @@ class Balance_Sheet_Next(): class Balance_Sheet_Table(): - def __init__(self, cash_balance, other_debt_service, net_income): + def __init__(self, cash_balance_dictionary, other_debt_service_dictionary, net_income_dictionary): + """Put historical data values into balance sheet based on the cash balance years. + Args: + year (int): year + cash_balance_dictionary (dict): dictionary of annual cash value items, key is year + other_debt_service_dictionary (dict): dictionary of annual liability value items, key is year + net_income_dictionary (dict): dictionary of annual liability value items, key is year + Returns: + dictionary: filled in historical balance sheet + """ self.hist_start_year = None self.hist_end_year = None @@ -60,25 +78,25 @@ class Balance_Sheet_Table(): self.bs_table = [] # entire table, not just historical - for year in cash_balance: + for year in cash_balance_dictionary: current_balance_sheet = Balance_Sheet() current_balance_sheet.put_hist_balance_sheet( - year, cash_balance, other_debt_service, net_income) + year, cash_balance_dictionary[year], other_debt_service_dictionary[year], net_income_dictionary[year]) self.hist_balance_sheet_table.append(current_balance_sheet) - sorted_balance_sheet_hist_year = sorted(cash_balance) + sorted_balance_sheet_hist_year = sorted(cash_balance_dictionary) self.hist_start_year = sorted_balance_sheet_hist_year[0] self.hist_end_year = sorted_balance_sheet_hist_year[-1] self.bs_table = self.hist_balance_sheet_table - def project_balance_sheet(self, analysis_date, other_debt_service, + def project_balance_sheet(self, analysis_date, other_debt_service_dictionary, net_income_dictionary): """Create balance sheet projection. Args: analysis_date (dict): {pro_forma date: duration (years)} - other_debt_service (dict): dictionary of debt service values per year + other_debt_service_dictionary (dict): dictionary of debt service values per year net_income_dictionary (dict): dictionary of net income values per years Returns: dictionary: full dictionary of dictionaries of balance sheet entries @@ -93,8 +111,8 @@ class Balance_Sheet_Table(): continue current_other_debt_service = 0.00 current_net_income = 0.00 - if year in other_debt_service: - current_other_debt_service = other_debt_service[year] + if year in other_debt_service_dictionary: + current_other_debt_service = other_debt_service_dictionary[year] if year in net_income_dictionary: current_net_income = net_income_dictionary[year] current_balance_sheet = Balance_Sheet_Next( diff --git a/bpfin/tests/test_financials/test_financial_balance.py b/bpfin/tests/test_financials/test_financial_balance.py index eebffa3..97e5407 100644 --- a/bpfin/tests/test_financials/test_financial_balance.py +++ b/bpfin/tests/test_financials/test_financial_balance.py @@ -1,5 +1,6 @@ from bpfin.financials.financial_balance import Balance_Sheet_Table from bpfin.tests.testdata import sample_data as db +from datetime import datetime, date def test_Balance_Sheet_Table(): @@ -8,22 +9,18 @@ def test_Balance_Sheet_Table(): input_raw_net_income = db.noi_dictionary output_hist_balance_sheet_table = db.hist_balance_sheet - # output_single_year_bs_2018 = db.balance_sheet_2018 - # output_single_year_bs_2025 = db.balance_sheet_2025 - # output_single_year_bs_2030 = db.balance_sheet_2030 - # output_first_year_cash = db.hist_balance_sheet[2016]['cash'] + output_single_year_bs_2018 = db.balance_sheet_2018 + output_single_year_bs_2025 = db.balance_sheet_2025 + output_single_year_bs_2030 = db.balance_sheet_2030 + output_first_year_cash = db.hist_balance_sheet[2016]['cash'] BS_table = Balance_Sheet_Table(input_raw_cash_balance, input_raw_other_debt_service, input_raw_net_income) BS_table.project_balance_sheet(db.analysis_date, db.liability_dictionary, db.noi_dictionary) - assert BS_table.get_hist_balance_sheet_table == output_hist_balance_sheet_table - # assert BS_table.get_single_year_balance_sheet( - # 2018) == output_single_year_bs_2018 - # assert BS_table.get_single_year_balance_sheet( - # 2025) == output_single_year_bs_2025 - # assert BS_table.get_single_year_balance_sheet( - # 2030) == output_single_year_bs_2030 - # assert BS_table.get_first_year_cash( - # datetime.date(2015, 10, 1)) == output_first_year_cash + assert BS_table.get_hist_balance_sheet_table() == output_hist_balance_sheet_table + assert BS_table.get_single_year_balance_sheet(2018) == output_single_year_bs_2018 + assert BS_table.get_single_year_balance_sheet(2025) == output_single_year_bs_2025 + assert BS_table.get_single_year_balance_sheet(2030) == output_single_year_bs_2030 + assert BS_table.get_first_year_cash(datetime(2015, 10, 1)) == output_first_year_cash -- GitLab From 59433e4c6be5ec171f621fe27833b560dbc2428a Mon Sep 17 00:00:00 2001 From: chenzheng06 Date: Thu, 1 Jun 2017 00:33:12 -0400 Subject: [PATCH 05/10] Activate cash_balance_year_gap test file --- .../test_financials/test_cash_balance.py | 43 ++++++++++--------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/bpfin/tests/test_financials/test_cash_balance.py b/bpfin/tests/test_financials/test_cash_balance.py index 44a0f90..7037a66 100644 --- a/bpfin/tests/test_financials/test_cash_balance.py +++ b/bpfin/tests/test_financials/test_cash_balance.py @@ -2,27 +2,28 @@ from bpfin.financials.cash_balance import cash_balance from datetime import date -# def test_cash_balance_year_gap(): -# input_dictionary = { -# date(2014, 11, 1): (500, False), -# date(2014, 12, 1): (400, False), -# date(2014, 3, 13): (600, False), -# date(2016, 11, 11): (500, False), -# date(2016, 12, 31): (400, True) -# } -# input_analysis_date = { -# 'proforma_start': date(2012, 5, 3), -# 'proforma_duration': 12 -# } -# output_cash_balance = { -# 2012: 450, -# 2013: 450, -# 2014: 500, -# 2015: 450, -# 2016: 400 -# } -# result = cash_balance(input_analysis_date, input_dictionary) -# assert result == output_cash_balance +def test_cash_balance_year_gap(): + input_dictionary = { + date(2014, 11, 1): (500, False), + date(2014, 12, 1): (400, False), + date(2014, 3, 13): (600, False), + date(2016, 11, 11): (500, False), + date(2016, 12, 31): (400, True) + } + input_analysis_date = { + 'proforma_start': date(2012, 5, 3), + 'proforma_duration': 12 + } + output_cash_balance = { + 2012: 450, + 2013: 450, + 2014: 500, + 2015: 450, + 2016: 400 + } + result = cash_balance(input_analysis_date, input_dictionary) + assert result == output_cash_balance + def test_cash_balance(): input_dictionary = { -- GitLab From 66b691bd7c29fb445743c1a1e5754e7c9c851560 Mon Sep 17 00:00:00 2001 From: Sarey Hamarneh Date: Thu, 1 Jun 2017 00:47:35 -0400 Subject: [PATCH 06/10] push changes according to chen comments --- bpfin/financials/financial_balance.py | 31 +++++++++++++++++---------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/bpfin/financials/financial_balance.py b/bpfin/financials/financial_balance.py index 4898d09..8dfab47 100644 --- a/bpfin/financials/financial_balance.py +++ b/bpfin/financials/financial_balance.py @@ -18,7 +18,8 @@ class Balance_Sheet(): self.net_income = None # self.eop_equity = None - def put_hist_balance_sheet(self, year, cash, other_debt_service, net_income): + def put_hist_balance_sheet(self, year, cash, other_debt_service, + net_income): """Put historical data values into balance sheet based on the cash balance years. Args: year (int): year @@ -61,15 +62,14 @@ class Balance_Sheet_Next(): class Balance_Sheet_Table(): - def __init__(self, cash_balance_dictionary, other_debt_service_dictionary, net_income_dictionary): + def __init__(self, cash_balance_dictionary, other_debt_service_dictionary, + net_income_dictionary): """Put historical data values into balance sheet based on the cash balance years. Args: year (int): year cash_balance_dictionary (dict): dictionary of annual cash value items, key is year other_debt_service_dictionary (dict): dictionary of annual liability value items, key is year net_income_dictionary (dict): dictionary of annual liability value items, key is year - Returns: - dictionary: filled in historical balance sheet """ self.hist_start_year = None @@ -79,11 +79,18 @@ class Balance_Sheet_Table(): # entire table, not just historical for year in cash_balance_dictionary: - current_balance_sheet = Balance_Sheet() - current_balance_sheet.put_hist_balance_sheet( - year, cash_balance_dictionary[year], other_debt_service_dictionary[year], net_income_dictionary[year]) - self.hist_balance_sheet_table.append(current_balance_sheet) + if year in net_income_dictionary: + current_balance_sheet.put_hist_balance_sheet( + year, cash_balance_dictionary[year], + other_debt_service_dictionary[year], + net_income_dictionary[year]) + self.hist_balance_sheet_table.append(current_balance_sheet) + if year not in net_income_dictionary: + current_balance_sheet.put_hist_balance_sheet( + year, cash_balance_dictionary[year], + other_debt_service_dictionary[year], None) + self.hist_balance_sheet_table.append(current_balance_sheet) sorted_balance_sheet_hist_year = sorted(cash_balance_dictionary) self.hist_start_year = sorted_balance_sheet_hist_year[0] @@ -91,7 +98,8 @@ class Balance_Sheet_Table(): self.bs_table = self.hist_balance_sheet_table - def project_balance_sheet(self, analysis_date, other_debt_service_dictionary, + def project_balance_sheet(self, analysis_date, + other_debt_service_dictionary, net_income_dictionary): """Create balance sheet projection. Args: @@ -112,7 +120,8 @@ class Balance_Sheet_Table(): current_other_debt_service = 0.00 current_net_income = 0.00 if year in other_debt_service_dictionary: - current_other_debt_service = other_debt_service_dictionary[year] + current_other_debt_service = other_debt_service_dictionary[ + year] if year in net_income_dictionary: current_net_income = net_income_dictionary[year] current_balance_sheet = Balance_Sheet_Next( @@ -150,7 +159,7 @@ class Balance_Sheet_Table(): def get_first_year_cash(self, commission_date): - first_year = commission_date.year+1 + first_year = commission_date.year + 1 for current_balance_sheet in self.bs_table: if current_balance_sheet.year == first_year: return current_balance_sheet.cash -- GitLab From 0814df6de198bb7b35d51fb7ee063365b2986743 Mon Sep 17 00:00:00 2001 From: Sarey Hamarneh Date: Thu, 1 Jun 2017 09:56:13 -0400 Subject: [PATCH 07/10] Push --- bpfin/financials/liability.py | 79 +++++++------ .../test_financials/test_cash_balance.py | 43 +++---- bpfin/tests/test_financials/test_liability.py | 105 +++++++++++++++++- 3 files changed, 160 insertions(+), 67 deletions(-) diff --git a/bpfin/financials/liability.py b/bpfin/financials/liability.py index 70cf1c6..642df73 100644 --- a/bpfin/financials/liability.py +++ b/bpfin/financials/liability.py @@ -69,7 +69,7 @@ def create_liability_dict(liability_dictionary): return final_dict -def final_liability_dict(start_date, liability_dictionary, months): +def final_liability_dict(analysis_date, liability_dictionary): """Create dictionary of {(year,month):debt value}, which includes all debts Args: start_date (datetime): first date of the dictionary @@ -78,46 +78,45 @@ def final_liability_dict(start_date, liability_dictionary, months): Return: dictionary: {(year,month):debt value} """ - if liability_dictionary: - final_dict = {} - pro_forma_calendar = liability_calendar(start_date, months) - debt_list = create_liability_dict(liability_dictionary) - for pro_date in pro_forma_calendar: - for debt_date_dict in debt_list: - for debt_date in debt_date_dict: - if pro_date.year == debt_date.year and pro_date.month == debt_date.month: - if (pro_date.year, pro_date.month, calendar.monthrange( - pro_date.year, - pro_date.month)[1]) not in final_dict: - final_dict[( - pro_date.year, pro_date.month, calendar.monthrange( - pro_date.year, pro_date.month)[1])] = [] - final_dict[(pro_date.year, - pro_date.month, - calendar.monthrange( - pro_date.year, - pro_date.month)[1] - )].append(debt_date_dict[debt_date]) - for pro_date in pro_forma_calendar: - if (pro_date.year, pro_date.month, calendar.monthrange( - pro_date.year, pro_date.month)[1]) not in final_dict: - final_dict[(pro_date.year, pro_date.month, calendar.monthrange( - pro_date.year, pro_date.month)[1])] = [0] + final_dict = {} + pro_forma_calendar = liability_calendar( + analysis_date['proforma_start'], + analysis_date['proforma_duration'] * 12) + debt_list = create_liability_dict(liability_dictionary) + for pro_date in pro_forma_calendar: + for debt_date_dict in debt_list: + for debt_date in debt_date_dict: + if pro_date.year == debt_date.year and pro_date.month == debt_date.month: + if (pro_date.year, pro_date.month, calendar.monthrange( + pro_date.year, + pro_date.month)[1]) not in final_dict: + final_dict[( + pro_date.year, pro_date.month, calendar.monthrange( + pro_date.year, pro_date.month)[1])] = [] + final_dict[(pro_date.year, + pro_date.month, calendar.monthrange( + pro_date.year, pro_date.month)[1] + )].append(debt_date_dict[debt_date]) + for pro_date in pro_forma_calendar: + if (pro_date.year, pro_date.month, calendar.monthrange( + pro_date.year, pro_date.month)[1]) not in final_dict: + final_dict[(pro_date.year, pro_date.month, calendar.monthrange( + pro_date.year, pro_date.month)[1])] = [0] - for key, value in final_dict.items(): - final_dict[key] = sum(value) + for key, value in final_dict.items(): + final_dict[key] = sum(value) - real_dict = {} - for key, value in final_dict.items(): - real_dict[datetime(key[0], key[1], key[2])] = value + real_dict = {} + for key, value in final_dict.items(): + real_dict[datetime(key[0], key[1], key[2])] = value - annual_liability_dict = {} - for full_date, liability in real_dict.items(): - if full_date.year not in annual_liability_dict: - annual_liability_dict[full_date.year] = [] - annual_liability_dict[full_date.year].append(liability) - sum_dict = {} - for year, value in annual_liability_dict.items(): - sum_dict[year] = sum(value) + annual_liability_dict = {} + for full_date, liability in real_dict.items(): + if full_date.year not in annual_liability_dict: + annual_liability_dict[full_date.year] = [] + annual_liability_dict[full_date.year].append(liability) + sum_dict = {} + for year, value in annual_liability_dict.items(): + sum_dict[year] = sum(value) - return sum_dict + return sum_dict diff --git a/bpfin/tests/test_financials/test_cash_balance.py b/bpfin/tests/test_financials/test_cash_balance.py index 44a0f90..7037a66 100644 --- a/bpfin/tests/test_financials/test_cash_balance.py +++ b/bpfin/tests/test_financials/test_cash_balance.py @@ -2,27 +2,28 @@ from bpfin.financials.cash_balance import cash_balance from datetime import date -# def test_cash_balance_year_gap(): -# input_dictionary = { -# date(2014, 11, 1): (500, False), -# date(2014, 12, 1): (400, False), -# date(2014, 3, 13): (600, False), -# date(2016, 11, 11): (500, False), -# date(2016, 12, 31): (400, True) -# } -# input_analysis_date = { -# 'proforma_start': date(2012, 5, 3), -# 'proforma_duration': 12 -# } -# output_cash_balance = { -# 2012: 450, -# 2013: 450, -# 2014: 500, -# 2015: 450, -# 2016: 400 -# } -# result = cash_balance(input_analysis_date, input_dictionary) -# assert result == output_cash_balance +def test_cash_balance_year_gap(): + input_dictionary = { + date(2014, 11, 1): (500, False), + date(2014, 12, 1): (400, False), + date(2014, 3, 13): (600, False), + date(2016, 11, 11): (500, False), + date(2016, 12, 31): (400, True) + } + input_analysis_date = { + 'proforma_start': date(2012, 5, 3), + 'proforma_duration': 12 + } + output_cash_balance = { + 2012: 450, + 2013: 450, + 2014: 500, + 2015: 450, + 2016: 400 + } + result = cash_balance(input_analysis_date, input_dictionary) + assert result == output_cash_balance + def test_cash_balance(): input_dictionary = { diff --git a/bpfin/tests/test_financials/test_liability.py b/bpfin/tests/test_financials/test_liability.py index 8c18ba5..3c0433b 100644 --- a/bpfin/tests/test_financials/test_liability.py +++ b/bpfin/tests/test_financials/test_liability.py @@ -1,19 +1,112 @@ -from datetime import datetime +from datetime import date from bpfin.financials.liability import final_liability_dict from bpfin.tests.testdata import sample_data as db def test_final_liability_dict(): - input_start_date = db.analysis_date['proforma_start'] + input_analysis_date = db.analysis_date input_dict = db.liability_input - input_duration = db.analysis_date['proforma_duration'] output = { 2012: 650, 2013: 2550, - 2014: 100 + 2014: 300, + 2015: 0, + 2016: 0, + 2017: 0, + 2018: 0, + 2019: 0, + 2020: 0, + 2021: 0, + 2022: 0, + 2023: 0, + 2024: 0, + 2025: 0, + 2026: 0, + 2027: 0, + 2028: 0, + 2029: 0, + 2030: 0, + 2031: 0, + 2032: 0, + 2033: 0, + 2034: 0, + 2035: 0, + 2036: 0, } - result = final_liability_dict(input_start_date, input_dict, input_duration) - print(result) + result = final_liability_dict(input_analysis_date, input_dict) + assert output == result + + +def test_final_liability_dict_single_year(): + input_dict = {'debt1': (100, 'NYSERDA', 10, date(2012, 12, 31))} + input_analysis_date = db.analysis_date + output = { + 2012: 100, + 2013: 900, + 2014: 0, + 2015: 0, + 2016: 0, + 2017: 0, + 2018: 0, + 2019: 0, + 2020: 0, + 2021: 0, + 2022: 0, + 2023: 0, + 2024: 0, + 2025: 0, + 2026: 0, + 2027: 0, + 2028: 0, + 2029: 0, + 2030: 0, + 2031: 0, + 2032: 0, + 2033: 0, + 2034: 0, + 2035: 0, + 2036: 0 + } + result = final_liability_dict(input_analysis_date, input_dict) + assert output == result + +def test_final_liability_dict_year_gap(): + input_dict = { + 'debt1': (100, 'NYSERDA', 10, date(2012, 12, 31)), + 'debt2': (200, 'Joe', 24, date(2014, 12, 31)), + 'debt3': (50, 'Tooraj', 12, date(2015, 3, 15)), + 'debt4': (250, 'Frank', 3, date(2018, 12, 31)) + } + input_analysis_date = db.analysis_date + output = { + 2012: 100, + 2013: 900, + 2014: 200, + 2015: 2900, # 2400 + 500 + 2016: 2300, # 2200 + 100 + 2017: 0, + 2018: 250, + 2019: 500, + 2020: 0, + 2021: 0, + 2022: 0, + 2023: 0, + 2024: 0, + 2025: 0, + 2026: 0, + 2027: 0, + 2028: 0, + 2029: 0, + 2030: 0, + 2031: 0, + 2032: 0, + 2033: 0, + 2034: 0, + 2035: 0, + 2036: 0 + + } + result = final_liability_dict(input_analysis_date, input_dict) assert output == result -- GitLab From e7a913871ec8e6e8edb1c3e192e2cbf23eed9096 Mon Sep 17 00:00:00 2001 From: Sarey Hamarneh Date: Thu, 1 Jun 2017 10:51:00 -0400 Subject: [PATCH 08/10] Remove description --- bpfin/financials/financial_balance.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/bpfin/financials/financial_balance.py b/bpfin/financials/financial_balance.py index 2556fa3..43d74db 100644 --- a/bpfin/financials/financial_balance.py +++ b/bpfin/financials/financial_balance.py @@ -26,8 +26,6 @@ class Balance_Sheet(): cash (float): cash value other_debt_service (float): other debt service value net_income (float): net income value - Returns: - dictionary: filled in historical balance sheet """ self.year = year self.cash = cash -- GitLab From c8e88d3a3f8f523e3f8afff7f5674a9a09a9cf7a Mon Sep 17 00:00:00 2001 From: Sarey Hamarneh Date: Thu, 1 Jun 2017 11:19:44 -0400 Subject: [PATCH 09/10] Changes --- bpfin/financials/financial_balance.py | 50 ++++++++++++++------------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/bpfin/financials/financial_balance.py b/bpfin/financials/financial_balance.py index 43d74db..1ce1872 100644 --- a/bpfin/financials/financial_balance.py +++ b/bpfin/financials/financial_balance.py @@ -4,7 +4,21 @@ from bpfin.utilbills.bill_lib import form_bill_year from numpy import mean +def convert_balance_sheet_class(balance_sheet_class): + balance_sheet_dict = { + 'year': balance_sheet_class.year, + 'cash': balance_sheet_class.cash, + 'other_debt_service': balance_sheet_class.other_debt_service, + 'net_income': balance_sheet_class.net_income + } + return balance_sheet_dict + + class Balance_Sheet(): + """This is to manage the balance sheet. + In the future this class will contain more important and complex functions. + """ + def __init__(self): self.year = None self.cash = None @@ -33,16 +47,6 @@ class Balance_Sheet(): self.net_income = net_income -def convert_balance_sheet_class(balance_sheet_class): - balance_sheet_dict = { - 'year': balance_sheet_class.year, - 'cash': balance_sheet_class.cash, - 'other_debt_service': balance_sheet_class.other_debt_service, - 'net_income': balance_sheet_class.net_income - } - return balance_sheet_dict - - class Balance_Sheet_Next(): def __init__(self, year, last_year_cash, other_debt_service, net_income): """Create next year value of balance sheet @@ -73,28 +77,26 @@ class Balance_Sheet_Table(): self.hist_start_year = None self.hist_end_year = None self.hist_balance_sheet_table = [] - self.bs_table = [] # entire table, not just historical + self.bs_table = [] - for year in cash_balance_dictionary: + for year in sorted(cash_balance_dictionary): current_balance_sheet = Balance_Sheet() if year in net_income_dictionary: - current_balance_sheet.put_hist_balance_sheet( - year, cash_balance_dictionary[year], - other_debt_service_dictionary[year], - net_income_dictionary[year]) - self.hist_balance_sheet_table.append(current_balance_sheet) - if year not in net_income_dictionary: - current_balance_sheet.put_hist_balance_sheet( - year, cash_balance_dictionary[year], - other_debt_service_dictionary[year], None) - self.hist_balance_sheet_table.append(current_balance_sheet) + net_income = net_income_dictionary[year] + else: + net_income = None + current_balance_sheet.put_hist_balance_sheet( + year, cash_balance_dictionary[year], + other_debt_service_dictionary[year], + net_income) + self.hist_balance_sheet_table.append(current_balance_sheet) sorted_balance_sheet_hist_year = sorted(cash_balance_dictionary) self.hist_start_year = sorted_balance_sheet_hist_year[0] self.hist_end_year = sorted_balance_sheet_hist_year[-1] - self.bs_table = self.hist_balance_sheet_table + self.bs_table = copy.deepcopy(self.hist_balance_sheet_table) def project_balance_sheet(self, analysis_date, other_debt_service_dictionary, @@ -153,7 +155,7 @@ class Balance_Sheet_Table(): current_balance_sheet.cash } } - return None + return def get_first_year_cash(self, commission_date): -- GitLab From b576962fc59b9cd97a474dbefdf4eb79d1c756bf Mon Sep 17 00:00:00 2001 From: Sarey Hamarneh Date: Thu, 1 Jun 2017 11:26:37 -0400 Subject: [PATCH 10/10] Description --- bpfin/financials/financial_balance.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/bpfin/financials/financial_balance.py b/bpfin/financials/financial_balance.py index 1ce1872..b8643c9 100644 --- a/bpfin/financials/financial_balance.py +++ b/bpfin/financials/financial_balance.py @@ -66,12 +66,14 @@ class Balance_Sheet_Next(): class Balance_Sheet_Table(): def __init__(self, cash_balance_dictionary, other_debt_service_dictionary, net_income_dictionary): - """Put historical data values into balance sheet based on the cash balance years. + """The balance sheet table and the projections (for now) is composed of cash, liability, and net_income. + Together, these three components allow us to project the future balance sheet, which is essentially cash available. + This class includes the historical balance sheet table and also the future projection of the balance sheet table. Args: year (integer): year - cash_balance_dictionary (dict): dictionary of annual cash value items, key is year - other_debt_service_dictionary (dict): dictionary of annual liability value items, key is year - net_income_dictionary (dict): dictionary of annual liability value items, key is year + cash_balance_dictionary (dict): dictionary of known annual cash value items, key is year + other_debt_service_dictionary (dict): dictionary of known annual liability value items, key is year + net_income_dictionary (dict): dictionary of known annual net_income value items, key is year """ self.hist_start_year = None @@ -101,7 +103,9 @@ class Balance_Sheet_Table(): def project_balance_sheet(self, analysis_date, other_debt_service_dictionary, net_income_dictionary): - """Create balance sheet projection. + """This function projects the balance sheet based on the given historical balance sheet information. + It uses projections of other_debt_service (liability) and net_income to forecast how cash will change over time. + The analysis_date lets us know how far in the future we need to project. Args: analysis_date (dict): {pro_forma date: duration (years)} other_debt_service_dictionary (dict): dictionary of debt service values per year -- GitLab