diff --git a/bills.py b/bills.py index d38084c..2d27512 100644 --- a/bills.py +++ b/bills.py @@ -1,4 +1,4 @@ -from db import get_bill_data, get_bill_types, get_bill_freqs, set_bill_type_growth, new_bill +from db import set_bill_type_growth, new_bill from defines import END_YEAR import datetime from datetime import date, timedelta @@ -51,6 +51,8 @@ def allocate_by_quarter( bill_info, bill_type, yr, prev_bill, bill): bill_info[bill_type]['qtr'][q_start.year] = {} for i in range(1,5): bill_info[bill_type]['qtr'][q_start.year][i]=0 + if q not in bill_info[bill_type]['qtr'][q_start.year]: + bill_info[bill_type]['qtr'][q_start.year][q]=0 bill_info[bill_type]['qtr'][q_start.year][q] += days*cost_per_day # next quarter cur = q_end + timedelta(days=1) @@ -139,14 +141,17 @@ def new_estimated_bill( bill_info, yr, bill_type, amt, new_date ): if bill_info[bill_type]['num_ann_bills'] == 4: q = qtr( new_date ) + # new bill in this qtr of this year, so set arrays up if yr not in bill_info[bill_type]['qtr']: bill_info[bill_type]['qtr'][yr]={} pb = find_previous_bill( bill_type, bill_info, new_date ) if pb['estimated'] == 0: - print( f" FIXFIXFIX - have a prev real bill={pb['bill_date']} & this is first est - likely need to better apportion this bill into the quarters" ) allocate_by_quarter( bill_info, bill_type, yr, pb, bill ) - - bill_info[bill_type]['qtr'][yr][q]=amt + else: + if not q in bill_info[bill_type]['qtr'][yr]: + # first in this year, just init it... + bill_info[bill_type]['qtr'][yr][q]=0 + bill_info[bill_type]['qtr'][yr][q]+=amt return @@ -155,12 +160,16 @@ def new_estimated_bill( bill_info, yr, bill_type, amt, new_date ): # NOTE: only ever called when there is a need to add a new bill def add_missing_annual_bill_in_yr( bill_type, bill_info, yr ): mm_dd = bill_info[bill_type]['last_bill']['bill_date'][5:] - amt = bill_info[bill_type]['last_bill']['amount'] + new_date= f'{yr}-{mm_dd}' + pb=find_previous_bill( bill_type, bill_info, new_date ) + if pb: + amt = pb['amount'] + else: + amt = bill_info[bill_type]['last_bill']['amount'] # okay the missing bill is before the first bill... - for i in range( bill_info[bill_type]['last_bill_year'], yr ): - amt += amt * bill_info[bill_type]['growth']/100 + amt += amt * bill_info[bill_type]['growth']/100 - new_estimated_bill( bill_info, yr, bill_type, amt, f'{yr}-{mm_dd}' ) + new_estimated_bill( bill_info, yr, bill_type, amt, new_date ) return # missing quarterly bill, find date based on MM-DD and ??? - can have missing bilsl in first year @@ -248,6 +257,8 @@ def get_growth_value( bt, bill_type ): return el['ann_growth_avg'] elif which == 'min': return el['ann_growth_min'] + elif which == 'simple': + return el['ann_growth_simple'] else: return el['ann_growth_max'] @@ -313,7 +324,8 @@ def process_bill_data(bd, bt, bf): # go from first_bill year until reach end year for yr in range( yr_min, END_YEAR+1 ): # we have all the bills needed for yr - but dont be cute with qtrly, gas bills suck can have missing with 4 bills - if yr in bill_info[bill_type]['year'] and len(bill_info[bill_type]['year'][yr]) == bill_info[bill_type]['num_ann_bills'] and bill_info[bill_type]['num_ann_bills'] !=4: + # > can occur when we add a real bill "on top of" an estimate. + if yr in bill_info[bill_type]['year'] and len(bill_info[bill_type]['year'][yr]) >= bill_info[bill_type]['num_ann_bills'] and bill_info[bill_type]['num_ann_bills'] !=4: continue add_missing_bills_for_yr( bill_type, bill_info, yr ) derive_ann_growth( bill_type, bill_info ) @@ -333,7 +345,7 @@ def add_missing_bills_for_yr( bill_type, bill_info, yr ): ################################################################################ # Takes qtrly bills and start from 2nd year of bills (so we can estimate growth) -# and go through each bill allocating hte proportion of each bill to each +# and go through each bill allocating the proportion of each bill to each # relevant quarter - to build more accurate totals. Would be mostly marginal # accept when Gas qtrly bills have 6 per year, and we need to guess say qtr4 in # the future, we can't easily find corresponding bill form previous year, so @@ -344,12 +356,13 @@ def ProportionQtrlyData( bill_type, bill_info ): now_yr = datetime.date.today().year # FIX UP CRAPPY QUARTERLY BILLING PROPORTIONS (only useful as some gas bills are 6 / year!) if bill_info[bill_type]['num_ann_bills']==4: - for yr in range( bill_info[bill_type]['first_bill_year'], now_yr+1): - for b in bill_info[bill_type]['year'][yr]: - pb = find_previous_bill( bill_type, bill_info, b['bill_date'] ) - if not pb: - continue - allocate_by_quarter( bill_info, bill_type, yr, pb, b ) + for yr in range( bill_info[bill_type]['first_bill_year'], END_YEAR+1): + if yr in bill_info[bill_type]['year']: + for b in bill_info[bill_type]['year'][yr]: + pb = find_previous_bill( bill_type, bill_info, b['bill_date'] ) + if not pb: + continue + allocate_by_quarter( bill_info, bill_type, yr, pb, b ) return ################################################################################ @@ -368,7 +381,7 @@ def derive_ann_growth( bill_type, bill_info ): continue; # just going to make sure we dont use estimated data in the last year of real data - can skew growths - if yr == bill_info[bill_type]['last_real_bill_year']: + if yr == bill_info[bill_type]['last_real_bill_year'] or bill_info[bill_type]['num_ann_bills'] ==1: skip_yr=False for b in bill_info[bill_type]['year'][yr]: if b['estimated']: @@ -397,24 +410,37 @@ def derive_ann_growth( bill_type, bill_info ): avg_growth = 0 max_growth = 0 count = 0 + simple_first_yr=0 + simple_last_yr=0 # start from year after first bill, so we can see annual growth from the following year onwards for yr in range( bill_info[bill_type]['first_bill_year']+1, now_yr+1): # if full data sets for consecutive years, work out annual growth stats if yr-1 in total and yr in total: + if simple_first_yr==0: + simple_first_yr=yr growth = (total[yr] - total[yr-1]) / total[yr-1] * 100 avg_growth += growth count += 1 + simple_last_yr=yr if growth < min_growth: min_growth = growth if growth > max_growth: max_growth = growth + # data to work with if count: - ## print( f"Before sanity check, min={min_growth}, avg={avg_growth/count}, max_growth={max_growth}" ) - # HACK FOR SANITY SAKE NOW - bills wont decrease normally, and 10% is unlikely for sustained growth - if min_growth< 0: min_growth=0 - if avg_growth< 0 or avg_growth > 10: avg_growth = 3*count - if max_growth>10 : max_growth = 9.99 - set_bill_type_growth( bill_type, min_growth, avg_growth/count, max_growth ) + if simple_first_yr != simple_last_yr: + # calculate a simple growth with full year consecutive totals -> last - first / years + simple_growth=( ((total[simple_last_yr]-total[simple_first_yr])/(simple_last_yr-simple_first_yr)) / total[simple_first_yr] )*100.0 + else: + # calculate a simple growth based on last - first / years - only 1 consecutive year I guess, so can't use it, use real first/last + if bill_info[bill_type]['first_bill_year'] != bill_info[bill_type]['last_real_bill_year']: + simple_growth=( ((total[bill_info[bill_type]['last_real_bill_year']]-total[bill_info[bill_type]['first_bill_year']])/(bill_info[bill_type]['last_real_bill_year']-bill_info[bill_type]['first_bill_year'])) / total[bill_info[bill_type]['first_bill_year']] )*100.0 + set_bill_type_growth( bill_type, min_growth, avg_growth/count, max_growth, simple_growth ) else: - # failsafe (just in case fill bills failed to add enough bills to average out) - print( f"{bill_type}: Unable to calculate growth!" ) + # okay use last - first / years to get a simple_growth, just need bills from different years + if bill_info[bill_type]['first_bill_year'] != bill_info[bill_type]['last_real_bill_year']: + simple_growth=( ((total[bill_info[bill_type]['last_real_bill_year']]-total[bill_info[bill_type]['first_bill_year']])/(bill_info[bill_type]['last_real_bill_year']-bill_info[bill_type]['first_bill_year'])) / total[bill_info[bill_type]['first_bill_year']] )*100.0 + set_bill_type_growth( bill_type, 0, 0, 0, simple_growth ) + else: + # failsafe (just in case fill bills failed to add enough bills to average out) + print( f"{bill_type}: Unable to calculate growth!" )