Annotated files NpvA.html and NpvA.java

Homework 0 of Computational Finance

Copyright © Philip H. Dybvig 1998
NpvA.html

The file NpvA.html is our program's interface to the "outside world." It is written in "hyper text markup language" (hence html), the default language of Web documents. In html, most items are labeled by matched tags. For example, <HTML> and </HTML> around the whole document indicate it is html. <HEAD> and </HEAD> indicate the head of the document, which contains only the title (marked by <TITLE> and </TITLE>) that shows in the top line of the browser. In the body of the document (between <BODY> and </BODY>) is the pair of tags <APPLET CODE=NpvA.class WIDTH=400 HEIGHT=350> and </APPLET>: this instructs the browser to include our applet at this point. Our applet tag has three arguments, CODE which gives the name of the class file, WIDTH which gives the width in pixels, and HEIGHT which gives the height in pixels. (Pixels, short for "picture elements," are the dots used to make up a picture.) Many other arguments can be used in an Applet tag, including user-defined arguments. Here NpvA.class is the name of the class file containing the class NpvA defining the applet. It is important that the two names agree (here they are both NpvA), including capitalization, even on systems that usually do not care about the case of file names.

One useful caution: the newest versions of Internet Explorer now like to edit (!) html files before saving them. This adds additional junk to the file and changes the file references to keep them pointing to my web page instead of letting them adjust to point to your directory. Using the ``html only'' selection in the ``save as'' dialog box in Internet Explorer should fix thie problem.

<HTML>
<HEAD>
<TITLE>A Simple NPV APPLET</TITLE>
</HEAD>
<BODY>
<APPLET CODE=NpvA.class WIDTH=400 HEIGHT=350>
</APPLET>
</BODY>
</HTML>
NpvA.java

NpvA.java is the program file that contains the actual java program. The compiler converts this program to "bytecodes" that are closer to machine language. Actual conversion to machine language would vary from machine to machine this is run on (and from operating system to operating system on the same hardware) and is not done at time of compilation.

This program does not use all the object-oriented features of the Java language (and indeed we will only scratch the surface of those features in this class): defining different panels as objects that are members of different classes would be more in that spirit. For example, each cash flow input line and the interest rate input line could all be made an object of the same type, whose properties would be specified in a separate class definition. Instead, we have a single class definition, the definition of the class NpvA, for the applet itself. This class definition extends the class Applet, which means that it inherits all the properties of applets (unless overridden) and has additional properties of its own. From a practical perspective, this extension (and inheritance of properties) is very helpful for avoiding duplicate effort and for maintaining consistency. When looking up information about a class, remember to check properties (variables and methods) from classes being extended as well.

Each class has a number of methods (functions) that perform operations in the class and variables that keep track of important data or states of the class. This is one of the features of object-oriented programming, characteristic of languages like C++ and java: the data and the functions used to manipulate the data are associated in a combined object. One important method in each class is a Constructor, which is a method with the same name as the class that is used to set up the object (construct it) the first time it is created.

This is the java 1.0 version of the applets. The exact details of how the applet responds to user input (e.g. the action method) are different in version 1.1. I do not suggest spending too much effort learning these features of the language.

Detailed comments are in the lines marked --> in the code below. This is not how comments are included in an actual Java file (use /* and */ instead).

/* NPV Applet (a lite application to get started) */

--> The text between /* and */ is a comment that is ignored by the
    compiler and is there to help out someone who looks at the
    program later (including the programmer, if some time has passed).

import java.applet.*;
import java.awt.*;

--> These two statements allow us to use the shortcut of omitting
    the prefix in some java classes below.  For example, we can write
    Applet instead of java.applet.Applet in defining NpvA.

