retirement_calc

Applications, Games, Tools, User libs and useful stuff coded in PureBasic
yrreti
Enthusiast
Enthusiast
Posts: 546
Joined: Tue Oct 31, 2006 4:34 am

retirement_calc

Post by yrreti »

This is just a quick program I threw together to try to figure out how long
a retirement amount, drawing interest, would last me if drawn out at a fixed rate.
It's not meant to be 100% accurate, and my thinking may be wrong here.
But it's meant to give me some kind of idea how long the money will last me.
You enter the Begin value, Yearly interest rate, Monthly amount needed, and
then Calculate. eg:
150000
4 (4%)
1200
Amount good for, shows the years and months it's good for. The balance left
is what's left when the amount left is less then you wish to withdraw.
If interest earnings are greater then amount withdrawn, (displays withdrawn -#'s),
then I programmed it to just stop at 30 years. I'd probably be dead beyond that anyway.
Also thanks to BackupUser for his InputBox.
The program will also open up a txt file in notepad, showing the complete
withdrawal skedule. (may need to put notepad.exe in working directory)

I won't be able to reply back until Monday as I'm going out of town in the morning.

If you find any big mistakes or any suggestions or improvements that could be added.
Please do, and post them here for me to learn and to share with others.

Code: Select all

;{- Enumerations / DataSections
;{ Windows
Enumeration
  #Window_0
EndEnumeration
;}
;{ Gadgets
Enumeration
  #Text_RBV
  #Text_YIR
  #Text_MAN
  #Text_AGF
  #Text_YM
  #Text_BL
  #Text_BLA
  
  #Button_RBV
  #Button_YIR
  #Button_MAN
  
  #Button_CALC
  
  #Alta
  #Altb
  #Altc
  #Alti
  
EndEnumeration
;}
Define.l Event, EventWindow, EventGadget, EventType, EventMenu
;}
Procedure OpenWindow_Window_0()
  If OpenWindow(#Window_0, 620, 163, 400, 133, Space(20)+"Calculated Range of Retirement Funds", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_TitleBar)
    TextGadget(#Text_RBV, 145, 20, 100, 20, "", #PB_Text_Border|#PB_Text_Center)
    TextGadget(#Text_YIR, 145, 50, 100, 20, "", #PB_Text_Border|#PB_Text_Center)
    TextGadget(#Text_MAN, 145, 80, 100, 20, "", #PB_Text_Border|#PB_Text_Center)
    SetGadgetColor(#Text_RBV, #PB_Gadget_BackColor, $EFEFEF)
    SetGadgetColor(#Text_YIR, #PB_Gadget_BackColor, $EFEFEF)
    SetGadgetColor(#Text_MAN, #PB_Gadget_BackColor, $EFEFEF)
    TextGadget(#Text_AGF, 268, 15, 120, 20, "Amount good for:",#PB_Text_Center)
    TextGadget(#Text_YM, 265, 30, 120, 20, "", #PB_Text_Border)
    
    TextGadget(#Text_BL, 268, 55, 120, 20, "Balance Left:",#PB_Text_Center)
    TextGadget(#Text_BLA, 265, 70, 120, 20, "", #PB_Text_Border|#PB_Text_Center)
    SetGadgetColor(#Text_YM, #PB_Gadget_BackColor, $EFEFEF)
    SetGadgetColor(#Text_BLA, #PB_Gadget_BackColor, $EFEFEF)
    
    ButtonGadget(#Button_RBV, 15, 20, 125, 20, "Retirement &Begin Value")
    ButtonGadget(#Button_YIR, 15, 50, 125, 20, "Yearly &Interest Rate")
    ButtonGadget(#Button_MAN, 15, 80, 125, 20, "Monthly &Amount Needed")
    
    ButtonGadget(#Button_CALC, 283, 100, 80, 25, "&Calculate")
    
    ;Alt keys
    AddKeyboardShortcut(0, #PB_Shortcut_Alt|#PB_Shortcut_A, #Alta)
    AddKeyboardShortcut(0, #PB_Shortcut_Alt|#PB_Shortcut_B, #Altb)
    AddKeyboardShortcut(0, #PB_Shortcut_Alt|#PB_Shortcut_C, #Altc)
    AddKeyboardShortcut(0, #PB_Shortcut_Alt|#PB_Shortcut_I, #Alti)
    
    
  EndIf
EndProcedure

Procedure.s InputBox(txtw, txth, title$, prompt$, def$="", flags=0)
  ; A version of InputRequester() by BackupUser
  ; Modified by AKJ 18-Oct-06
  ; Downloaded: www.purebasic.fr/english/viewtopic.php?t=2412
  ; textw and txth are the outer dimensions of the prompt text gadget
  ; Available flags are:
  ;   #PB_String_{BorderLess  LowerCase  Numeric  Password  ReadOnly  Uppercase}
  ; Features:
  ; (1) Modal (locks the calling window until done)
  ; (2) Prompt area is larger
  ; (3) Prompt area supports multi-line text with Chr(13)
  ; (4) Cancel button in addition to OK button
  ; (5) Returns the default string (def$) if the Cancel button is pressed
  ; (6) Returns "" if an error occurs
  ; (7) Standard Windows look-And-feel
  ; (8) Plays the "question" prompt sound
  ; (9) Works with or without a calling window
  ;(10) Emulates the Visual Basic InputBox() command
  ;(11) Supports all #PB_String_xxx flags
  Protected winBox, txtPrompt, strInput, butOK, butCancel ; Gadgets
  Protected box, ev, id, ret, esc, a, thread1, thread2, text$=""
  
  If txtw<128 ; To show buttons correctly
    txtw=128
  EndIf
  
  If txth<20 ; Height of a normal text line
    txth = 20
  EndIf
  winBox=OpenWindow(#PB_Any,0,0,txtw+13,txth+20+23+8*4,title$,#PB_Window_WindowCentered)
  box=WindowID(winBox)
  If winBox; And CreateGadgetList(box)
    txtPrompt=TextGadget(#PB_Any,6,8,txtw,txth,prompt$)
    If flags&#PB_String_Password=0
      flags|#ES_MULTILINE
    EndIf
    
    strInput=StringGadget(#PB_Any,6,txth+8*2,txtw,20,def$,flags|#ES_AUTOVSCROLL)
    
    butOK=ButtonGadget(#PB_Any,6,txth+20+8*3,60,23,"OK") ; Set x=txtw-122 for button to be on the right
    
    ;butCancel=ButtonGadget(#PB_Any,txtw-54,txth+20+8*3,60,23,"Cancel")
    
    SendMessage_(GadgetID(strInput),#EM_SETSEL,0,Len(def$))
    GetAsyncKeyState_(#VK_RETURN)
    GetAsyncKeyState_(#VK_ESCAPE)
    StickyWindow(winBox,#True)
    SetForegroundWindow_(box)
    SetActiveGadget(strInput)
    MessageBeep_(#MB_ICONQUESTION)
    
    Repeat
      ev=WaitWindowEvent(1)
      id=EventGadget()
      ret=GetAsyncKeyState_(#VK_RETURN)
      esc=GetAsyncKeyState_(#VK_ESCAPE)
      a=GetForegroundWindow_()
      If a<>box
        thread1=GetWindowThreadProcessId_(@a,0)
        thread2=GetWindowThreadProcessId_(@box,0)
        If thread1<>thread2
          AttachThreadInput_(thread1,thread2,#True)
        EndIf
        SetForegroundWindow_(box)
        Sleep_(1)
        If thread1<>thread2
          AttachThreadInput_(thread1,thread2,#False)
        EndIf
        SetActiveGadget(strInput); !!! : MessageBeep_(#MB_ICONQUESTION)
      EndIf
    Until (ev=#PB_Event_Gadget And (id=butOK Or id=butCancel)) Or ret<>0 Or esc<>0 Or ev=#PB_Event_CloseWindow
    
    If id=butOK Or ret<>0
      text$=GetGadgetText(strInput)
    Else
      text$=def$
    EndIf
    CloseWindow(winBox)
  EndIf
  ProcedureReturn text$
EndProcedure

OpenWindow_Window_0()

;{- Event loop
Repeat
  Event = WaitWindowEvent()
  Select Event
    ; ///////////////////
  Case #PB_Event_Gadget
    EventGadget = EventGadget()
    EventType = EventType()
    
    If EventGadget = #Button_RBV
      erbb:
      rbv$ = InputBox(130, 70, " ", "Enter Retirement Beginning Balance: ", "")
      start_RBV.d=ValD(rbv$)
      l=Len(rbv$)
      Select l
      Case 4 To 6 ;formats # with , added
        rrbv$=Right(rbv$,3)
        lrbv$=Left(rbv$,l-3)
        arbv$=lrbv$+","+rrbv$
        
      Case 7 To 9 ;formats # with two ,'s added
        rrbv1$=Right(rbv$,3)
        lrbv$=Left(rbv$,l-3)
        nl=Len(lrbv$)
        rrbv2$=Right(lrbv$,3)
        lrbv$=Left(lrbv$,nl-3)
        arbv$=lrbv$+","+rrbv2$+","+rrbv1$
      Default
        arbv$=rbv$
      EndSelect
      
      SetGadgetText(#Text_RBV, arbv$)
      
      
    ElseIf EventGadget = #Button_YIR
      eyir:
      yir$ = InputBox(130, 70, " ", "Enter Yearly Interest Rate:    eg: 4.5 = 4.5% ", "")
      yir.d=ValD(yir$)
      interest_per_year.d=yir/100+0.00000001
      SetGadgetText(#Text_YIR, yir$)
      
    ElseIf EventGadget = #Button_MAN
      eman:
      man$ = InputBox(130, 70, " ", "Enter the Monthy Amount Needed: ", "")
      man.d=ValD(man$)
      l=Len(man$)
      Select l
      Case 4 To 6 ;formats # with , added
        rman$=Right(man$,3)
        lman$=Left(man$,l-3)
        aman$=lman$+","+rman$
      Case 7 To 9 ;formats # with two ,'s added
        rman1$=Right(man$,3)
        lman$=Left(man$,l-3)
        nl=Len(lman$)
        rman2$=Right(lman$,3)
        lman$=Left(lman$,nl-3)
        aman$=lman$+","+rman2$+","+rman1$
      Default
        aman$=man$
      EndSelect
      SetGadgetText(#Text_MAN, aman$)
      
    ElseIf EventGadget = #Button_CALC
      calc:
      If start_RBV>0
        If interest_per_year>0
          
          percent.d=((interest_per_year)/365)*30.4375 ;= interest per 30.4375 day month, per 365.25 year.
          interest_per_year$=Left(StrF(interest_per_year),5)
          
          If Right(interest_per_year$,1)="0"
            interest_per_year$=Left(StrF(interest_per_year),4)
          EndIf
          
          awd.d=0 ;(Amount With drawn)
          next_RBV.d=start_RBV
          month=0
          
          ;Get program run directory path
          pp$=Space(#MAX_PATH)
          GetCurrentDirectory_(#MAX_PATH,@pp$)
          drv$=Left(pp$,3)
          pp$=pp$+"\"
          CreateFile(1,pp$+"CRRF_list.txt")  ;write output to file
          WriteStringN(1, "Retirement Beginning Balance: "+Str(start_RBV)+"         Interest Rate/year: "+interest_per_year$+"         Amount Needed: "+Str(man))
          WriteStringN(1,"")
          While next_RBV>man
            start_next_RBV=next_RBV
            interest = (start_next_RBV * percent)
            awd = man-interest
            next_RBV=next_RBV-awd
            month=month+1
            month$=Left("Month: "+Str(month)+Space(11),14)
            Month_Start$=Left("Start: "+Str(start_next_RBV)+Space(11),18)
            Month_End$=Left("End: "+Str(next_RBV)+Space(11),18)
            Interest$=Left("Interest: "+Str(interest)+Space(11),18)
            With_drawn$=Left("Withdrawn: "+Str(awd)+Space(11),19)
            Amount_total$="Amount Total: "+Str(interest+awd)
            
            WriteStringN(1, month$+Month_Start$+Month_End$+Interest$+With_drawn$+Amount_total$)
            If month=360  ;30 years
              Break
            EndIf
          Wend
          al$=StrF(next_RBV,0)
          l=Len(al$)
          Select l
          Case 4 To 6 ;formats # with , added
            ral$=Right(al$,3)
            lal$=Left(al$,l-3)
            aal$=lal$+","+ral$
            
          Case 7 To 9 ;formats # with two ,'s added
            ral1$=Right(al$,3)
            lal$=Left(al$,l-3)
            nl=Len(lal$)
            ral2$=Right(lal$,3)
            lal$=Left(lal$,nl-3)
            aal$=lal$+","+ral2$+","+ral1$
          Default
            aal$=al$
          EndSelect
          
          SetGadgetText(#Text_BLA,aal$)
          
          year=0
          While month>11
            year=year+1
            month=month-12
          Wend
          WriteStringN(1,"")
          If year>29
            WriteStringN(1," Years: "+Str(year)+" plus years")
            SetGadgetText(#Text_YM, " Years: "+Str(year)+" plus years")
          Else
            WriteStringN(1,"Years: "+Str(year)+"  Months: "+Str(month))
            SetGadgetText(#Text_YM, " Years: "+Str(year)+"  Months: "+Str(month))
          EndIf
          CloseFile(1)
          
          ;You may need to put copy of notepad.exe in working directory to cover
          ;different installs of windows.
          RunProgram("notepad.exe" , "CRRF_list.txt", pp$)
        EndIf
      EndIf
    EndIf
    
  Case #PB_Event_Menu
    
    Select EventMenu()      ;********************************************************
    Case #Alta
      Goto eman
      
    Case #Altb
      Goto erbb
      
    Case #Altc
      Goto calc
      
    Case #Alti
      Goto eyir
      
    EndSelect
    
    ; ////////////////////////
  Case #PB_Event_CloseWindow
    EventWindow = EventWindow()
    If EventWindow = #Window_0
      CloseWindow(#Window_0)
      Break
    EndIf
  EndSelect
  ForEver
  ;
  ;}