Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

How to Develop an Yearly Interest Calculator

0.00/5 (No votes)
21 Jan 2010 1  
An article that uses C# to develop a yearly calculation utility.

Introduction

When you study a .NET language like C#, you soon find out that there are many types of APIs that facilitate certain operations - mathematics, file I/O, thread synchronization, networking, and so forth - and thus reduce the complications that come with building an actually practical Windows application. This article will focus on building a practical Windows Forms application by using certain Math APIs that are defined in the Framework Class Library. Prior to stepping through the process of building such an application, however, this article will begin by describing some of these APIs, special characters, and numeric specifiers by using sample code. If the downloadable application does not appear to have any practical usage, it could function as a skeleton application on which to expand on or help the user to create something similar which does have practical use.

A basic math API which is used to raise one number to the power of another can be written as:

public static class Math {
  // method
  public static extern double Pow (double x, double y);
  ... 
}

Now, here is a very basic program that raises the number 16 to the 2nd power:

using System;
public class Application {
  public static void Main() {
    Console.WriteLine("Pow({0}, {1}) = {2}", 16, 2, Math.Pow(16, 2));
  }
}

Here is the output:

Pow(16, 2) = 256

Characters and Escape Sequences

In the .NET Framework, characters are always represented by 16-bit Unicode values. A character is represented with an instance of the System.Char structure (a value type) that offers two public read-only constant fields: MinValue is defined as '\0', and MaxValue is defined as '\uffff'. There is also a set of escape sequences that may be used to represent characters that are difficult to represent literally. For instance, when you hit the return key, your cursor drops down one line and then moves to the far left. This is called a carriage return line feed, and is often known as 0x0D and 0x0A, respectively. So, when you build a Windows application that is going to perform an operation and display the results in a multiline text box, these escape sequences play a part in the string formatting and their line placement:

  • \' \u0027 (39) Single Quotation Mark
  • \" \u0022 (34) Double Quotation Mark
  • \\ \u005C (92) Backslash
  • \0 \u0000 (0) Null
  • \a \u0007 (7) Bell
  • \b \u0008 (8) Backspace
  • \t \u0009 (9) Tab
  • \v \u000B (11) Vertical tab
  • \f \u000C (12) Form feed
  • \n \u000A (10) New line
  • \r \u000D (13) Carriage return

Below is a code snippet showing the use of some of these escape sequences:

using System;
public class Program {
  public static void Main() {
   Console.WriteLine("Alert \\a: {0} ({1})", '\a', (int)'\a');
   Console.WriteLine("Backspace \\b: {0} ({1})", '\b', (int)'\b');
   Console.WriteLine("Horizontal tab \\t: {0} ({1})", '\t', (int)'\t');
   Console.WriteLine("Newline \\r: {0} ({1})", '\r', (int)'\r');
   Console.WriteLine("Vertical quote \\v: {0} ({1})", '\v', (int)'\v');
   Console.WriteLine("Form feed \\f: {0} ({1})", '\f', (int)'\f');
   Console.WriteLine("Carriage return \\r: {0} ({1})", '\r', (int)'\r');
  }
}

This outputs like this:

Alert \a:  (7)
Backspace \b: (8)
Horizontal tab \t:       (9)
 (13)ne \r:
Vertical quote \v: ♂‚ (11)
Form feed \f: ♀ (12)
 (13)age return \r:

So, what is the point of showing a number raised to a power and a bunch of technical details about .NET Framework characters? Well, they are going to a pivotal role now that we can build an application. This application requires a Windows Form that has three Labels, two regular TextBoxes for user input, a NumericUpDown control, and a third multiline text box with a vertical scroll bar. The NumericUpDown control is nearly the same as the DomainUpDown with the restriction that its contents are numeric. Finally, a Button control is going to take two user input fields, principal and interest, and calculate the amount of the yearly account balance having earned that interest. The NumericUpDown control increments by one each time: so if you click from 1 to 2, you will get a second line of output with interest earned in the second line of the multiline text box. The NumericUpDown control's Minimum property is set to 1 and its Maximum property is set to 10. Its Increment property is set to 1 and its read-only property is set to true. The AutoSize property of all of the Labels is set to false to enable a clear 16 pt font using Times New Roman. Here is a look at the application without using it to calculate any interest earned:

Capture.JPG