public class NpvA extends Applet {

--> This says this is the class definition of the class NpvA and
    that objects in this class inherit the properties of the class
    Applet (short for java.applet.Applet), except as overridden here.
    The class is public since it will be referred to from outside this
    file (and specifically from the html file above).

--> About the { -- The pair { and } is used to surround a series of
    statements that give particulars of the class definition.  More
    generally, the pair { and } surround a series of statements that
    are to be treated as one statement.

  TextField c0,c1,c2,c3,c4,c5,R;
  Label npvchar;

--> A object is made up of variables and methods.  The TextFields
    (little input boxes) c0,c1,c2,c3,c4,c5, and R and the Label
    npvchar are the variables of an object in the class NpvA.  For
    these objects, space is reserved by these type declarations (and
    the types corresponding to the names are established), but the
    objects are created later.  There are additional variables not
    shown here that are inherited from the class Applet.

--> About ; -- Most statements in Java end with ;  Exceptions are usually
    statements that are "incomplete."  For example, the start of the
    class definition or method definition must be followed by the
    definition itself (usually in { and }) and is incomplete.  An
    example not used in this program is the if() syntax.  The statement
    if(x < 0) x = 0; rounds negative x up to 0.  There is no ; after
    the if part since that is not complete.  As another note, if many
    statements are included in { } to be treated as one, there is no
    following ; afterwards.  If you have a missing ; or an extra one,
    the compiler will give you an error.  Unfortunately, while the
    compiler will know there is an error it may not know the nature
    of the error.  As a result, the error message may be cryptic and
    seem to have nothing to do with ; at all.

  public NpvA() {

--> With rare exceptions we needn't worry about now, every class needs
    to have a constructor, which is a method that does whatever has to
    be done when an object of the class is first created.  The constructor
    is a public method (since creation is done from outside the object
    being constructed) with the same name as the class.  There can be
    many constructors with different argument lists; in this case there
    is just one constructor.  For example, this class could have a second
    constructor which is just the same except that it takes and uses an
    argument specifying the background color.

    setLayout(new BorderLayout());

--> This sets the layout of the applet to be in a format with a center
    and a border on all four sides.  Not all of the pieces need exist; in
    this case we have a "North" (top) piece and a "Center" piece.
    The center piece itself has two panels, and each panel is made up
    of smaller elements and some of them of even smaller elements.

    add("North",new Label("Sample NPV Applet",Label.CENTER));

--> In the "North" position, we have a simple label "Sample NPV Applet"
    which is itself centered right-to-left (as directed by the Label.CENTER
    argument).  If that argument were not included, the text would be
    left-justified by default.

    Panel centr = new Panel();

--> The center panel is created.  It is not yet included in the applet;
    the Java compiler does not know the name centr is related to where we
    plan to put the panel in the applet, which will be done later with another
    add() command like the one used to add the label at the top.

      centr.setLayout(new FlowLayout());

--> The layout for this center panel is a FlowLayout, which means that objects
    are put on the same line until there is no more space, at which point they
    continue on the next line.  GridLayout (which we see in a minute) would
    probably work just as well here.  What we are going to have is just two
    panels side-by-side.

      Panel leftcentr = new Panel();

--> The left part of the center panel is a new panel called leftcentr.

        leftcentr.setLayout(new GridLayout(7,1));

--> This left panel is set up in a grid of 7 rows and one column.

        leftcentr.add(new Label("Cash Flows",Label.CENTER));

--> The first row has the single label "Cash Flows" centered.

        Panel in0 = new Panel();
        in0.setLayout(new FlowLayout(FlowLayout.LEFT));
        in0.add(new Label("year 0"));
        in0.add(c0 = new TextField("-100",12));

--> The second row is a new panel with a flow layout giving a label "year
    0" on the left and a TextField c0 on the right.  This TextField is an
    input box where the initial cash flow is typed.  Its name c0 was declared
    above as the start of the definition of the class NpvA.  "-100" is the
    initial text in the textfield, and 12 is the width in characters.

        leftcentr.add(in0);

--> The second row is now added to the panel leftcentr.

        Panel in1 = new Panel();
        in1.setLayout(new FlowLayout(FlowLayout.LEFT));
        in1.add(new Label("year 1"));
        in1.add(c1 = new TextField("5",12));
        leftcentr.add(in1);
        Panel in2 = new Panel();
        in2.setLayout(new FlowLayout(FlowLayout.LEFT));
        in2.add(new Label("year 2"));
        in2.add(c2 = new TextField("5",12));
        leftcentr.add(in2);
        Panel in3 = new Panel();
        in3.setLayout(new FlowLayout(FlowLayout.LEFT));
        in3.add(new Label("year 3"));
        in3.add(c3 = new TextField("5",12));
        leftcentr.add(in3);
        Panel in4 = new Panel();
        in4.setLayout(new FlowLayout(FlowLayout.LEFT));
        in4.add(new Label("year 4"));
        in4.add(c4 = new TextField("5",12));
        leftcentr.add(in4);
        Panel in5 = new Panel();
        in5.setLayout(new FlowLayout(FlowLayout.LEFT));
        in5.add(new Label("year 5"));
        in5.add(c5 = new TextField("105",12));
        leftcentr.add(in5);

--> Rows 3-7 set up input boxes for cash flows in years 2-5 that
    are constructed in exactly the same way as row 2.

        centr.add(leftcentr);

--> This adds the panel leftcentr to the center panel.

    Panel rightcentr = new Panel();

--> This creates the right panel of the center panel in the applet.

      rightcentr.setLayout(new GridLayout(4,1));

--> The panel rightcentr is laid out in a grid of 4 rows and 1 column.

      rightcentr.add(new Label("Interest Rate (%):"));

--> The first row is the label "Interest Rate (%):" left-justified.

      rightcentr.add(R = new TextField("5",12));

--> The second row is the input cell for the interest rate.  This is
    called R as defined as a TextField variable earlier.

      rightcentr.add(new Label("The NPV is:"));

--> The third row is the label "The NPV is:"

      rightcentr.add(npvchar = new Label("",Label.LEFT));

--> The fourth row is the label npvchar which is going to be used for
    showing the computed NPV.

      npvchar.resize(180,npvchar.size().height);

--> The label npvchar is set to be 180 pixels wide.  (This command is
    deprecated, which is to say that there are other ways of doing it
    in later versions of Java beyond 1.0.)

      centr.add(rightcentr);
    add("Center",centr);

--> The panel rightcentr is added to the panel centr, and the panel
    centr is added to the applet.

    recalc();}

--> This says to "recalculate" the NPV with the initial values.  The
    } says that this is the end of the constructor NpvA().

