HP Forums
A program to calc leasing - Printable Version

+- HP Forums (https://www.hpmuseum.org/forum)
+-- Forum: HP Calculators (and very old HP Computers) (/forum-3.html)
+--- Forum: HP Prime (/forum-5.html)
+--- Thread: A program to calc leasing (/thread-3927.html)



A program to calc leasing - salvomic - 05-20-2015 10:35 PM

hi,
I put on the HP Prime Software Library a program to calculate Leasing with advanced payments (monthly pmt and yield) and Leasing with residual.
This is the link.
The program uses the power of the "financial" functions of the Prime.

Enjoy!

Salvo


RE: A program to calc leasing - DrD - 05-20-2015 10:51 PM

I've watched you come a long way with the Prime, congratulations on yout programming!

Regarding your latest share, the leasing program, have you considered using a DRAWMENU type interface to access the choices? Alternative menu options, such as CHOOSE, or conditional branching from an INPUT variable, also work; but with DRAWMENU a segway into the world of graphics is bound to follow. Once you have the pixels at your command, you can do pretty amazing things.

-Dale-


RE: A program to calc leasing - salvomic - 05-20-2015 10:58 PM

(05-20-2015 10:51 PM)DrD Wrote:  I've watched you come a long way with the Prime, congratulations on yout programming!
thanks a lot, Dale!
My dream now is to have 90% of the HP 12C also in the Prime :-)
Quote:Regarding your latest share, the leasing program, have you considered using a DRAWMENU type interface to access the choices? Alternative menu options, such as CHOOSE, or conditional branching from an INPUT variable, also work; but with DRAWMENU a segway into the world of graphics is bound to follow. Once you have the pixels at your command, you can do pretty amazing things.

-Dale-

DRAWMENU would be better, but for now I'm not so able to make one.
Please, help me to make one for the program!
Tomorrow, in the mean time, I'll try to add also calculation for yield for "leasing with residual": it's like use IRR, but I must generalize an example, first: lessee accept to pay in advance first and last rate; like a matrix with frequencies: [-CF0+advanced*PMT, 1][PMT, n-advanced][0, 1][residual_val, 1]: I must abstract a rule Smile

yes, I'd like to have a good menu, better, drawmenu: I must learn it...

Salvo


RE: A program to calc leasing - salvomic - 05-21-2015 08:47 AM

(05-20-2015 10:51 PM)DrD Wrote:  Regarding your latest share, the leasing program, have you considered using a DRAWMENU type interface to access the choices?
...

-Dale-

Dale,
I have put just now a new version with choose menu for the choices, thank you always for the tips and advice Smile
–•• ••– TU!

73, Salvo


RE: A program to calc leasing - DrD - 05-21-2015 10:33 AM

(05-20-2015 10:58 PM)salvomic Wrote:  <<<
DRAWMENU would be better, but for now I'm not so able to make one.
Please, help me to make one for the program!
Salvo
>>>

There may be several ways to approach this, but I keep a skeleton menu framework (program) in my "master program catalog," expressly for this. To use, just put routines (or subroutines) in between the (otherwise empty) IF END constructs, that relate to the soft buttons, as set up in DRAWMENU(). An example: the "Exit" soft button, (btn 6), and it's associated routine. Rename it to your program, and embellish as needed.

I hope you can find this useful, I know I sure have. One day, (maybe), I will take the time to try to work out how to do submenu popups, from DRAWMENU(). I started to do that once, but it quickly got to be a larger task than I wanted to deal with at that time. That is an exercise, as they say, left to the reader!

Grobs, using graphics commands, work well for creating dynamic, or interactive screen applications, made more useful when driven by soft menu selection on screen, from DRAWMENU(). Here's the code I use for this framework:

Code:

