diff --git a/src/owlplanner/plan.py b/src/owlplanner/plan.py index 5979af3..5558ff1 100644 --- a/src/owlplanner/plan.py +++ b/src/owlplanner/plan.py @@ -317,7 +317,7 @@ def _setStartingDate(self, mydate): mydate = mydate.strftime('%Y-%m-%d') if mydate is None: refdate = date.today() - self.startDate = refdate.strftime('%m-%d') + self.startDate = refdate.strftime('%Y-%m-%d') else: mydatelist = mydate.split('-') if len(mydatelist) == 2 or len(mydatelist) == 3: diff --git a/tests/test_regressions.py b/tests/test_regressions.py index 81e7761..65c15e5 100644 --- a/tests/test_regressions.py +++ b/tests/test_regressions.py @@ -22,7 +22,7 @@ def test_constructor1(): assert p.startDate == '1-1' -def test_constructor2(): +def test_constructor1_2(): inames = ['Joe', 'Jane'] yobs = [1960, 1961] expectancy = [80, 82] @@ -62,6 +62,7 @@ def test_date_2(): assert p.expectancy == expectancy assert p.N_i == 2 assert p._name == name + assert p.startDate == date.today().strftime('%Y-%m-%d') def createPlan(ni, name, ny): diff --git a/ui/Assets.py b/ui/Assets.py index e4c8950..e6a31ab 100644 --- a/ui/Assets.py +++ b/ui/Assets.py @@ -1,41 +1,40 @@ import streamlit as st -import key as k +import key as k st.write('## Assets') - st.write('## Account Balances') accounts = {'txbl': 'taxable', 'txDef': 'tax-deferred', 'txFree': 'tax-exempt'} -col1, col2 = st.columns(2, gap='small', vertical_alignment='top')#, border=False) +col1, col2 = st.columns(2, gap='small', vertical_alignment='top') with col1: iname0 = st.session_state.iname0 for key in accounts: - nkey = key+str(0) - k.init(nkey, 0) - ret = k.getNum('%s %s account ($k)' % (iname0, accounts[key]), nkey) + nkey = key+str(0) + k.init(nkey, 0) + ret = k.getNum('%s %s account ($k)' % (iname0, accounts[key]), nkey) with col2: if st.session_state.status == 'married': iname1 = st.session_state.iname1 for key in accounts: - nkey = key+str(1) - k.init(nkey, 0) - ret = k.getNum('%s %s account ($k)' % (iname1, accounts[key]), nkey) + nkey = key+str(1) + k.init(nkey, 0) + ret = k.getNum('%s %s account ($k)' % (iname1, accounts[key]), nkey) if st.session_state.status == 'married': st.write('#### Beneficiary fractions') - col1, col2, col3 = st.columns(3, gap='small', vertical_alignment='top')#, border=False) + col1, col2, col3 = st.columns(3, gap='small', vertical_alignment='top') with col1: - nkey = 'benf'+str(0) - k.init(nkey, 1) - ret = k.getNum('Beneficiary fraction (%s)' % accounts['txbl'], nkey) + nkey = 'benf'+str(0) + k.init(nkey, 1) + ret = k.getNum('Beneficiary fraction (%s)' % accounts['txbl'], nkey) with col2: - nkey = 'benf'+str(1) - k.init(nkey, 1) - ret = k.getNum('Beneficiary fraction (%s)' % accounts['txDef'], nkey) + nkey = 'benf'+str(1) + k.init(nkey, 1) + ret = k.getNum('Beneficiary fraction (%s)' % accounts['txDef'], nkey) with col3: - nkey = 'benf'+str(2) - k.init(nkey, 1) - ret = k.getNum('Beneficiary fraction (%s)' % accounts['txFree'], nkey) + nkey = 'benf'+str(2) + k.init(nkey, 1) + ret = k.getNum('Beneficiary fraction (%s)' % accounts['txFree'], nkey) diff --git a/ui/Basic_Information.py b/ui/Basic_Information.py index 13a57d7..a70d33d 100644 --- a/ui/Basic_Information.py +++ b/ui/Basic_Information.py @@ -7,7 +7,7 @@ def checkAllOK(): ss = st.session_state - return (ss.name == '' or ss.iname0 == '' + return (ss.name == '' or ss.iname0 == '' or (ss.status == 'married' and ss.iname1 == '')) @@ -21,7 +21,7 @@ def genPlan(): yobs.append(ss.yob1) life.append(ss.life1) - try: + try: print(inames, yobs, life, ss.name, ss.startDate) plan = owl.Plan(inames, yobs, life, ss.name, ss.startDate) except Exception as e: @@ -29,13 +29,14 @@ def genPlan(): return ss.plan = plan + st.write('## Basic Information') choices = ['single', 'married'] k.init('status', choices[0]) st.radio('Marital status', choices, - index=choices.index(st.session_state['status']), key='_status', - on_change=k.push, args=['status'], horizontal=True) + index=choices.index(st.session_state['status']), key='_status', + on_change=k.push, args=['status'], horizontal=True) col1, col2 = st.columns(2, gap='small', vertical_alignment='top') with col1: @@ -46,10 +47,10 @@ def genPlan(): iname0 = k.getText('Your first name', 'iname0') k.init('yob0', 1965) - ret = k.getNum("%s's birth year"%iname0, 'yob0') + ret = k.getNum("%s's birth year" % iname0, 'yob0') k.init('life0', 80) - ret = k.getNum("%s's expected longevity"%iname0, 'life0') + ret = k.getNum("%s's expected longevity" % iname0, 'life0') today = date.today() thisyear = today.year @@ -73,10 +74,10 @@ def genPlan(): iname1 = k.getText("Your spouse's first name", 'iname1') k.init('yob1', 1965) - ret = k.getNum("%s's birth year"%iname1, 'yob1') + ret = k.getNum("%s's birth year" % iname1, 'yob1') k.init('life1', 80) - ret = k.getNum("%s's expected longevity"%iname1, 'life1') + ret = k.getNum("%s's expected longevity" % iname1, 'life1') st.button('Initialize plan', on_click=genPlan, disabled=checkAllOK()) diff --git a/ui/Fixed_Income.py b/ui/Fixed_Income.py index cdf0509..98a40c8 100644 --- a/ui/Fixed_Income.py +++ b/ui/Fixed_Income.py @@ -1,4 +1,5 @@ import streamlit as st + import key as k @@ -6,17 +7,18 @@ def getInput(i, key, text, defval=0): nkey = key+str(i) k.init(nkey, defval) iname = st.session_state['iname'+str(i)] - ret = st.number_input("%s's %s"%(iname, text), min_value=0, + ret = st.number_input("%s's %s" % (iname, text), min_value=0, value=st.session_state[nkey], on_change=k.push, args=[nkey], key='_'+nkey) + if st.session_state.iname0 == '': st.info('Basic information must be filled before filling this page.') else: st.write('# Fixed Income') st.write('### Social Security') - col1, col2 = st.columns(2, gap='small', vertical_alignment='top')#, border=False) + col1, col2 = st.columns(2, gap='small', vertical_alignment='top') with col1: getInput(0, 'ssAge', 'social security age', 67) getInput(0, 'ssAmt', 'social security amount (k$)') @@ -27,7 +29,7 @@ def getInput(i, key, text, defval=0): getInput(1, 'ssAmt', 'social security amount (k$)') st.write('### Pension') - col1, col2 = st.columns(2, gap='small', vertical_alignment='top')#, border=False) + col1, col2 = st.columns(2, gap='small', vertical_alignment='top') with col1: getInput(0, 'pAge', 'pension age', 65) getInput(0, 'pAmt', 'social security amount (k$)') @@ -36,5 +38,4 @@ def getInput(i, key, text, defval=0): if st.session_state.status == 'married': getInput(1, 'pAge', 'pension age', 65) getInput(1, 'pAmt', 'social security amount (k$)') - diff --git a/ui/Optimization_Parameters.py b/ui/Optimization_Parameters.py index a51fee6..729e065 100644 --- a/ui/Optimization_Parameters.py +++ b/ui/Optimization_Parameters.py @@ -1,20 +1,20 @@ import streamlit as st + import key as k st.write('# Optimization Parameters') - -col1, col2 = st.columns(2, gap='small', vertical_alignment='top')#, border=False) +col1, col2 = st.columns(2, gap='small', vertical_alignment='top') with col1: iname = st.session_state.iname0 k.init('maxX0', 1000) - ret = k.getNum("%s's maximum Roth Conversion ($k)"%iname, 'maxX0') + ret = k.getNum("%s's maximum Roth Conversion ($k)" % iname, 'maxX0') with col2: if st.session_state.status == 'married': iname = st.session_state.iname1 k.init('maxX1', 1000) - ret = k.getNum("%s's maximum Roth Conversion ($k)"%iname, 'maxX1') + ret = k.getNum("%s's maximum Roth Conversion ($k)" % iname, 'maxX1') k.init('med', True) ret = k.getToggle('Medicare and IRMAA calculations', 'med') diff --git a/ui/Rate_Selection.py b/ui/Rate_Selection.py index 3ff0765..94fcedd 100644 --- a/ui/Rate_Selection.py +++ b/ui/Rate_Selection.py @@ -34,20 +34,19 @@ def update_rates(key): rates = FXRATES[ret] k.init('fxRate'+str(j), rates[j]) - ro = ret != 'user' + ro = (ret != 'user') col1, col2, col3, col4 = st.columns(4, gap='small', vertical_alignment='top') with col1: ret = k.getNum('S&P 500', 'fxRate0', ro) - + with col2: ret = k.getNum('Corporate Bonds Baa', 'fxRate1', ro) - + with col3: ret = k.getNum('10-y Treasury Notes', 'fxRate2', ro) - + with col4: ret = k.getNum('Common Assets / Inflation', 'fxRate3', ro) - elif st.session_state.rateType == 'varying': choices3 = ['historical', 'histochastic', 'stochastic'] diff --git a/ui/key.py b/ui/key.py index f546228..4cd6a03 100644 --- a/ui/key.py +++ b/ui/key.py @@ -1,35 +1,42 @@ import streamlit as st + def dump(): print('Dump:', st.session_state) + def push(key): # print('pushing', key, 'as', st.session_state['_'+key]) st.session_state[key] = st.session_state['_'+key] # dump() + def store(key, val): # print('storing', key, 'as', val) st.session_state[key] = val # dump() + def init(key, val): if key not in st.session_state: # print('init', key, 'as', val) st.session_state[key] = val # dump() + def getNum(text, nkey, disabled=False, callback=push): - return st.number_input(text, - value=st.session_state[nkey], - disabled=disabled, - on_change=callback, args=[nkey], key='_'+nkey) + return st.number_input(text, + value=st.session_state[nkey], + disabled=disabled, + on_change=callback, args=[nkey], key='_'+nkey) + def getText(text, nkey, disabled=False, callback=push): - return st.text_input(text, - value=st.session_state[nkey], - disabled=disabled, - on_change=callback, args=[nkey], key='_'+nkey) + return st.text_input(text, + value=st.session_state[nkey], + disabled=disabled, + on_change=callback, args=[nkey], key='_'+nkey) + def getRadio(text, choices, nkey, callback=push): return st.radio(text, choices, @@ -37,6 +44,7 @@ def getRadio(text, choices, nkey, callback=push): on_change=callback, args=[nkey], key='_'+nkey, horizontal=True) + def getToggle(text, nkey, callback=push): return st.toggle(text, value=st.session_state[nkey], - on_change=callback, args=[nkey], key='_'+nkey) + on_change=callback, args=[nkey], key='_'+nkey) diff --git a/ui/main.py b/ui/main.py index a56f880..048a7b9 100644 --- a/ui/main.py +++ b/ui/main.py @@ -17,5 +17,5 @@ st.Page('Monte_Carlo.py'), st.Page('Summary.py'), st.Page('Logs.py'), - ]) + ]) pg.run()