And, here is a look at the interest earned for four years. The reader should take care to note that the interest earned appears as compound interest. The first year's amount of $10,000 at 36% interest simply earns $10,036. The second year's balance comes to $10,072.13, or $36 dollars and 13 cents more. Compounded interest would earn 36% on the $10,036, and not just add $36.00 to each year:

Capture1.JPG

Here is the code this application placed in one file, in order to compile it on the DOS prompt. In the directory "C:\Windows\Microsoft.NET\Framework\v2.0.50727", just type 'type con > Thefile.cs'. The cursor will drop to a blank screen where there is no prompt. Copy and paste the code onto the blank DOS windows, and compile the code with the '/target:winexe' switch:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

public partial class Form1 : Form
{
    private System.Windows.Forms.Button calculateButton;
    private System.Windows.Forms.TextBox principalTextBox;
    private System.Windows.Forms.Label label1;
    private System.Windows.Forms.TextBox interestTextBox;
    private System.Windows.Forms.Label label2;
    private System.Windows.Forms.NumericUpDown yearUpDown;
    private System.Windows.Forms.TextBox displayTextBox;
    private System.Windows.Forms.VScrollBar vScrollBar1;
    private System.Windows.Forms.Label label3;

    public Form1()
    {
        InitializeComponent();
    }

    private void InitializeComponent() {
        this.calculateButton = new System.Windows.Forms.Button();
        this.principalTextBox = new System.Windows.Forms.TextBox();
        this.label1 = new System.Windows.Forms.Label();
        this.interestTextBox = new System.Windows.Forms.TextBox();
        this.label2 = new System.Windows.Forms.Label();
        this.yearUpDown = new System.Windows.Forms.NumericUpDown();
        this.displayTextBox = new System.Windows.Forms.TextBox();
        this.vScrollBar1 = new System.Windows.Forms.VScrollBar();
        this.label3 = new System.Windows.Forms.Label();
        this.SuspendLayout();
        // 
        // calculateButton
        // 
        this.calculateButton.Font = 
        new System.Drawing.Font("Times New Roman", 14.25F, 
          System.Drawing.FontStyle.Bold, 
          System.Drawing.GraphicsUnit.Point, ((byte)(0)));
        this.calculateButton.Location = new System.Drawing.Point(310, 30);
        this.calculateButton.Name = "calculateButton";
        this.calculateButton.Size = new System.Drawing.Size(103, 33);
        this.calculateButton.TabIndex = 0;
        this.calculateButton.Text = "Calculate";
        this.calculateButton.UseVisualStyleBackColor = true;
        this.calculateButton.Click += 
         new System.EventHandler(this.calculateButton_Click);
        // 
        // principalTextBox
        // 
        this.principalTextBox.Location = new System.Drawing.Point(152, 30);
        this.principalTextBox.Name = "principalTextBox";
        this.principalTextBox.Size = new System.Drawing.Size(133, 20);
        this.principalTextBox.TabIndex = 1;
        // 
        // label1
        // 
        this.label1.Font = 
        new System.Drawing.Font("Times New Roman", 15.75F, 
        ((System.Drawing.FontStyle)((System.Drawing.FontStyle.Bold | 
        System.Drawing.FontStyle.Italic))), 
        System.Drawing.GraphicsUnit.Point, ((byte)(0)));
        this.label1.Location = new System.Drawing.Point(14, 33);
        this.label1.Name = "label1";
        this.label1.Size = new System.Drawing.Size(100, 23);
        this.label1.TabIndex = 2;
        this.label1.Text = "Principal";
        // 
        // interestTextBox
        // 
        this.interestTextBox.Location = new System.Drawing.Point(152, 105);
        this.interestTextBox.Name = "interestTextBox";
        this.interestTextBox.Size = new System.Drawing.Size(133, 20);
        this.interestTextBox.TabIndex = 3;
        // 
        // label2
        // 
        this.label2.Font = 
            new System.Drawing.Font("Times New Roman", 
            15.75F, System.Drawing.FontStyle.Bold, 
            System.Drawing.GraphicsUnit.Point, ((byte)(0)));
        this.label2.Location = new System.Drawing.Point(18, 105);
        this.label2.Name = "label2";
        this.label2.Size = new System.Drawing.Size(100, 23);
        this.label2.TabIndex = 4;
        this.label2.Text = "Interest";
        // 
        // yearUpDown
        // 
        this.yearUpDown.Location = new System.Drawing.Point(267, 178);
        this.yearUpDown.Maximum = 
           new decimal(new int[] {
             10,
             0,
             0,
             0});
        this.yearUpDown.Minimum = 
          new decimal(new int[] {
             1,
             0,
             0,
             0});
        this.yearUpDown.Name = "yearUpDown";
        this.yearUpDown.ReadOnly = true;
        this.yearUpDown.Size = new System.Drawing.Size(37, 20);
        this.yearUpDown.TabIndex = 5;
        this.yearUpDown.Value = 
          new decimal(new int[] {
             1,
             0,
             0,
             0});
        // 
        // displayTextBox
        // 
        this.displayTextBox.Location = new System.Drawing.Point(70, 298);
        this.displayTextBox.Multiline = true;
        this.displayTextBox.Name = "displayTextBox";
        this.displayTextBox.Size = new System.Drawing.Size(300, 120);
        this.displayTextBox.TabIndex = 6;
        // 
        // vScrollBar1
        // 
        this.vScrollBar1.Location = new System.Drawing.Point(353, 298);
        this.vScrollBar1.Name = "vScrollBar1";
        this.vScrollBar1.Size = new System.Drawing.Size(17, 120);
        this.vScrollBar1.TabIndex = 7;
        // 
        // label3
        // 
        this.label3.Font = 
        new System.Drawing.Font("Times New Roman", 12F, 
            System.Drawing.FontStyle.Bold, 
            System.Drawing.GraphicsUnit.Point, ((byte)(0)));
        this.label3.Location = new System.Drawing.Point(70, 238);
        this.label3.Name = "label3";
        this.label3.Size = new System.Drawing.Size(189, 23);
        this.label3.TabIndex = 8;
        this.label3.Text = "Your Account Balance is:";
        // 
        // Form1
        // 
        this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        this.BackColor = 
        System.Drawing.Color.FromArgb(((int)(((byte)(0)))), 
          ((int)(((byte)(192)))), ((int)(((byte)(0)))));
        this.ClientSize = new System.Drawing.Size(427, 451);
        this.Controls.Add(this.label3);
        this.Controls.Add(this.vScrollBar1);
        this.Controls.Add(this.displayTextBox);
        this.Controls.Add(this.yearUpDown);
        this.Controls.Add(this.label2);
        this.Controls.Add(this.interestTextBox);
        this.Controls.Add(this.label1);
        this.Controls.Add(this.principalTextBox);
        this.Controls.Add(this.calculateButton);
        this.Name = "Form1";
        this.Text = "Form1";
        this.ResumeLayout(false);
        this.PerformLayout();
    }