  public boolean action(Event ev, Object arg) {
    if(ev.target instanceof TextField) {
      recalc();
      return true;}
    return false;}

--> This method is the one that is called when the applet detects input,
    and says that if the input is a change in a TextField, the method
    recalc() should be evoked.  Since this is a deprecated function (that
    is changed in later versions of Java), I would not worry about learning
    the details.

  double text2double(TextField tf) {
    return Double.valueOf(tf.getText()).doubleValue();}

--> This method extracts the text from a TextField and converts the text to
    the double-precision number it represents.  I was surprised I could not
    do this more simply, and if you know an easier way please tell me :-). 
    Starting with the TextField tf, its method .getText() extracts the text.
    Double.valueOf() converts the text to a Double, which is an object
    containing a double precision number and related methods, including the
    method doubleValue() which returns the double precision number itself.

  public void recalc() {
    npvchar.setText(String.valueOf(npv(text2double(R)/100.0,
      text2double(c0),text2double(c1),text2double(c2),text2double(c3),
      text2double(c4),text2double(c5))));}
  float npv(double r, double c0, double c1, double c2, double c3,
    double c4, double c5) {

--> This signifies the start of the definition of the method npv, which
    takes double precision numbers r (interest rate) and c0, c1, c2, c3, c4,
    and c5 (cash flows) and returns the NPV as a float (single precision real
    number).  

    double disc = 1.0/(1.0+r);

--> The discount factor disc is declared here to be double and then its value
    set to 1/(1+r).

    return((float) (c0 + disc*(c1 + disc*(c2 + disc*(c3 + disc*(c4 + disc*c5))))));}}

--> This computes and returns the npv.  The npv computation may look like an odd
    way of computing c0 + c1*disc + c2*disc^2 + c3*disc^3 + c4*disc^4 + c5*disc^5,
    but the telescoping formula is actually efficient and accurate.  The first } at
    the end closes the definition of npv(...) and the the second } closes the
    definition of the class NpvA.