EXPORT menu()
BEGIN

  LOCAL m,m1,mx,my; // Mouse vars
  RECT();           // Clear Screen
  DRAWMENU("Btn1","Btn2","Btn3","Btn4","Btn5","Exit");     // Menu labels

  //Main loop 
  While 1 DO
    WHILE MOUSE(1)>=0 DO END;  // get mouse XY coordinates

    //Selection loop
    REPEAT
      m:=MOUSE;
      m1:=m(1);
    UNTIL SIZE(m1)>0;
      
    mx:=m1(1);
    my:=m1(2);
  
    // query softbuttons
    IF my>=220 AND my<=239 THEN

      // "Btn1" Menu button 1      
      IF mx>=0 AND mx<=51 THEN
     
      END;  //"Btn1" Btn 1

      // "Btn2" Menu button 2 
      IF mx>=53 AND mx<=104 THEN

      END;  //  "Btn2" btn 2

      // "Btn3" Menu button 3 
      IF mx>=106 AND mx<=157 THEN              

      END;    //  "Btn3" btn 3
    
      // "Btn" menu button 4
      IF mx>=159 AND mx<=210 THEN        
              
      END;   //  "Btn4" btn 4

      //"Btn5" menu button 5
      IF mx>=212 AND mx<=263 THEN  
       
      END;   //  "Match" btn 5

      // menu button 6 Exit
      IF mx>=265 AND mx<=316 THEN
        RETURN "Exit" ;
      END;   //  Menu btn 6
      
    END;  // Selection loop
  
  END;  // Main loop

END;  // program



RE: A program to calc leasing - salvomic - 05-21-2015 10:47 AM

(05-21-2015 10:33 AM)DrD Wrote:  There may be several ways to approach this, but I keep a skeleton menu framework (program) in my "master program catalog," expressly for this. To use, just put routines (or subroutines) in between the (otherwise empty) IF END constructs, ...

hi Dale,
thank you for the gift Smile
very interesting.
I'm seeing it and I think to use in some programs of mine...
For now about "Leasing" I'm using a simple choose menu, but maybe in the future I could change it...
I think to use your Drawmenu with "IRR" program, today I try a bit!

Salvo

EDIT:
I'm trying the skeleton...
How to return to menu from the functions?
I've having troubles with a simple code:
Code:

about()
BEGIN
PRINT("Something");
WAIT(0); CFmenu();
END;

When it revert to the Drawmenu (CFmenu) or also "Exit" button recall menu, or Prime hangs...

Thank you


RE: A program to calc leasing - salvomic - 05-21-2015 02:32 PM

with your help, Dale (DrD), khapster, Eddie, I'm debugging this menu based on Drawmenu and menu handler routine.

Please help me to debug.
i.e. when user press "Quit" soft key the program return to previous Print screen: any advise?

Code:

// Initialize procedures used in project
EVENTHANDLER();
PUTMENU();
GETMENU();

Leasing_advpmt();
Leasing_yield();
Leasing_residual();
Leasing_res_yield();

// Initialize variables used globally in project
mSEL;
eTYP;
kP;
m;
m1;

EXPORT Leasing()
BEGIN
// Initialize local variables used within this procedure
 LOCAL mx,my,mTXT,EXITPGM;

 // Set the menu text (this is softcoded and determines if a menu item is valid)
 mTXT := {"AdvPmt","Yield","Resid","ResYld","","Quit"};

 // MAIN CODE - Loop until ESC is pressed, then exit the program
 EXITPGM := 0;
 WHILE EXITPGM == 0 DO

   // Clear the screen and draw the menu
   RECT_P();
   PUTMENU(mTXT);

   // Flush the mouse buffer
   WHILE MOUSE(1) ≥ 0 DO END;

   // Loop until we have a keyboard or mouse event
   REPEAT
     EVENTHANDLER();
   UNTIL eTYP <> "";

    CASE

     // If the event type was a keyboard action then process it
     IF eTYP == "K" THEN
       // If the ESC key was pressed set the program to end
       IF kP == 4 THEN
         EXITPGM := 1;  
       ELSE
         // ESC was not pressed do what you want with the keypress, we are just going to do a TEXTOUT        
       END;        
     END;

     // If the event type was mouse action then process it
     IF eTYP == "M" THEN
       // Convert mouse coordinates to decimal
       mx := B→R(m1(1));  
       my := B→R(m1(2));
       // Determine if mouse coordinates are inside of a valid menu item otherwise return a zero
       GETMENU(mx,my,mTXT);
       // If a valid menu item was selected, do something, we are just going to do a TEXTOUT
       IF mSEL > 0 THEN
         CASE 
          // If menu item 1 was selected display a choose box for the user to select from
           IF mSEL == 1 THEN
             Leasing_advpmt();
           END;
           IF mSEL == 2 THEN
             Leasing_yield(); 
           END;
           IF mSEL == 3 THEN
             Leasing_residual();  

           END;
           IF mSEL == 4 THEN