    [System.STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }

    private void calculateButton_Click(object sender, EventArgs e)
    {
        decimal principal;
        double rate;

        int year;
        decimal amount;
        string output;

        principal = Convert.ToDecimal(principalTextBox.Text);
        rate = Convert.ToDouble(interestTextBox.Text);
        year = Convert.ToInt32(yearUpDown.Value);
        output = "year\tAmount on Deposit\r\n";

        for (int yearCounter = 1; yearCounter <= year; yearCounter++)
        {
            amount = principal * ( ( decimal)
            Math.Pow(( 1 + rate / 100), yearCounter));
            output += (yearCounter + "\t" + 
              string.Format( "{0:C}", amount) + 
              "\r\n" );
        }
        displayTextBox.Text = output;
    }
}

Notice the event handler of the Button control. We first declare the data types that are represented by the first two Labels and the other necessary variables for the calculation. The output is considered a string type in order to format the calculation using the tab, carriage return, and new line escape sequences. The delimiter "{0:C}" stands for currency. So these variables get converted into numeric data types to then have the Names (property) of the first two TextBoxes and the NumericUpDown controls passed as parameters. They are then used within a for loop to iterate the years counted, incrementing each year by one. Afterwards, the string data type "amount" is calculated using the Math Power API to finally output the results in the multiline text box, whose Name is set to that output.

The reason the .NET Framework uses the 16-bit Unicode encoding scheme is to ease the complications involved with global development. C is a specifier that formats a string using the culture-aware currency attributes, such as symbols (money, separator) and significant number of digits.

References

  • Professional .NET Framework 2.0 by Joe Duffy
  • CLR via C# by Jeffrey Richter

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here