Leasing_res_yield();
           END;
           IF mSEL == 6 THEN
             EXITPGM := 1;         
           END;
         DEFAULT
           // This is the default action for the menu selection and will only run if no case statement is satisfied

         END;
       ELSE
       // Mouse not in menu, do something if needed
       END;
     END;
   END;  
 END;
END;

// -------------------------------------------------------------------
// Detect keyboard or mouse input (keyboard has priority)
// -------------------------------------------------------------------
EVENTHANDLER()
BEGIN
 eTYP := "";
 kP := GETKEY;
 IF kP <> -1 THEN
   eTYP := "K";
 ELSE
   m := MOUSE;
   m1 := m(1);
   IF  SIZE(m1) > 0 THEN
     eTYP := "M";
   END;
 END;
END;

// ----------------------------------------------
// Draw the menu using the list passed in
// ----------------------------------------------
PUTMENU(mTXT)
BEGIN
 DRAWMENU(mTXT(1),mTXT(2),mTXT(3),mTXT(4),mTXT(5),mTXT(6));
END;

// ------------------------------------------------------------------------------------------
// Get the number of the menu item selected (1-6) by checking mouse position
// Menu items with empty/blank text will return a zero
// ------------------------------------------------------------------------------------------
GETMENU(mx,my,mTXT)
BEGIN
 mSEL := 0;
 IF my≥220 AND my≤239 THEN
   CASE
     IF mx≥0 AND mx≤51 AND mTXT(1)>"" THEN
       mSEL := 1;
     END;
     IF mx≥53 AND mx≤104 AND mTXT(2)>"" THEN
       mSEL := 2;
     END;
     IF mx≥106 AND mx≤157 AND mTXT(3)>"" THEN
       mSEL := 3;
     END;
     IF mx≥159 AND mx≤210AND mTXT(4)>""  THEN
       mSEL := 4;
     END;
     IF mx≥212 AND mx≤263 AND mTXT(5)>"" THEN
       mSEL := 5;
     END;
     IF mx≥265 AND mx≤319 AND mTXT(6)>"" THEN
       mSEL := 6;
     END;
   END;
 END;
END;

// ------------------------------------------------------------------------------------------
// LEASING APPLICATION CODE
// ------------------------------------------------------------------------------------------

Leasing_advpmt()
// solve for monthly payment
// by Salvo Micciché 2015 - Credits: kharpster
BEGIN
LOCAL r, n, fpmt, val;
INPUT ({r, n, fpmt, val},"Leasing: advance payments", {"yield%", "n lease", "n pmt advance", "value"}, 
{"Yield (rate)%", "Duration of lease", "Num of advance payments", "Value of Leasing"}, {0,0, 0, 0},{0,12, 3,0});
LOCAL npmt, pv;
npmt:= n - fpmt;
pv:= Finance.CalcPV(npmt, r, -1, 0, 12, 12, 1);
PRINT;
PRINT(
"Leasing with advanced payments

Value of lease: " + EVAL(val) + "
Duration of lease: " + EVAL(n) + "
Advanced payments n.: " + EVAL(fpmt) + "
Periodic payments n.: " + EVAL(npmt) + "
Yield (rate): " + EVAL(r) + "% 
Monthly payment: " + EVAL(val/(pv+fpmt))
);

WAIT;
RETURN val/(pv+fpmt);
END;


Leasing_yield()
// solve for yield
BEGIN
LOCAL n, fpmt, val, pmt, yield, npmt, pv;
INPUT ({n, fpmt, val, pmt},"Leasing: calc yield", {"n lease", "n pmt advance", "value", "payment"}, 
{"Duration of lease", "Num of advance payments", "Value of Leasing", "Monthly payment"}, {0,0, 0, 0},{12,3, 0, 0});
npmt:= n - fpmt;
pv:= fpmt*pmt-val;
yield:= Finance.CalcIPYR(npmt, pv, pmt, 0, 12, 12, 1);
PRINT;
PRINT ("Leasing: solving for Yield

Value of lease (loan): " + EVAL(val) + "
Duration of lease: " + EVAL(n) + "
Advanced payments n.: " + EVAL(fpmt) + "
Periodic payments n.: " + EVAL(npmt) + "
Monthly Payment: " + EVAL(pmt) + "
Monthly yield: " + EVAL(yield/12) + "% 
Yearly yield: " + EVAL(yield) + "%"
);
WAIT;
RETURN yield;
END;


Leasing_residual()
// Leasing with residual value, solve for monthly payment
BEGIN
LOCAL n, r, val, resval, fpmt, att, pv;
LOCAL npmt, pv2;
INPUT ({n, fpmt, r, val, resval},"Leasing with residual", {"n lease", "n adv pmt", "yield%", "value", "res value"}, 
{"Duration of lease", "Num advanced payments", "Yield (rate)%", "Value of Leasing (loan)", "Residual value"}, 
{0,0, 0, 0, 0},{12, 3, 0, 0, 0});
pv:= Finance.CalcPV(n, r,0, resval, 12, 12, 1);
att:= pv + val;
npmt:= n - fpmt;
pv2:= Finance.CalcPV(npmt, r, -1, 0, 12, 12, 1);
pv2:= pv2 + fpmt;
PRINT;
PRINT ("Leasing with residual 

Value of lease (loan): " + EVAL(val) + "
Residual value: " + EVAL(resval) + "
Duration of lease: " + EVAL(n) + "
Advanced payments n.: " + EVAL(fpmt) + "
Periodic payments n.: " + EVAL(npmt) + "
Yield (rate): " + EVAL(r) + "% 
Monthly payment: " + EVAL(att/pv2)
);
WAIT;
RETURN att/pv2;
END;

Leasing_res_yield()
// Leasing with residual value, solve for yield (rate)
BEGIN
LOCAL n, fpmt, val, pmt, resval, j, irr;
LOCAL flows:={}, yield, npmt, netamt;
INPUT ({n, fpmt, val, resval, pmt},"Leasing: calc yield", {"n lease", "n pmt advance", "value", "res val", "payment"}, 
{"Duration of lease", "Num of advance payments", "Value of Leasing", "REsidual value", "Monthly payment"},
{0,0, 0, 0, 0},{36,2, 0, 0, 0});
npmt:= n - fpmt;
netamt:= -val+pmt*fpmt; // net amount (-value + payment*advanced num pmt)
flows:= append(flows, netamt); // create list, append net amount
FOR j FROM 1 TO npmt DO
flows:= append (flows, pmt); // append payment, (num pmt - advanced pmt) times
END; // for
FOR j  FROM 1 TO (fpmt-1) DO
flows:= append (flows, 0);  // append 0, (mum advanced pmt minus 1)
END; // for
flows:= append(flows, resval); // append residual value
L1:= flows;
irr:= Solve.SOLVE(ΣLIST(MAKELIST((L1(I)/X^(I-1)),I,1,SIZE(L1))),X)-1;
// Solve.SOLVE() could not always work, but give only a secure value, solve() works better, butr gives more values
PRINT;
PRINT ("Leasing with advanced payments and residual value: yield 
Solved for IRR

Value of lease (loan): " + EVAL(val) + "
Residual value: " + EVAL(resval) + "
Duration of lease: " + EVAL(n) + "
Advanced payments n.: " + EVAL(fpmt) + "
Periodic payments n.: " + EVAL(npmt) + "
Monthly Payment: " + EVAL(pmt) + "
Net amount of cash advanced: " + EVAL(netamt) + "
Monthly yield: " + EVAL(irr*100) + "% 
Yearly yield: " + EVAL(12*irr*100) + "%"

);
WAIT;
RETURN 12*irr; // yearly yield (IRR) in decimal
END;



RE: A program to calc leasing - DrD - 05-21-2015 03:45 PM

(05-21-2015 10:47 AM)salvomic Wrote:  EDIT:
I'm trying the skeleton...
How to return to menu from the functions?
I've having troubles with a simple code:
Code:

about()
BEGIN
PRINT("Something");
WAIT(0); CFmenu();
END;

When it revert to the Drawmenu (CFmenu) or also "Exit" button recall menu, or Prime hangs...

Thank you

In the Main Loop, the skeleton is constantly waiting for mouse activity. Therefore the soft button menu should be present at all times. If something else is displayed at the soft button coordinates, and the contents of DRAWMENU() have disappeared due to other programmed activity, just serves to confuse a user, possibly ending up in some unanticipated routine.

The way to keep the DRAWMENU() present at all times is by controlling the graphics screen, (typically, GO). The way to do that is to use textout_p() instead of the print terminal. You would keep all text content above the lines reserved for the soft button menu. As mentioned previously, grobs, and graphics commands are the next step in program evolution.

Forget about the print terminal. Use the pixels on the screen to your advantage, where you control the location of text, foreground and background colors, text size, etc. It actually sounds more difficult to describe, than it actually is. I would suggest just to dive in, make some mistakes, and you'll be a pro before the weekend!

What you will end up with is your soft button menu present constantly. At any time you can jump into the menu's routines or exit, accordingly. A well designed soft button driven routine, will keep the user under control such that no unanticipated activity should occur. Simpler is better in constructing your programs, unless you have a need for speed. It makes debugging easier. Small self contained routines are easiest to debug (modular programming) and they fit nicely in between those IF END blocks in the skeleton.

I use this technique in the Smith Chart program, and to date, there is a lot of activity, such as rotating the text along the perimeter of the outer constant resistance circle, which could not be done without the graphics command set. I used graphics screen G1 to create "invisible" content, and BLIT_P() it back to GO, the user viewable screen, where, pixel by pixel, I recreate the font needed to appear as rotated text. I'm sure you will appreciate the programmer-side advantage once you get a handle on grob programming, and your programs will come alive for the user, in the end-game!

-Dale-


RE: A program to calc leasing - salvomic - 05-21-2015 03:57 PM

(05-21-2015 03:45 PM)DrD Wrote:  In the Main Loop, the skeleton is constantly waiting for mouse activity. Therefore ...
Forget about the print terminal. ...

I use this technique in the Smith Chart program, and to date, ...
I'm sure you will appreciate the programmer-side advantage once you get a handle on grob programming, and your programs will come alive for the user, in the end-game!

-Dale-

thanks a lot, Dale, I'm reading more time your advice here, I agree, and I will apply it by now.
I hope to rewrite the Printed Terminal rows into TEXTOUT_P soon, but first I must understand how to do when I recall EVAL(something) inside a line to print...

I'm sure some of you will have the patience to help me in that job Smile

Salvo

EDIT:
I've rewritten Leasing and Cash_Flow with TEXTOUT_P and eliminated Print() and MsgBox and the stability is greatly improved!


RE: A program to calc leasing - salvomic - 05-23-2015 05:15 PM

Leasing and ...mortgage.

In the HP Software Libraries for Prime (in this link) I put a program to calculate APR (Annual percentage rate) for a mortgage with fees (as percentile points %, fix amount or both).
The program use the powerful financial functions of the Prime.

ciao
Salvo