Tag Archives: Calculator

Computational Chemistry is the Spice of Life

Actually, no, it isn’t. It’s pretty darn interesting, though.

Since AP Chemistry ran out of things to do (since we took the AP test), my teacher decided to assign our class a project: come up with a way to relate chemistry to your future career field. Easy, I thought. MIT has Course 6-7 (computational biology), so some sort of chemistry equivalent (computational chemistry) must exist somewhere on the Internet. As it turned out, I was spot on. Computational chemistry is big.

I started looking at computational chemistry software. All of it carried a steep learning curve and a steeper price tag, and I couldn’t really think of much high-level research, since I just finished AP Chemistry. Instead, I decided to take matters into my own hands. I thought it might be interesting to do some “exploration” around the Ideal Gas Law. At first, the goal of my project was simply to show that PV did indeed equal nRT. After I finished the first step, I started looking into why (hint: gas molecules aren’t very big). After that, it dawned on me that I could calculate an approximate value of R, the Universal Gas Constant.

What’s more, I wrote my program in Python:

#!/usr/bin/env python3
# Computational chemistry: does PV = nRT?
# Copyright (c) 2013 John Parsons. All rights reserved.
import sys
import random
import math
import copy
 
class Particle:
    """Gas molecule."""
    def __init__(self, vel, pos):
        """Creates a new object instance. Vel: (xVelocity, yVelocity, zVelocity). Pos = (x, y, z) coordinates."""
        # Set up variables
        self.velocity = vel
        self.position = pos
 
    def getListOfDistances(self, allParticlesInTank):
        """Gets a sorted list of distances between the current particle and all other particles. allParticlesInTank: list of all other particles."""
 
        particles = [x for x in allParticlesInTank if x.velocity != self.velocity and x.position != self.position] # Get a shallow copy of the particle list and remove the current particle
        particleDistances = [] # List of tuples that stores distances
 
        for particle in particles: # Loop through particles
            distance = 0
 
            # Quick way of implementing 3D distance formula
            for x in range(3):
                distance += (self.position[x] - particle.position[x])** 2
 
            distance = distance ** 0.5 # Take the square root
 
            particleDistances.append((particle, distance)) # Add the particle - distance tuple to the list
 
        return sorted(particleDistances, key = lambda x:x[1]) # Return particles sorted by their distance from the current particle
 
 
# Shameless self-promo        
print("compchem.py -- Copyright (c) 2013 John Parsons")
print("Compares simulated gas pressure with the Ideal Gas Law.")
# Print usage if user doesn't know what he's doing
if len(sys.argv) < 7:
    print("USAGE: python compchem.py TEMPERATURE_IN_KELVIN MOLAR_MASS_IN_GRAMS NUMBER_OF_PARTICLES ITERATIONS ATOMIC_RADIUS_PICOMETERS INTERMOLECULAR_COLLISIONS_TRUE-FALSE")
    print("EX: python compchem.py 300 16.00 1000 1000 200 True")
    exit()
 
# Constants / calculations to make the later code more verbose
AVOGADRO_NUMBER = 6.022 * (10 ** 23)
CUBE_SIDE_WIDTH = 1000000 # Bounds of simulation, in nanometers
SURFACE_AREA_M = (6 * (CUBE_SIDE_WIDTH ** 2)) * 10**-18 
NUMBER_OF_PARTICLES = int(sys.argv[3]) # User-defined number of particles to play with
GAS_CONSTANT = 8.3144621 # R
GAS_TEMPERATURE = float(sys.argv[1]) # T
GAS_MOLAR_MASS = float(sys.argv[2]) # M (grams -- note that we must convert to KG for momentum!)
GAS_PARTICLE_MASS = GAS_MOLAR_MASS / AVOGADRO_NUMBER # Convenient mass of single particle
GAS_SPEED = (3 * GAS_CONSTANT * GAS_TEMPERATURE / (GAS_MOLAR_MASS / 1000)) ** 0.5 # (3rt/m)^.5, root-mean-square velocity of gas
TANK_VOLUME = CUBE_SIDE_WIDTH ** 3 # Volume of container in nm^3, used later.
SIMULATOR_ITERATIONS = int(sys.argv[4])
ATOMIC_RADIUS = float(sys.argv[5]) # In picometers = 10**-12m
INTERMOLECULAR_COLLISIONS = False
if sys.argv[6].lower() == "true": # Whether or not to check for collisions between molecules
    INTERMOLECULAR_COLLISIONS = True
 
 
# Print all the simulation parameters (calculated and hard-coded) in a nicely formatted manner
print("Simulation paramaters:\r\n\tGAS_SPEED = " + str(GAS_SPEED) + " m/s\r\n\tGAS_MOLES = " + str(NUMBER_OF_PARTICLES / AVOGADRO_NUMBER) + " moles\r\n\tTANK_VOLUME = " + str(TANK_VOLUME) + " nm^3\r\n\tATOMIC_RADIUS = " + str(ATOMIC_RADIUS) + " pm\r\n\tCHECK_INTERMOLECULAR_COLLISIONS = " + str(INTERMOLECULAR_COLLISIONS) + "\r\n\tSIMULATION_TIME = " + str(SIMULATOR_ITERATIONS * 10**-8) + " s")
 
# Apply ideal gas law: num particles/Avogadro = n; GAS_CONSTANT = R, GAS_TEMPERATURE = T, tank_volume * 10**-24 = tank volume in m^3
IDEAL_PRESSURE = ((NUMBER_OF_PARTICLES / AVOGADRO_NUMBER) * GAS_CONSTANT * GAS_TEMPERATURE) / (TANK_VOLUME * (10 ** -27))
print("\r\nIdeal Gas Law calculated pressure: " + str(IDEAL_PRESSURE) + " Pa\r\n")
 
def velocityVectorWithSpeed(speed):
    """Creates a velocity vector with random direction and specified speed."""
    x = random.randint(-500, 500) # Create random vector components
    y = random.randint(-500, 500)
    z = random.randint(-500, 500)
    magnitude = (x**2 + y**2 + z**2)**0.5 # Magnitude of vector
    unitVector = (x/magnitude, y/magnitude, z/magnitude)
 
    return ([i * speed for i in unitVector]) # Return vector such that its magnitude is the specified speed
def randomPosition():
    """Generates a random tuple (x, y, z) that stores a position."""
    return ([random.randint(0, CUBE_SIDE_WIDTH) for x in range(3)])
 
particles = [] # list of particles
 
# Create all our cute little particles
for i in range(0, NUMBER_OF_PARTICLES):
    particles.append(Particle(velocityVectorWithSpeed(GAS_SPEED), randomPosition()))
 
sumOfMomenta = 0 # Used for storing total impulse imparted to walls of container
print("Simulating: 0/" + str(SIMULATOR_ITERATIONS) + "\r", end = "")
sys.stdout.flush() # Force printing
 
# Now run the simulation -- each iteration will represent 10^-8 seconds
for ii in range(0, SIMULATOR_ITERATIONS): # Do some number of 10**-8 second iterations (as defined by user)
    if ii % 100 == 0: # Make it pretty as hell
        print("Simulating: " + str(ii) + "/" + str(SIMULATOR_ITERATIONS) + "\r", end="")
        sys.stdout.flush() # Make it actually print
 
    for particle in particles: # Loop through all the particles
        repositionVector = ([x * 10 for x in particle.velocity]) # x m/s * 10**9 nm/m * 10**-8 s/iteration = nm/iteration
 
        # Loop through and change positions
        for i in range(3):
            particle.position[i] = particle.position[i] + repositionVector[i] # Adjust particle position
            if particle.position[i] >= CUBE_SIDE_WIDTH or particle.position[i] <= 0: # Check to see if we need to change direction
                particle.velocity[i] = particle.velocity[i] * -1 # We do! Now we need to figure out how much impulse is imparted
                if particle.position[i] >= CUBE_SIDE_WIDTH: # Prevent the particle from being turned around again by putting the particle where it should really be.
                    particle.position[i] = CUBE_SIDE_WIDTH - (particle.position[i] - CUBE_SIDE_WIDTH) 
                else:
                    particle.position[i] = -particle.position[i]
                # p = mv (mass in kilograms). J = delta p = dp
                dp = (GAS_PARTICLE_MASS * 2 * math.fabs(particle.velocity[i])) / 1000
                sumOfMomenta += dp
 
        # Now we do collision detection
        if INTERMOLECULAR_COLLISIONS:
            distances = particle.getListOfDistances(particles)
            for distance in distances:
                if distance[1] <= ATOMIC_RADIUS * 10**-3: # If they're too close together, we have a collision
                    # We had a collision!
                    print("Collision between molecules.")
                    sys.stdout.flush()
                else:
                    break # There will be no distances greater than this one
 
print("Simulating: " + str(ii + 1) + "/" + str(SIMULATOR_ITERATIONS), end="")
print("\n\r\nSum of momentum changes: " + str(sumOfMomenta) +" m*N")
 
# We ran for (10**-8 * SIMULATOR ITERATIONS) seconds; P=F/A; mv = Ft so P = mv/tA
ACTUAL_PRESSURE = sumOfMomenta / ((10**-8 * SIMULATOR_ITERATIONS) * SURFACE_AREA_M)
PERCENT_ERROR = (math.fabs(IDEAL_PRESSURE - ACTUAL_PRESSURE) / IDEAL_PRESSURE) * 100 # |actual-experimental|/actual
 
# Let the user know how we did
print("Average pressure: " + str(ACTUAL_PRESSURE) + " Pa")
print("Pressure error: " + str(PERCENT_ERROR) + "%")
 
if PERCENT_ERROR > 5:
    print("Percent error was too great; Ideal Gas Law did not hold.")
else:
    print("Percent error was reasonable; Ideal Gas Law held as expected.")
 
print() # Formatting
 
# Now calculate the simulated value of the gas constant
# PV/nT = R
ACTUAL_GAS_CONSTANT = (ACTUAL_PRESSURE * (TANK_VOLUME * 10**-27)) / ((NUMBER_OF_PARTICLES / AVOGADRO_NUMBER) * GAS_TEMPERATURE)
GAS_CONSTANT_ERROR = (math.fabs(GAS_CONSTANT - ACTUAL_GAS_CONSTANT) / GAS_CONSTANT) * 100 # Same error formula as above
 
print("Calculated gas constant: " + str(ACTUAL_GAS_CONSTANT) + " m^3*Pa*K^-1*mol^-1")
print("Gas constant error: " + str(GAS_CONSTANT_ERROR) + "%")
 
input("Press enter to exit.")

I won’t go into any sort of massive description of my code. I will go through a few points, though.

  • You will notice from my (likely very improvable) code that adding molecular collisions will add significantly to the running time of the program. 
  • You will get a significant amount of error when molecules are travelling very quickly. This is expected. The error, however, is on the wrong side of the Ideal Gas Law. It happens because particles literally escape the “test chamber” and thus are unable to impart pressure on the inside of its walls.
  • Low temperatures also create significant error.
  • Newtonian Mechanics are exclusively used. You won’t see Schrodinger’s Equation anywhere in this program. There are a few reasons for this. First, it’s written in Python, so it’s slow to begin with. Second, I have no idea what a partial differential equation is. I might come back to this issue next year!
  • Everything in the program is based on the idea that impulse, or change in momentum, is equal to force times change in time, which is equal to mass times the change in velocity. Thus, mass times change in velocity divided by total change in time is equal to total average force. Divide that by area and you get a pressure! Woo-hoo! Physics!
  • My code probably isn’t very “pythonic.” That’s because I don’t know Python very well. Yet. I’ll get better!
  • Estimation quality and computing time, as they should be, are inversely related (as opposed to the direct relation to time spent doing computational chemistry and fun). The more molecules you simulate for more time, the better your results will be. Fewer molecules give crappier results. Numbers in the thousands for both iterations and particles seem to do okay.

Here’s the program in action. Note the relatively accurate estimation! Fun-fun-fun!

Mmmmmm. Semiconductor chemistry simulating physics. I wonder if the transistors in my CPU feel like actors.

Mmmmmm. Semiconductor chemistry simulating more chemistry. I wonder if the transistors in my CPU feel like actors.

Oh. By the way. This trial eventually finished. FYI, the accepted value of the Universal Gas Constant is 8.3144621 m^3 Pa mol^-1 K^-1. We were off by about 0.0001–we had four sig figs of perfection!

Not bad for a rough approximation that uses "10^-20 moles of gas" and runs for "0.0001 seconds!"

Not bad for a rough approximation that uses “10^-20 moles of gas” and runs for “0.0001 seconds!”

Drawing the Mandelbrot Fractal in C#

I suppose you could say I had a deprived coding childhood; I already wrote about how I never calculated pi and now I am about to tell you that until this afternoon, I had never drawn the Mandelbrot set. I don’t know why I never took the time to do so, but as with the pi calculator, when I decided to plot the Mandelbrot set, I found a very interesting coding challenge waiting for me.

The first step in the process was to fix the notoriously slow Bitmap.SetPixel() method. I haven’t decompiled System.Drawing to look at .NET’s implementation but I assume it involves some sort of Marshal.Copy()ing of unmanaged bitmap data to a managed byte array, modifications to pixels in the managed byte array, and recopying the array to unmanaged memory. That’s well and good for setting three pixels. We’re going to render Mandelbrot sets of an arbitrary size; 2800×1600 is about 4.5 million pixels. Bitmap.SetPixel() would make this process way, way longer than necessary.

I created a class with a readable, writable bitmap as well as a method to set any of its pixels using unsafe code.

public class FastBitmap
{
    public FastBitmap(int width, int height)
    {
        this.Bitmap = new Bitmap(width, height, PixelFormat.Format24bppRgb);
    }
 
    public unsafe void SetPixel(int x, int y, Color color)
    {
        BitmapData data = this.Bitmap.LockBits(new Rectangle(0, 0, this.Bitmap.Width, this.Bitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
        IntPtr scan0 = data.Scan0;
 
        byte* imagePointer = (byte*)scan0.ToPointer(); // Pointer to first pixel of image
        int offset = (y * data.Stride) + (3 * x); // 3x because we have 24bits/px = 3bytes/px
        byte* px = (imagePointer + offset); // pointer to the pixel we want
        px[0] = color.B; // Red component
        px[1] = color.G; // Green component
        px[2] = color.R; // Blue component
 
        this.Bitmap.UnlockBits(data); // Set the data again
    }
 
    public Bitmap Bitmap
    {
        get;
        set;
    }
}

This class isn’t very useful outside of this program; it would need some modifications to use pixel formats other than 24bpp RGB. However, it gets the job done! The SetPixel method is what makes this class useful. It locks the provided Bitmap’s pixels, then gets a pointer to where the first color byte of the first pixel is in memory (Scan0.ToPointer()). It then figures out what the offset is to the pixel we want to modify. Finally, it creates a pointer to the pixel we want. It sets the blue, green and red to the specified color’s blue, green and red, then finally unlocks the bitmap data. When the data gets unlocked, it is saved in memory.

The SetPixel method presented here does not provide tremendous performance. It does, however, let you work with a bitmap fast enough that you won’t get bored. Most Mandelbrot rendering time is in calculations, anyway.

Now that we have an image class, we can get down to the math. The Mandelbrot fractal is based on the following formula:

Where C is the starting point on the complex plane and the starting value is zero.

Where C is the starting point on the complex plane and the starting value is zero.

The formula is given a starting value, C, that lies somewhere in the complex plane. If the formula (using C) does not tend to infinity, then C is part of the Mandelbrot set. If C tends to infinity, it is part of the Mandelbrot set. As a quick programmatic note, if the absolute value of Z sub N (the value of the formula after N iterations) ever becomes greater than two, the formula will tend to infinity.

Knowing that, we can start coming up with some pseudo-code:

for x on the screen:
  for y on the screen:
    scale (x, y) to the complex plane to figure out where we are
    c = where we are on the screen
    z = 0 + 0i
    b = a bitmap
    for i = 0 to however many iterations:
      z = z^2 + c
      if |z| > 2:
        plot (x, y) on b as some color that indicates how much "infinite tendency" there is at C
        break

If you read the Wikipedia article about rendering the Mandelbrot set, you will notice that it uses two real numbers to accomplish the same thing as one complex one. C# has a complex number class, which we will use in our code. However, before we talk about the actual rendering, we need a color palette. The members of the Mandelbrot set will be rendered black (or actually, based on the flow of the pseudo-code, not rendered at all), while the rest of the set will be rendered some color based on how many iterations it takes for the absolute value of Z to eclipse two. The more iterations it takes, the whiter the pixel. The fewer iterations, the bluer the pixel. It all comes together in the following (very simple) method:

public static List<Color> GenerateColorPalette()
{
    List<Color> retVal = new List<Color>();
    for (int i = 0; i <= 255; i++)
    {
        retVal.Add(Color.FromArgb(255, i, i, 255));
    }
    return retVal;
}

Okay, we can finally translate the pseudo-code into a real Mandelbrot-rendering method:

public static Bitmap DrawMandelbrot(int width, int height, double rMin, double rMax, double iMin, double iMax)
{
    List<Color> Palette = GenerateColorPalette();
    FastBitmap img = new FastBitmap(width, height); // Bitmap to contain the set
 
    double rScale = (Math.Abs(rMin) + Math.Abs(rMax)) / width; // Amount to move each pixel in the real numbers
    double iScale = (Math.Abs(iMin) + Math.Abs(iMax)) / height; // Amount to move each pixel in the imaginary numbers
 
    for (int x = 0; x < width; x++)
    {
        for (int y = 0; y < height; y++)
        {
            Complex c = new Complex(x * rScale + rMin, y * iScale + iMin); // Scaled complex number
            Complex z = c;
            for (int i = 0; i < Palette.Count; i++) // 255 iterations with the method we already wrote
            {
                if (z.Magnitude >= 2.0)
                {
                    img.SetPixel(x, y, Palette[i]); // Set the pixel if the magnitude is greater than two
                    break; // We're done with this loop
                }
                else
                {
                    z = c + Complex.Pow(z, 2); // Z = Zlast^2 + C
                }
            }
        }
    }
 
    return img.Bitmap;
}

Some notable points about this method:

  1. The rScale and iScale variables represent the change in real or imaginary value in the complex plane of each pixel on the screen.
  2. Some good parameters to pass to this method are rMin = -2.5, rMax = 1.0, iMin = -1.0 and iMax (no copyright infringement intended!) = 1.0.
  3. This method could be significantly improved on multi-core machines by dividing up the x-values to render and running a thread on each core. However, any rendering would have to be done after all the threads finished to avoid any cross-thread bit-locking issues. Luckily, the part that takes a while is the iterating, not the rendering.

That’s all it takes to draw a pretty good-looking Mandelbrot fractal. Here’s a fairly large one that you can give to your math teacher. I promise it will make him or her proud. I’m totally giving one to my math team coach as a New Year’s present.

Very blue...

Very blue…

Calculating Pi

One programming task that I had never taken on (up until this morning, anyway), was a pi calculator. Finding pi is not an overwhelmingly daunting task; one can get an extremely precise approximation from the System.Math.PI constant. However, that’s no fun. The real fun is in rolling your own pi calculator. As it turns out, this was no beginner project. It was math-heavy, theory-heavy and CPU-heavy. Oh, and it was a blast!

The trouble was that at first, I had no idea where to begin. In C#, there is no “arbitrary precision” decimal type; the decimal class can hold 28 or so significant figures (remember the calculator tutorial?). No self-respecting pi calculator would ever stop at 28 significant figures. 28,000 would be a bit better! The first challenge in coding the pi calculator would be coming up with a way to store an unlimited number of significant figures. I’d read about some pi calculator authors implementing “BigFraction” or “BigRational” classes based off of the fairly new BigInteger (arbitrarily-sized .NET integer) class, so I thought I’d take a crack at writing one of those. I also decided that before I wrote a single line of code, I needed to choose a pi calculation formula.

The requirements for a formula are simple: that it converges relatively quickly and requires relatively few calculations per iteration. Unfortunately, the use of a “BigRational” class adds another requirement: no fractional powers of numbers that have irrational fractional powers. That’s a real drag, because it means we can’t use the Chudnovsky Algorithm, which is the Holy Grail of fast pi calculation algorithms:

The trouble is with the 3k + 3/2 part; 640320 is not a perfect square (it is almost 800.2^2, but not quite).

The trouble is with the 3k + 3/2 part; 640320 is not a perfect square (it is almost 800.2^2, but not quite).

With the really good algorithm out of the way, I started trying to find another good algorithm. My first thought took me back to my trig identity days a few years ago (okay, the past three years of high school):

So then if you take the deriv... actually, no.

So then if you take the derivat… actually, no.

This is actually a sound, correct thought. In fact it has a name: the Gregory-Leibniz formula. This will eventually converge to pi. However, after following a link off the handy, dandy Wikipedia page I used to decide which algorithm I would use in my program, I learned that it takes five billion iterations of arctan(1) (which I will get to in a moment) to produce ten correct digits of pi. YIKES! It was a good thought.

Anyway, I eventually decided on the original Machin formula, from 1706:

Although it was created in 1706, Wikipedia says it is still one of the fastest-converging pi-calculation algorithms!

Despite its age, it converges quickly and is relatively easy to compute.

Awesome. We have a formula. Now we need to figure out how an arctangent can be computed. It is actually rather simple, especially with programmatic help:

See. Not that bad.

See. Not that bad.

Alright! We have the formula for computing pi and we have the formula for computing arctangent, so now we’re done. Not so fast. Remember when I mentioned the BigRational class? As it turns out, writing a BigRational class is the bulk of this project. I won’t bore you with too many tiny details of the way I implemented it; I will tell you that it was designed for simplicity over speed. It definitely needs some refining, but it works.

The basic concept behind the BigRational class is simple: it is a fraction. It has a numerator and a denominator. The numerator and denominator are arbitrarily-precise, so the entire ratio is arbitrarily-precise. The class has a bunch of methods to help the numerator and denominator do their fraction-y duty:

As it turns out, a lot of help.

As it turns out, a lot of help.

Most of the methods listed in the class diagram are pretty self-explanatory; I won’t go into detail here (but you can download the source code to the project at the bottom of the page). All the operators help the BigRationals play well together, and the * operator has an overload that allows “scalar” multiplication. That is, it allows multiplication by a BigInteger.

The two methods that I will delve into are the Reduce method and the ToDecimalString method. The Reduce method reduces a BigRational into its simplest form. It implements Euclid’s Algorithm, which is a means of reducing a fraction. It works in steps:

  1. The larger of the numerator and the denominator is set as the “big number.” The smaller is set as the “small number.”
  2. The program finds the remainder when the big number is divided by the small number.
  3. If the remainder is not zero, the small number becomes the big number and the remainder from step two becomes the small number.
  4. If the remainder is zero, both the numerator and denominator may be divided by the small number. At this point, the small number is the greatest common factor of the numerator and denominator.
  5. Steps 2, 3 and 4 are repeated until step four terminates with the small number equal to one. At this point, the fraction is in simplest form.

In code, the above steps look like this:

public void Reduce()
{
    // Set up big and small number
    BigInteger bigNumber, smallNumber = 0;
    if (Numerator > Denominator)
    {
        bigNumber = Numerator;
        smallNumber = Denominator;
    }
    else
    {
        bigNumber = Denominator;
        smallNumber = Numerator;
    }
 
    // Now divide a bunch of times
    while (smallNumber != 1)
    {
        // Find the remainder
        BigInteger rem = (bigNumber % smallNumber);
        if (rem != 0)
        {
            bigNumber = smallNumber; // Set up the numbers for the next iteration
            smallNumber = rem;
        }
        else
        {
            // We can divide both the numerator and denominator by the previous remainder
            Numerator /= smallNumber;
            Denominator /= smallNumber;
 
            // Re-assign bigNumber and smallNumber
            if (Numerator > Denominator)
            {
                bigNumber = Numerator;
                smallNumber = Denominator;
            }
            else
            {
                bigNumber = Denominator;
                smallNumber = Numerator;
            }
        }
    }
 
    // One last thing -- if the numerator is positive and the denominator is negative, the numerator needs to become negative and the denominator needs to become positive.
    // If they're both negative, they should both be positive
    if (Denominator < 0 && Numerator > 0 || Numerator < 0 && Denominator < 0)
    {
        Numerator = -Numerator;
        Denominator = -Denominator;
    }
}

The only change between the pseudo-code and actual implementation was the addition of the small if-statement at the bottom. I noticed that the denominator would sometimes be negative instead of the numerator being negative. That would probably throw off some calculations, so I made sure that only the numerator of the BigRational could ever be negative.

The ToDecimalString method converts a BigRational into its decimal equivalent — a handy helper when it comes to calculating pi (since it’s no fun unless it starts with 3.14159…). I considered two different implementation styles:

  1. Multiplying the entire fraction by 10^however many digits I wanted.
  2. Creating my own long division algorithm that would return a string of digits of a specified length.

Contrary to what seems sane, I chose the second method. I suppose it was partially because I had always wanted to write an actual long division algorithm, but by any means, it took some head-scratching at first. Long division isn’t something I have to do very much, so I started by doing out a few long division problems. As it turns out, there is a nice pattern. The non-decimal part of the number may be calculated in one fell swoop by using integer division. It may then be committed to a string. After that, a decimal point should be committed to the string. Then, a “new numerator” should be created. Its value is the remainder from the previous iteration multiplied by ten. The next decimal digit is equal to the “new numerator” minus the remainder when it is divided by the denominator of the fraction, all divided by the denominator of the fraction. This process can be repeated until the desired number of digits is reached.

Okay, it makes more sense in code. Wow.

public string ToDecimalString(BigInteger decimalDigits)
{
    StringBuilder rv = new StringBuilder();
    this.Reduce(); // Go as fast as possible
    BigInteger remainder = Numerator % Denominator;
 
    // Get the non-decimal part
    rv.Append(((Numerator - remainder) / Denominator).ToString() + ".");
    remainder = Numerator % Denominator;
 
    BigInteger newNum = remainder * 10;
 
    // Now get the decimal part
    for (BigInteger i = 0; i < decimalDigits; i++)
    {
        rv.Append(((newNum - (newNum % Denominator)) / Denominator).ToString()); // This literally just does long division
        newNum = (newNum % Denominator) * 10;
    }
 
    return rv.ToString();
}

The only real advantage this method presents is the lack of any string parsing. It is all basic use of a StringBuilder. Plus, it seems to work very well!

With the BigRational class done, the next step was the actual pi calculation. The first step was to implement an arctangent method, in accordance with the formula I mentioned earlier.

public static BigRational ArcTangent(BigRational input, BigInteger iterations)
{
    BigRational retVal = input;
    for (BigInteger i = 1; i < iterations; i++)
    {
        // arctan(x) = x - x^3/3 + x^5/5 ...
        // = summation(n->infinity) (-1)^(n) * x^(2n+1)/(2n+1)
        BigRational powRat = input.Pow((2 * i) + 1);
        retVal += new BigRational(powRat.Numerator * (BigInteger)Math.Pow(-1d, (double)(i)), ((2 * i) + 1) * powRat.Denominator);
        if (i % 100 == 0)
        {
            Console.WriteLine("ArcTangent {0}: {1}/{2} iterations complete.", input, i, iterations); // Status update.
        }
    }
 
    return retVal;
}

Wait. There’s a parameter called “iterations.” How do we figure out how many iterations are necessary? This page provided the answer. As it turns out…

I find it's a good idea to add twenty or so digits to the end to make sure everything is correct.

I find it’s a good idea to add twenty or so digits to the end to make sure everything is correct.

In other words…

public static BigInteger GetConversionIterations(BigInteger digits, BigRational q)
{
    return (BigInteger)((double)digits / (2 * Math.Log10((double)q.GetReciprocal())));
}

That was quick. That also finished laying the foundation for actually calculating pi. Phew. That was a lot of keystrokes.

public static BigRational GetPi(BigInteger numDigits)
{
    // pi = 16 arctan(1/5) − 4 arctan(1/239)
    BigRational oneFifth = new BigRational(1,5);
    BigRational oneTwoThirtyNine = new BigRational(1, 239);
    BigRational arcTanOneFifth = PiCalc.ArcTangent(oneFifth, PiCalc.GetConversionIterations(numDigits + 1, oneFifth)); // Start computing
    BigRational arcTanOneTwoThirtyNine = PiCalc.ArcTangent(oneTwoThirtyNine, PiCalc.GetConversionIterations(numDigits + 1, oneTwoThirtyNine));
 
    return (arcTanOneFifth * 16) - (arcTanOneTwoThirtyNine * 4);
}

This code block implements Machin’s formula as discussed above. An improved version of this program could take advantage of multi-core computing by calculating one arctangent on one thread and the other arctangent on another. More formulas should also be tested to determine which is the fastest; this program really slows down as the iteration count gets higher because the fractions get really, really, really huge. Of course, this program was never going to break any records anyway because it was written in C#. JIT-compiled, super high-level languages aren’t exactly speed demons. Then again, my Phenom II x4 (overclocked to 3.7 gHz) is also beginning to show its age. I’d be curious to see how performance compares on one of the latest-generation i7s.

Although it is sluggish, it does seem to compute pi properly. Here are the first 10,001 digits:

Although it looks like a lot of pi, it's not a lot of pi.

Although it looks like a lot of pi, it’s not a lot of pi.

So that’s it. It’s done. It works. Now it just needs to run for a few days so I can brag to my friends! The funny thing about calculating pi is how although we believe pi is completely irrational and will never end, we’ve calculated enough digits that it might as well end. If my calculations are correct, it only takes about 80 digits of pi to calculate the volume of the observable universe to the nearest cubic meter. Thus, ten thousand would calculate it to the nearest 1/10^9920 cubic meter, whatever that would be. That’s some mind-blowing precision. Imagine what a million digits would do.

Download this Project (MIT License)

Porting my Calculator to Python

Although the first language I actually learned was VB.NET, Python is what actually inspired me to begin programming. My dad talked me out of learning it (one of my friends suggested that I did); who knows what kind of programmer I would be today if I had learned it. My guess is that I would be better with server-sided activities and worse on the desktop. Perhaps I’d be more of a Linux guy.

Anyway, I got inspired to learn Python yesterday for whatever reason, and today, I decided to port my calculator to Python. For the sake of comparison, I stayed fairly true to my original C# program. Here’s the very annoying program I came up with (it has no way to exit and loops forever so you have to close the console if you want to close it):

# Python calculator program
# This is the first Python program I've written for a LONG time.
def main():
	while 1==1:
		try:
			number1 = float(raw_input("Enter a number, then hit enter: "))
			number2 = float(raw_input("Enter another number, then hit enter: "))
			operator = raw_input("Which operation do you want? (Choose +, -, * or /, then hit enter): ")
			if operator == "+":
				print "The sum is:", Add(number1, number2)
			elif operator == "-":
				print "The difference is:", Subtract(number1, number2)
			elif operator == "*":
				print "The product is:", Multiply(number1, number2)
			elif operator == "/":
				print "The quotient is:", Divide(number1, number2)
			else:
				print "Please choose another operator."
 
		except:
			print "Error, please try again."
 
		print "\r\n"
 
def Add(num1, num2):
	return num1+num2
 
def Subtract(num1, num2):
	return num1-num2
 
def Multiply(num1, num2):
	return num1*num2
 
def Divide(num1, num2):
	return num1/num2
 
main()

Here it is in action, running in PowerShell:

Python Calculator Image

You can do the four most basic operations over and over! Woo!

In doing this port, I noticed that my beginner-targeted C# code was way longer than it needed to be (with all the helper methods) but very easy to understand. I also noticed a lot of things about Python, some of which I liked and some of which I did not.

The Good

  • The console print command makes it very easy to concatenate variables in.
  • In the small program I had, relying on indentation instead of { } to organize code saved a lot of screen space.
  • The raw_input() function serves as an equivalent to Console.WriteLine(), Console.ReadLine() in C#, saving more keystrokes.
  • Overall simplicity and intuitiveness. I’m a C# developer, not a Python developer, but I was able to complete this port with a little help from Google. Python operators were similar to the C# ones and the syntax isn’t difficult to understand at all. I can read Python code and understand much of what it does, unlike Ruby programs which tend to make my eyes glaze over.

The Not-So-Good

  • I’m not sure how well the whole indentation thing would work in a huge program. Things are bound to get mixed up eventually. Still, I’ve spent plenty of time counting curly brackets trying to figure out why my code won’t compile, so it may just come down to preference.
  • Lack of strong typing. I’m used to seeing float number1, not just some random variable declaration. Again, things could get confusing, especially if you forget what a variable is for.
  • The variable declaration syntax. It makes copy and pasting code much easier not having to get rid of keywords, but it is nice to know that you are declaring a variable for the first time, even if it is with the var keyword in JavaScript.
  • This page says, “Java is a pair of scissors, Ruby is a chainsaw.” That’s fair enough, but where does Python figure into things? Does it have enough horsepower to get things done or should I stick with my C#?

Even with its flaws, I do rather like Python. XKCD sums it up pretty well. I think I will try writing some more programs in it. Heck, I might do some server-sided things with it. Learning another programming language can’t possibly be a bad thing.

Creating a Calculator with C# Part 7: Tying up the Loose Ends

This is it. We’re done after this. That’s right – I will cast you off into the land of C#. Alone. It’s a sort of sad reality.

In this tutorial, we’re going to fix all those funky behaviors that happen in our calculator but not the Windows one with the help of two Boolean variables – resetFlag and allowDecPoint. You should declare both of them as class variables and set them to true right off the bat.

public partial class frmMain : Form
{
    // ...
    bool resetFlag = true;
    bool allowDecPoint = true;
    // ...

resetFlag will be used to figure out if the display TextBox needs to be reset when one of the numbers or the decimal point is hit. You can see that “resetting” behavior very frequently in the Windows calculator:

  • Whenever one of the operator buttons or the equals button is clicked
  • Whenever one of the memory buttons is clicked
  • Whenever one of the one-number operations (like square root) is conducted
  • Whenever the calculator displays zero (such as when it first starts up or after the user clicks CE or C)
When resetFlag is set to true, the user will not be able to backspace with the ← button.

The allowDecPoint variable should seem more obvious to you – numbers may only contain one decimal, so after one is put in the display TextBox, no more can be added. This prevents number parsing errors. Notice the glaring lack of error checking in our math. It is not because we don’t assume our users are morons, but because we are simply going to safeguard the code.

Now, let’s start adding places where resetFlag will be set to true. It should be set to true at the end (with the last line of code) of the following parts of our massive if statement:

  • else if (btn.Text == “*” || btn.Text == “/” || btn.Text == “+” || btn.Text == “-”)
  • else if (btn.Text == “=”)
  • else if (btn.Text == “√”)
  • else if (btn.Text == “%”)
  • else if (btn.Text == “1/x”)
  • else if (btn.Text == “MC”)
  • else if (btn.Text == “MR”)
  • else if (btn.Text == “MS”)
  • else if (btn.Text == “M+”)
  • else if (btn.Text == “M-”)
  • else if (btn.Text == “C”)
  • else if (btn.Text == “CE”)

Notice that the pieces of code listed above correspond to the behaviors I described earlier. Coding gets a lot easier when you plan out what you want to do, then write it. It isn’t a dark art. Moving on, we’ve set resetFlag to true in a whole bunch of places but not to false once. That’s a problem. The actual resetting gets done when a user clicks one of the number buttons or the decimal button, so the first part of the if statement seems like a logical place to stick some code. When we reset the display TextBox, we will clear its text, set resetFlag to false, and set allowDecPoint to true, since there is no decimal in the TextBox.

if ((char.IsDigit(btn.Text, 0) &amp;&amp; btn.Text.Length == 1) || btn.Text == ".")
{
    if (resetFlag)
    {
        txtDisplay.Clear();
        resetFlag = false;
        allowDecPoint = true;
    }
    // ...

Now, we need to implement one more tiny piece of the resetFlag modification. Remember when I mentioned that the user can’t backspace when resetFlag is set to true?

else if (btn.Text == "←")
{
    if (txtDisplay.TextLength &gt; 0 &amp;&amp; !resetFlag)
    {
        txtDisplay.Text = txtDisplay.Text.Remove(txtDisplay.TextLength - 1);
    }
}

We’ve added a “&& !resetFlag”. We went over what && is in the last lesson: it’s a logical AND, so for the code within this if statement to execute, txtDisplay’s text length must be greater than zero and !resetFlag must be true. We haven’t covered ! yet. ! is the NOT operator. It is used with Booleans and causes it to behave in the opposite manner from which it is set. That is, !true is false and !false is true. Therefore, in the code above, resetFlag must be false for the code to execute.

Let’s move on to the other variable. You won’t have to add as much code for this one – we only have to make sure allowDecPoint is true when we append a decimal and set allowDecPoint to false when we do. We don’t have to worry about allowDecPoint when we add any other numbers, so we just append the text. Modify the first part of your if statement to look like this:

if ((char.IsDigit(btn.Text, 0) &amp;&amp; btn.Text.Length == 1) || btn.Text == ".")
{
    if (resetFlag)
    {
        txtDisplay.Clear();
        resetFlag = false;
        allowDecPoint = true;
    }
    if (btn.Text == "." &amp;&amp; allowDecPoint)
    {
        txtDisplay.Text += btn.Text;
        allowDecPoint = false;
    }
    else if (btn.Text != ".")
    {
        txtDisplay.Text += btn.Text;
    }
}

The second if statement inside the larger if statement checks to see if allowDecPoint is true if the button text is “.”. If so, it allows the decimal to be appended. Otherwise, the != operator (not equal to) is used to see if the button’s text does not equal “.”. If it does not, it is a number so it gets added to the TextBox. Notice that if btn.Text is “.” and allowDecPoint is false, nothing happens, so it is not added to the TextBox.

Now, remember the reciprocal DivideByZeroException possibility I mentioned in the last lesson? We’re going to fix that now with another if statement. Rather than allowing the exception to be thrown, you should stop the problem in its tracks. Instead of using a try…catch statement, we’ll use an if statement to see if the value is zero before we divide. If so, we’ll just set the display value to zero:

else if (btn.Text == "1/x")
{
    decimal currVal = decimal.Parse(txtDisplay.Text);
    if (currVal != 0)
    {
        currVal = 1 / currVal;
        txtDisplay.Text = currVal.ToString();
    }
    else
    {
        txtDisplay.Text = "0";
    }
    resetFlag = true;
}

In this case, we use an else instead of an else if because it saves keystrokes – something is either zero or not, so there is no need to type out “else if (currVal == 0)”. If currVal != 0 and currVal == 0 are both false in the same if statement, something is seriously wrong.

Finally, we’ll make some changes to C and CE. Rather than clearing the TextBox, since we set resetFlag to true in both sections, we’ll set txtDisplay to zero like the Windows calculator does.

else if (btn.Text == "C")
{
    workingMemory = 0;
    opr = "";
    txtDisplay.Text = "0";
    resetFlag = true;
}
else if (btn.Text == "CE")
{
    txtDisplay.Text = "0";
    resetFlag = true;
}

To be consistent, open up the designer and set txtDisplay’s Text property to “0″ in the designer. Since resetFlag is true to begin with, it will just be erased when the user hits a button.

We have one last thing to do now: preventing the user from adding leading zeros to a number. Users should not be able to enter something like “00000016″. This isn’t binary! Accomplishing this actually took some trial-and-error, but it is actually trivial to emulate the behavior of the Windows calculator. Change your if(resetFlag) code to look like this:

if (resetFlag)
{
    txtDisplay.Clear();
    if (btn.Text != "0")
    {
        resetFlag = false;
    }
    allowDecPoint = true;
}

This way, the text will be reset again if the user hits zero.

You have been building up to this moment for seven lessons. You should feel very proud of yourself. You have gone from a beginner-level, “Hello World” tutorial to a console calculator to a calculator with a Windows GUI and 28 buttons that closely emulates the functionality of the Windows calculator when it is set in standard mode. Your calculator could be used as what we call a “little blue crutch” in school – a four-function calculator without graphing capability. With some of your new C# skill, you could write a program that graphs equations.

I know that the calculator is a common project for beginners. New developers all go through the “creative” stage, where they write more software than Microsoft. It’s a good thing – I’ve been there. My old computer had a hard drive with perhaps 50 Visual Studio projects, of which perhaps four were done. But still, I had lots of fun. Here are some projects that I enjoyed that you probably will, too:

  • A “network messenger” chat system that can either be connection-less (done with UDP instead of TCP) or use a client-server system (done with TCP, more advanced).
  • A video/media player. If you want, write some visualizations for it. Check out the Bass.NET library.
  • A YouTube downloader. I understand that this is way harder than it used to be. This project was particularly fun – I wrote a plugin system for the conversion formats (including my own FLV music extractor) and later ported it to Python on Ubuntu.
  • A rich text editor.
  • A web browser. Check out .NET’s WebBrowser control. Note that it’s IE-based, so you’ll come to hate it and want to check out WebKit.NET.
  • Pong.
  • A clock or alarm clock.
  • An email client – at least something to send emails. Receiving them is a lot harder (I stopped on mine when I got to MIME parsing).
  • Your own scripting or programming language. I wrote one called BeepScript then wrote a program to play Mario in computer beeps. Fun, fun, fun!
  • A Craigslist watcher.
  • An IDE for .NET similar to Visual Studio. Look into System.Reflection – you can compile .NET code very easily!
  • A .NET disassembler similar to ildasm.exe. Your C# code is actually compiled to a series of “opcodes” that aren’t machine code. The opcodes can be disassembled to CIL (Common Intermediate Language), which is basically .NET assembler. There are methods that allow you to disassemble .NET assemblies within the .NET framework.
  • An operating system. This isn’t very possible in C# (I say very because of COSMOS) but is lots of fun if you really want to learn what is going on with a computer.
  • A screenshot taker.
  • A drawing program or photo editor (or even photo cropper) similar to Microsoft Paint.
  • An RSS reader.

Here are some resources you might find helpful:

Whatever you choose to do, I wish you the best of luck with it. Thank you very much for reading this tutorial series. I hope it was helpful and I truly hope it sparked your interest in programming.

Click here to download my project (requires a VS product from 2010 or later).

A note on the licensing: You will notice that there is a file called license.txt in the root directory of the project. This project uses the MIT license. The MIT software license grants me the copyright (since I wrote it) and gives you unlimited rights to use the code in this project. I would have provided the source as a public domain dedication, but unfortunately, some nations do not have a “public domain”. The MIT license is about as close to the public domain as one can get with a license – you may sell this calculator if you want! I’m not saying that people would buy it.

If you do something interesting with it, I’d love to hear about it in a comment!

Creating a Calculator with C# Part 6: Making Your Calculator Function

In the last part of this tutorial series, you learned how to stick numbers into your TextBox. Hopefully you’re feeling fairly proud of yourself at this point. In this tutorial, we’ll implement the “calculator” part of the whole operation. To sum it up, we’ll make it function. Integral to the whole thing is the “if…elseif…else” statement we learned earlier (the math puns are now over). We’ll be using that to check the button text in our button click method. Based on the button text, the calculator will do something. Unfortunately, we haven’t attached all the Button.Click events yet. Let’s do that now. I won’t force you to type it all out if you don’t want to (I can understand why!).

public frmMain()
{
    InitializeComponent();
 
    btn0.Click += new EventHandler(ButtonClickHandler);
    btn1.Click += new EventHandler(ButtonClickHandler);
    btn2.Click += new EventHandler(ButtonClickHandler);
    btn3.Click += new EventHandler(ButtonClickHandler);
    btn4.Click += new EventHandler(ButtonClickHandler);
    btn5.Click += new EventHandler(ButtonClickHandler);
    btn6.Click += new EventHandler(ButtonClickHandler);
    btn7.Click += new EventHandler(ButtonClickHandler);
    btn8.Click += new EventHandler(ButtonClickHandler);
    btn9.Click += new EventHandler(ButtonClickHandler);
 
    // Below here are all the new ones
 
    btnBack.Click += new EventHandler(ButtonClickHandler);
    btnC.Click += new EventHandler(ButtonClickHandler);
    btnCE.Click += new EventHandler(ButtonClickHandler);
    btnDecimal.Click += new EventHandler(ButtonClickHandler);
    btnDivide.Click += new EventHandler(ButtonClickHandler);
    btnEquals.Click += new EventHandler(ButtonClickHandler);
    btnMC.Click += new EventHandler(ButtonClickHandler);
    btnMMinus.Click += new EventHandler(ButtonClickHandler);
    btnMPlus.Click += new EventHandler(ButtonClickHandler);
    btnMR.Click += new EventHandler(ButtonClickHandler);
    btnMS.Click += new EventHandler(ButtonClickHandler);
    btnMultiply.Click += new EventHandler(ButtonClickHandler);
    btnPercent.Click += new EventHandler(ButtonClickHandler);
    btnPlus.Click += new EventHandler(ButtonClickHandler);
    btnPlusMinus.Click += new EventHandler(ButtonClickHandler);
    btnRecriprocal.Click += new EventHandler(ButtonClickHandler);
    btnSquareRoot.Click += new EventHandler(ButtonClickHandler);
    btnSubtract.Click += new EventHandler(ButtonClickHandler);
 
}

Every button click now triggers our event. That’s what we want! Now, we can write an if statement to check for every other condition. Change the if statement in your ButtonClickHandler method to look like this:

if ((char.IsDigit(btn.Text, 0) &amp;&amp; btn.Text.Length == 1) || btn.Text == ".")
{
    txtDisplay.Text += btn.Text;
}
// Two-number operations
else if (btn.Text == "*" || btn.Text == "/" || btn.Text == "+" || btn.Text == "-")
{
}
else if (btn.Text == "=")
{
}
// One-number operations
else if (btn.Text == "±")
{
}
else if (btn.Text == "√")
{
}
else if (btn.Text == "%")
{
}
else if (btn.Text == "1/x")
{
}
else if (btn.Text == "←")
{
}
// Memory operations
else if (btn.Text == "MC")
{
}
else if (btn.Text == "MR")
{
}
else if (btn.Text == "MS")
{
}
else if (btn.Text == "M+")
{
}
else if (btn.Text == "M-")
{
}
else if (btn.Text == "C")
{
}
else if (btn.Text == "CE")
{
}

This if statement handles every possible button input. Notice the change to the original statement. The || (“logical OR”) operator is used. The logical OR operator allows code to execute as long as one condition is true. So, if the character is a digit (which we want to add to the screen) or if the character is a decimal (which we also want to add to the screen), we will add it because in either case, (char.IsDigit(btn.Text, 0) || btn.Text == “.”) will be true.

Look at it mathematically – Booleans are essentially just bits, with a value of either 0 (false) or 1 (true). Bool1 || Bool2 || Bool3 || … || BoolN will return true if at least one of the values between Bool1 and BoolN is true. So false || false || true || false is true.

This operator gets used again in the first else if statement.  Obviously, btn’s text can’t be both all four of the characters it is compared against, but the code in that statement will execute if it is one of those characters.

There is also another big change to the first statement – I found a bug in my original code as I tested! Adding the btn.Text.Length == 1 check ensures that “1/x” does not get appended to the TextBox when that button is pushed. The && (“logical AND”) operator is the exact opposite of the logical OR operator: if any one value is false, the logical AND will return false. This means that True || True || False || True returns false.

Now, we simply plug in code to wire the calculator up, right? Easier said than done (especially when we get into idiot-proofing in the next tutorial), but we can start with the one-number operations right now, since they are the simplest. I mentioned a while ago that .NET has a whole bunch of numeric data types to choose from. We are absolutely not going to use integers – no modern calculator only does integer math and we don’t have hardware limitations. What else can we use? We could use floating points (the .NET type System.Double), but since floating points store approximations, we don’t want to go down that road. Luckily, .NET has a memory-hogging, slow, lovable data type called Decimal. Decimal can store just about any value you ever want. Its maximum absolute value is about 7.92×10^28 and its minimum absolute value (besides zero) is about 1×10^-28. That’s more than good enough.

Not convinced yet? This is the full maximum value your calculator can hold: 79,228,162,514,264,337,593,543,950,335. If 79 octillion isn’t big enough for you, then you still have another 228 septillion to go through. If that still isn’t enough, then perhaps you should just find a better calculator!

Now then, we’ll start with the ± function. We’ll get the current value of the TextBox, convert it to a Decimal, negate it (if it is negative, it will become positive and vice versa), convert its value back to a string, and then set the TextBox’s value equal to it. How do we do that?

else if (btn.Text == "±")
{
    decimal currVal = decimal.Parse(txtDisplay.Text);
    currVal = -currVal;
    txtDisplay.Text = currVal.ToString();
    // Shorthand version:
    // txtDisplay.Text = (-decimal.Parse(txtDisplay.Text)).ToString();
}

This code is displayed in both the long version and the shorthand version that I would probably use and have to write a comment about in production code. It gets the value of the display TextBox (with a glaring lack of error checking), negates it, then sets the display text again. The shorthand version does the same thing with a few more parentheses and two fewer lines of code. Both do the exact same thing.

With the ± function done, we can move on down to the √ (square root) operation. Just like before, we’ll get a Decimal value, but this time we will square root it. C# does not have a power operator or a square root operator (the same as raising a number to a power of 1/2) so we will have to use a method in the System.Math class.

else if (btn.Text == "√")
{
    decimal currVal = decimal.Parse(txtDisplay.Text);
    currVal = (decimal)Math.Sqrt((double)currVal);
    txtDisplay.Text = currVal.ToString();
}

The most noteworthy part of this code is the second line. Math.Sqrt (the square root function) takes a double as an argument and returns another double. This is probably due to performance reasons but it comes at the expense of accuracy. We will simply have to convert from a Decimal to a Double and back again. We accomplish that with a cast – first on currVal inside the parentheses and then on the whole thing.

Next are the % (percent) and 1/x (reciprocal) buttons. Note that the reciprocal button will crash the program if you try to find the reciprocal of 0. This will be fixed in the next tutorial. For now, we do something similar to the last two methods:

else if (btn.Text == "%")
{
    decimal currVal = decimal.Parse(txtDisplay.Text);
    currVal = currVal / 100;
    txtDisplay.Text = currVal.ToString();
}
else if (btn.Text == "1/x")
{
    decimal currVal = decimal.Parse(txtDisplay.Text);
    currVal = 1 / currVal;
    txtDisplay.Text = currVal.ToString();
}

For the percent, we divide the value in the TextBox by 100. For the reciprocal, we divide 1 by the value in the TextBox. Feel free to try these out – provide some input and hit the button. If you find the reciprocal of a number that has a repeating decimal, the rounding will be a little off if you hit the reciprocal button twice. Try this with the number 7 or 9. We won’t worry about that for the time being.

Next is the back (←) button. This button needs to trim off the last character of the TextBox.

else if (btn.Text == "←")
{
    if (txtDisplay.TextLength &gt; 0)
    {
        txtDisplay.Text = txtDisplay.Text.Remove(txtDisplay.TextLength - 1);
    }
}

This code actually contains some error checking – if the text length of the TextBox is zero, then the line within the if statement will throw an exception. The check prevents the exception. If you are wondering how I find all these properties, I don’t usually have to remember the name or even look on MSDN. You should notice when you type something into the editor that a little box pops up sometimes:

Intellisense Image

This is one of the most helpful inventions of all time at work.

This box contains everything that has to do with whatever variable or class you’re working with. It also contains information about method arguments.

Anyway, back on subject – the String.Remove method as we’ve used it gets rid of everything at or after the specified character index in the string. Indices are zero-based (the first character is at index zero, the second is at one, and so on) while lengths are one-based (one-character strings have a length of one, two of two, and so on), so we have to subtract one from the string’s length to get the last character. We then remove it and set the TextBox text.

Now, we move on to the memory. We need to declare two new class variables. One should be called memory and the other should be called workingMemory (because I can’t think of anything better to call it). Memory will be used for the memory buttons (MR and the like) while workingMemory will store numbers before operations are conducted on them. Both should be Decimals. While you’re at it, declare a string called opr (short for operator, which we can’t use as a variable name because it is a C# keyword).

I say class variables because they need to be accessible to all the methods in the class. The curly brackets help categorize everything in your code, but they also define a hierarchy. Variables declared at one hierarchical level cannot be accessed at a higher one.  The more open curly brackets you are within, the lower your hierarchical level is. Class variables live in the class, not a method, and so are accessible to all the methods of the class.  All that explaining was for this:

public partial class frmMain : Form
{
    decimal memory = 0;
    decimal workingMemory = 0;
    string opr = "";
// ...
// The rest of the code goes here

Now that we’ve declared and initialized our variables, we can start working on the memory piece of the application. The easiest part (not that any of them are difficult) to implement is the MC function. MC clears the memory. Simply set memory equal to 0. For MR, we have to recall the memory value into the TextBox – set the Text to a string version of the memory variable.

MS stores the TextBox value in memory and removes the value from the TextBox, so we will just set memory equal to the value in the TextBox then clear it. Finally M+ and M- add and subtract (respectively) from the value stored in memory, so we act accordingly in the code. This part is actually quite simple.

else if (btn.Text == "MC")
{
    memory = 0;
}
else if (btn.Text == "MR")
{
    txtDisplay.Text = memory.ToString();
}
else if (btn.Text == "MS")
{
    memory = decimal.Parse(txtDisplay.Text);
    txtDisplay.Clear();
}
else if (btn.Text == "M+")
{
    memory = memory + decimal.Parse(txtDisplay.Text);
}
else if (btn.Text == "M-")
{
    memory = memory - decimal.Parse(txtDisplay.Text);
}

Before we move on to the “big four” operations, we have to take care of C and CE. C means clear – it clears the working memory (not the number the user chose to store in memory), the operation, and the TextBox. CE means clear entry and only clears the TextBox. We can write the code to take care of both of those:

else if (btn.Text == "C")
{
    workingMemory = 0;
    opr = "";
    txtDisplay.Clear();
}
else if (btn.Text == "CE")
{
    txtDisplay.Clear();
}

Setting opr equal to an empty string (“”) will come into play later with the equals button, and setting workingMemory to 0 will have an effect too. Both of these methods call txtDisplay.Clear() which is a fast way of getting rid of the text in a TextBox. Now, we move on to the operations.

The way we will be making these operations work is rather rudimentary. In the next tutorial, we’ll look at how we can better emulate the way the Windows calculator works since it is something most users are already familiar with and will reduce our program’s learning curve. For now, in our operation part of the if statement, we need to set what the operator is, set workingMemory, and clear the TextBox so the user can enter more values. Easy enough, right?

else if (btn.Text == "*" || btn.Text == "/" || btn.Text == "+" || btn.Text == "-")
{
    opr = btn.Text;
    workingMemory = decimal.Parse(txtDisplay.Text);
    txtDisplay.Clear();
}

Finally, in the equals button part, we need to get the second value from the TextBox and put a resulting value in the TextBox based on what the operation is. For this, I’ve decided to use a switch statement. The reason I used an if statement instead of a switch statement before is because you cannot use method calls in a switch like I did in the if – you can only compare values (so char.IsDigit(btn.Text, 0) would not be allowed, which would add a bunch of code). This time, there are only four possible values, so I chose a switch:

else if (btn.Text == "=")
{
    decimal secondValue = decimal.Parse(txtDisplay.Text);
    switch (opr)
    {
        case "+":
            {
                txtDisplay.Text = (workingMemory + secondValue).ToString();
                break;
            }
        case "-":
            {
                txtDisplay.Text = (workingMemory - secondValue).ToString();
                break;
            }
        case "*":
            {
                txtDisplay.Text = (workingMemory * secondValue).ToString();
                break;
            }
        case "/":
            {
                txtDisplay.Text = (workingMemory / secondValue).ToString();
                break;
            }
    }
}

Your calculator is now totally wired. It’s far from user-friendly and has some minor issues, but we’ll work on it! You can do one thing to reduce errors right now – go to the Forms designer, click on the TextBox, and set its ReadOnly property to true. This will prevent troublemakers like me from typing gibberish into your TextBox.

Great job on this tutorial. At this point, you have a working calculator. The only thing left to do is to make it work well.

Working Calculator Image

Woo-hoo!!

Creating a Calculator with C# Part 5: Casting, Handling Events, Getting Input and Useful Methods

My thoughts and prayers go out to every individual who was hurt in the shootings last night in Colorado.

In the last installment of this tutorial, you learned how to use the Windows Forms editor. That’s a big step, but the Windows Forms editor isn’t much help if you don’t know how to use your creation. I saw Spiderman last night (because I didn’t want to stay out until two watching Batman on a day I had to drive for 4 hours), and using the Forms editor without being to write the corresponding code is kind of like inserting lizard DNA into your body when it actually turns you into a lizard – insane.

Now, open up your project and right-click on the form you made. Choose “View Code”. The code editor that you saw with the console application will pop up, but the code will look different. Where’s the main method, you ask? It’s there – but it’s in Program.cs. I suggest you don’t mess with it right now. Anyway, you have a code file that looks like this:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
 
namespace Calculator
{
    public partial class frmMain : Form
    {
        public frmMain()
        {
            InitializeComponent();
        }
    }
}

This seems a little more complex than the console application, does it not? Just like before, we have using statements (although Windows applications have more by default). We have a namespace and a class and a method. There are two key differences. The first is the “: Form” thing, and the second is that the frmMain() method doesn’t have a return type.

The “: Form” thing means that our class inherits from the class System.Windows.Forms.Form. The Form class provides basic form functionality and lets us put controls on the screen. We can set the size of the form, change the color of the form, move the form, and do pretty much whatever we want with the form. Inheriting from the Form class allows us to get that functionality and add whatever we need onto it.

The latter difference also bears a lot of explaining. It is called a constructor. Constructors are methods that are called whenever a new instance of a class is created. What do I mean by that? Remember how I told you that you can use classes as variables? Each variable contains a different instance of a class, and a class instance is created with the “new” keyword. So a class could contain two variables, v1 and v2, and two variables could be declared with separate instances of the class. v1 and v2 could be 1 and 2 in the first and 5 and 6 in the second, like so:

// Call this from the Main method of a console application.
static void ClassExample()
{
    A a = new A();
    A b = new A();
    b.v1 = 5;
    b.v2 = 6;
 
    Console.WriteLine(a.v1 + " " + a.v2 + " " + b.v1 + " " + b.v2);
}
 
// Put this outside the Program class
public class A
{
    public int v1 = 1;
    public int v2 = 2;
}

The above code will output “1 2 5 6″. Declaring something within a class as static means it does not go with an instance of a class; changing it will affect all instances.

For now, all you need to know is that the constructor runs before the form opens. We’re going to take advantage of that by adding some code to the constructor:

public frmMain()
{
    InitializeComponent();
 
    btn0.Click += new EventHandler(ButtonClickHandler);
}

While you’re add it, add the ButtonClickHandler method to stop the error about ButtonClickHandler not existing in the current context:

private void ButtonClickHandler(object sender, EventArgs e)
{
    throw new NotImplementedException(); // Prevent head-scratching later on.
}

Now I have three more things to explain: the btn0.Click += part, the private keyword and the arguments that ButtonClickHandler requires.

  • btn0.Click is called an event. The event happens when btn0 (the zero button – I’m writing this a full day later and I can figure out what controls do because of my naming convention!) is clicked. += is an operator that appends something, so you are essentially adding the event handler method to the Click event. In other words, when the user clicks the button, that method will be automatically called.
  • The private keyword means a method may only be called by other methods in the same class. There is no sense in making an event handler public; it will only make it easier for outside code to interfere with our program.
  • ButtonClickHandler requires two arguments: sender and e. Sender is whatever raised the event – so when you click btn0, sender is btn0. The EventArgs (e) are the base EventArgs class and don’t do anything useful, but some EventArgs let you do cool things like keep a form from closing when a user presses the X button or getting the location of the mouse.

But John, you said C# is type-safe. The type of btn0 is Button, not object! That should be an error!

I like the way you’re thinking, but remember inheritance? Btn0 is a button. You’re correct about that, but if you go back far enough in the family tree, btn0 is an object because every single class in C# is an object. String is an object. EventHandler is an object. System.Linq.ParallelQuery is an object. So, you can use a cast to convert the object into what it actually is. We’ll get there in a bit. For now, add this event handler to the other nine number buttons.

public frmMain()
{
    InitializeComponent();
 
    btn0.Click += new EventHandler(ButtonClickHandler);
    btn1.Click += new EventHandler(ButtonClickHandler);
    btn2.Click += new EventHandler(ButtonClickHandler);
    btn3.Click += new EventHandler(ButtonClickHandler);
    btn4.Click += new EventHandler(ButtonClickHandler);
    btn5.Click += new EventHandler(ButtonClickHandler);
    btn6.Click += new EventHandler(ButtonClickHandler);
    btn7.Click += new EventHandler(ButtonClickHandler);
    btn8.Click += new EventHandler(ButtonClickHandler);
    btn9.Click += new EventHandler(ButtonClickHandler);
}

Now, whenever you click one of the number buttons, your program will crash because of an unhandled exception! Exciting stuff – you can try it out if you want but we really need more functionality than that. Go to your handler and add this (by the way, my TextBox is named txtDisplay):

private void ButtonClickHandler(object sender, EventArgs e)
{
    Button btn = (Button)sender;
    if (char.IsDigit(btn.Text, 0))
    {
        txtDisplay.Text += btn.Text;
    }
}

WHOA, WHOA, WHOA! I thought this was a basic course on C#! That looks like gibberish! I know it does, but it’s the best I can do to make that work. The way this calculator is going to work is to save ourselves a lot of extra coding, we’re going to have one event handler for all the buttons, and figure out which button we’re working with based on sender. To do so, we create a button variable, and use what is known as a cast to turn sender into a Button. You can’t do that arbitrarily; the classes must be compatible. That is, going back and forth from Button to object is fine, but going from Button to TextBox would cause your program to crash.

The next thing the code does is to look at the button’s text and decide if it is a number. The char.IsDigit method does just that. Since the number buttons only have one digit on them, using char (which represents a character in C#) is fine because one digit means there is only one character. If the character turns out to be a number, we add it to the display with the += operator, which appends it.

I know this was a short tutorial, but I have to get on the road to Bot Blast now. As always, thanks for reading!

Creating a Calculator with C# Part 4: Designing the Windows Form

We now move on to the fun part: creating a GUI. GUI creation in C# requires absolutely no code. You can drag-and-drop what are known as controls on to your window, which is called a form. Controls are items on a form that serve some sort of function. I realize how broad that definition is, but controls can be anything from a TextBox (which you use to enter text) to a Button to a Label to a WebBrowser. C# provides you with all sorts of goodies to make cool programs with. In this tutorial, you will be designing your calculator window. Now, I know you have never designed a form before, so we should probably have a model to design our form from…

The Windows Calculator

Oh, hey. That’s convenient.

The Windows calculator is actually a very useful program. Most of the time, I use it in scientific mode because it is the most familiar to me (since I use a TI-30XIIS in school whenever I don’t need to graph and a TI-84+ when I do), but there are other modes as well. The programmer mode is actually kind of useful for testing logic operations before you try them in code (having a xor button can come in handy).

Windows Programming Calculator

So is being able to enter numbers in binary.

Our calculator will be based on the most basic calculator. It will have all of the same functions, but will look a little different. Why? The Windows calculator uses a theme that looks like Windows Ribbon, and we’ll be using the default theme. What’s Ribbon, you ask? Look at Microsoft Word 2007 or later and compare it to Word 2003.

I hate to break it to you, but you’ll need to create a new project in Visual C#. Fire it up, then go to File > New. This time, select Windows Forms Application as your project type and name your project Calculator. Hit OK. Go up to the View menu, and choose Toolbox (or press Control+Alt+X) and then go up again and choose Properties Window (or press F4). Press the pushpin icon to make both windows dock. Your window will change to look something like this (remember that I have Visual Studio so my window has a few additional features):

Windows Forms Designer

No errors! So far, so good!

I know it looks overwhelming, but you will find the forms designer to be fast, easy and intuitive. On the left side of the screen is the toolbox. It contains every control that you can use in your C# application. The most common ones are listed under Common Controls, but at the top (where it says All Windows Forms), you can find all the controls. On the right side is the property editor. It modifies a control’s properties. What are properties, you ask? Properties are attributes of a control – anything from a label’s text to a form’s border style. To modify a control, click on it and then search for the corresponding property in the editor. I’ll walk you through it more once we start adding controls.

In the top middle is the form preview. When you drag-and-drop (yes, drag-and-drop!) controls from the toolbox into the form, you can move them around. What the form looks like here will be what it looks like when your program runs. If you make a mistake when adding a control, you can either right-click it and choose delete or click on it and press the delete key.

Finally, the bottom middle has the error list. You may have seen it before if you made mistakes in the first three tutorials. If you can’t see it now, you can go to View > Error List. Make sure to click on the pushpin if you want it to stay showing. Otherwise, it lives in the bottom toolbar.

Let’s start designing our calculator form. Drag the box at the bottom right of the form out to make it a little bit bigger, then add a TextBox to the form from the common controls in the toolbox. You’ll notice that if you mouse over it, your cursor indicates that you can move it. Drag it to the top-left of the form. You’ll notice some blue spacer lines appear. They are suggesting how close your TextBox should be to the edge. Let me suggest something – listen to them. They know what they’re talking about. Finally, drag the right side of the TextBox over so that it stretches all the way across your form. Again, pay attention to the blue lines. When you’re done, it will look like this:

Form with Textbox

It already looks like a calculator.

Now, we’re going to edit the TextBox’s properties a little bit. Make sure it’s selected, then go to the properties editor. Find where it says (Name) and change textBox1 to txtDisplay. Then, go to Font and click in the box to the right of it. A button with an ellipsis will pop up. Click that button, and an editor will pop up. Change the font size to 24pt. Notice how the TextBox grows.

Now, why did we change textBox1 to txtDisplay? When we access the TextBox through code, we will want to know what it does. Imagine having a form with 16 TextBoxes, named textBox1 through textBox16. One of the TextBoxes has a first name in it. Which is it? Now imagine it’s named txtFirstName – it becomes self-explanatory. The txt prefix categorizes the control and makes it easier to find. You should always prefix your control names. Here are some prefixes I use:

  • frm for Form
  • txt (sometimes tb) for TextBox
  • btn for Button
  • lb for ListBox
  • rtb for RichTextBox
  • lbl for Label
  • pan for Panel
  • cb for ComboBox

Notice how the prefix is simply an easy-to-remember abbreviation. If you want, you can rename the form from Form1 to frmMain (I usually name my Windows Applications’ main form frmMain), but since this program will only have one form, you don’t need to if you don’t want to.

Next, drag two buttons on the form. Resize the first one so it looks like you will be able to have five columns of buttons and 6 rows. Then, place the second one below the first and stretch it to be the same width, then place it to the side of the first to make it the same height. The little blue helper lines (or maybe a pink line which indicates alignment) will appear again to let you know when you’re all set!

Adding Buttons

2 down, 26 to go.

Now, start adding buttons to make your window look like the Windows calculator. Remember that the button on the bottom-left is two buttons wide and the one on the bottom right is two buttons tall. Don’t worry about fonts, names or text yet. Just get the buttons on the form. If you need to, you can resize the buttons or the form to make everything fit. Making this part look good is up to you – I can’t drag-and-drop for you (actually, I can but I’m not going to). Here’s my finished product. I had to make my form wider and a tiny bit shorter.

Skeleton Form

My example only had 16 TextBoxes with non-descriptive names? We have 28 buttons here!

Hopefully you see the problem here – the buttons look like we have a calculator here, but we have no idea what any of the buttons do. Our users don’t either. I know we don’t like them, but we have to deal with them. Go through all the buttons and change the text to match the Windows calculator. I know your job is to code, not to scour the web for special characters, so here’s all that you’ll need: √±←☺. Okay, you won’t need the smiley face but I included it just in case (you might want to read ahead a bit now).

When you’re done changing button texts, you also need to change the button names. You need to come up with some sort of naming convention for your buttons. A naming convention is a standardized way of naming your controls so you don’t end up with one control named foo3, one named duck, and another named overlyDescriptiveNameForButtonOnLeftSideOfForm. You don’t have to follow the one I suggest, but please make it reasonable. Note that your names can only contain letters, numbers, dashes, and underscores and must start with a letter or underscore.

  • For all numbers: btnNumber (ie. the button for 3 is btn3)
  • Any functional or operation button: btnFunction
    • MC is btnMC, MR is btnMR, MS is btnMS, M+ is btnMPlus, M- is btnMMinus, CE is btnCE, C is btnC
    • ← is btnBack, ± is btnPlusMinus, √ is btnSquareRoot, % is btnPercent, + is btnAdd, – is btnSubtract, * is btnMultiply, / is btnDivide, 1/x is btnRecriprocal, = is btnEquals and . is btnDecimal

That covers it. Now you can get to work. I’ll wait for you to finish by showing you that mine is already done. Haha.

Completed Button Titles

We still haven’t written a single line of code.

Now, there are a few things left to do. The first is to make these buttons look better, because the font looks comically small right now. You can change the font on every button at once by clicking one, then holding shift or control and selecting all the others. Just like before, click on the box to the right of where it says “Font” in the property editor, then click the button that pops up. Change the font to whatever you want. Bold 14pt seems to be big enough for my huge calculator.

Next, we’re going to modify the form, so click on the border to deselect all the buttons and to select the form. Change the Text property from “Form1″ to something better. “My Calculator” wouldn’t be bad. Next, find the MaximizeBox property and set it to false by clicking where it says True next to it, hitting the button that pops up, and choosing false. Finally, change FormBorderStyle to FixedSingle. The last two actions will keep users from resizing your form at all.

Now, the moment of truth. Hit F5 or press the green play button to run your program and display your form.

Finished Product

It’s beautiful.

You can type in the TextBox and hit all the buttons. Of course, nothing happens yet because we haven’t written any code, but we still have a beautiful product.

A common question is how the heck the Forms Designer works, since the buttons just appear and you don’t have to write any code. If you go to View > Solution Explorer and click the arrow next to Form1.cs, you will see two more files pop up. The designer generates code, which gets put in Form1.Designer.cs. My designer file has 425 lines of code in it. The designer just saved you a ton of work – learn to use it well and you will be making gorgeous GUIs very quickly. Good work today!

Creating a Calculator with C# Part 3: Custom Methods, Throwing Exceptions, Conditional Logic, and a Console Calculator

By now, we’ve covered quite a bit of C#. Hopefully it’s all made sense to you and you’re starting to see how useful C# can be. If not, rest assured: the really cool stuff will start in the next lesson when we start using the Windows Forms Editor to display the windows you’re used to seeing. For now, open up the project we were working on in the last lesson. We’ll be making some big changes to it. In fact, by the time we’re done, we’ll have a basic four-function calculator. Of course, the calculator we end up with will look a lot like the one in Windows, so don’t think you’ll be finishing the series on something so basic.

If you’re just joining us, here’s the entire program from part 2:

    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                int number1;
                int number2;
 
                Console.WriteLine("Enter a number, then hit enter:");
                number1 = int.Parse(Console.ReadLine());
                Console.WriteLine("Enter another number, then hit enter:");
                number2 = int.Parse(Console.ReadLine());
 
                int sum = number1 + number2;
                Console.WriteLine("The sum is: " + sum.ToString());
 
                Console.ReadLine();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Main(args);
            }
        }
    }
}

We’ll start by adding four methods to the Program class. There are two obvious questions here: where do you put a method and how do you declare one? The first question is somewhat more difficult to answer. Notice the curly brackets ( { and } ) in the code. After the namespace keyword, there is an opening curly bracket ( { ), and down at the bottom, there is a closing curly bracket ( } ). The same happens one tab in below the class keyword. The same happens for Main. Anything between the curly brackets is considered to be “inside” or “part of” whatever the brackets are related to.

So, in this case, the new methods will go inside the Program class but not inside the Main method. Methods in C# can either be “void” or have a return value. Voids do not return any value; they simply perform a task. Functions that have a return value perform tasks and then return information for another method to use. We’ll be declaring four methods with a return type of int. They will also have to be static methods, which means they aren’t tied to a specific class instance. Don’t worry about this right now – just know that since Main is static, it’s way easier to make the other methods static as well. Each method will take two arguments: num1 and num2. The syntax for declaring methods is like this:

static ReturnDataType NameOfMethod (ArgumentDataType arg1, ArgumentDataType arg2, ... , ArgumentDataType argN)
{
    // Code of method
}

So what’s there? ReturnDataType is the DataType we’ll be returning. In our case, it will be int. NameOfMethod is just the method’s name. One will be Add, one will be Subtract, one will be Multiply, and one will be Divide. ArgumentDataType is the DataType of the argument. Look at Main. Args is associated with a DataType of string[]. Arg1, Arg2, and ArgN are simply the names of the arguments. Just like main, the example method has curly brackets. Let’s declare our four methods now.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace Hello_World
{
    class Program
    {
        // Below Main method - don't delete the Main method!
 
        static int Add(int num1, int num2)
        {
        }
 
        static int Subtract(int num1, int num2)
        {
        }
 
        static int Multiply(int num1, int num2)
        {
        }
 
        static int Divide(int num1, int num2)
        {
        }
    }
}

Hopefully it’s painfully obvious what these four methods will do. But how do you return a value from a method? The return keyword. You can return a value in a similar way to how you would set a variable, except you don’t use an equals sign. When a return statement runs, code execution in your method will end, so make sure you’re ready to exit when you use one! I’ll write the multiply and divide methods; I’ll leave the add and subtract methods up to you. Remember that C# is case-sensitive!

static int Add(int num1, int num2)
{
 
}
 
static int Subtract(int num1, int num2)
{
 
}
 
static int Multiply(int num1, int num2)
{
    return num1 * num2;
}
 
static int Divide(int num1, int num2)
{
    return num1 / num2;
}

The one flaw with this code is that since we are using integers, num1 / num2 will be an integer, so 3/2 gets rounded down to 1. We’ll be fixing that in the next version of our calculator. For now, everything else will work fine. The next thing that needs to be done is to collect some user input in the Main method to figure out which method to use on the numbers. Below the number2 = int.Parse(Console.ReadLine()) statement, add this:

Console.WriteLine("Which operation do you want? (Choose +, -, * or /, then hit enter):");
switch(Console.ReadLine())
{
}

What’s that switch business? In C#, switch is a keyword used for conditional logic. It lets you check to see if a variable matches a value. In this case, we’ll be comparing what Console.ReadLine() returns to “+”, “-”, “*”, and “/”. If it doesn’t match any of those, C# allows you to create a default case.

switch (Console.ReadLine())
{
    case "+":
        {
            int sum = Add(number1, number2);
            Console.WriteLine("The sum is: " + sum.ToString());
            break;
        }
    case "-":
        {
            int difference = Subtract(number1, number2);
            Console.WriteLine("The difference is: " + difference.ToString());
            break;
        }
    case "*":
        {
            int product = Multiply(number1, number2);
            Console.WriteLine("The product is: " + product.ToString());
            break;
        }
    case "/":
        {
            int quotient = Divide(number1, number2);
            Console.WriteLine("The quotient is: " + quotient.ToString());
            break;
        }
    default:
        {
            Console.WriteLine("You didn't use a valid operator.");
            break;
        }
}

This requires some explaining. The case “string” statements define a case that C# should check the string against. If it matches, the code inside the brackets will be run. If it doesn’t, it will be skipped. The break statements tell C# that the code regarding the case is over. Finally, the default statement provides a default case in the event that the string doesn’t match anything else. It should always go last and should always be present – remember to always assume your user is clueless and will try to break your program. Want to know more? Here is more than you will ever want to. Now, at this point, you can remove all the sum stuff from the last lesson. When you’re done, your Main method will look like this:

static void Main(string[] args)
{
    try
    {
        int number1;
        int number2;
 
        Console.WriteLine("Enter a number, then hit enter:");
        number1 = int.Parse(Console.ReadLine());
        Console.WriteLine("Enter another number, then hit enter:");
        number2 = int.Parse(Console.ReadLine());
        Console.WriteLine("Which operation do you want? (Choose +, -, * or /, then hit enter):");
        switch (Console.ReadLine())
        {
            case "+":
                {
                    int sum = Add(number1, number2);
                    Console.WriteLine("The sum is: " + sum.ToString());
                    break;
                }
            case "-":
                {
                    int difference = Subtract(number1, number2);
                    Console.WriteLine("The difference is: " + difference.ToString());
                    break;
                }
            case "*":
                {
                    int product = Multiply(number1, number2);
                    Console.WriteLine("The product is: " + product.ToString());
                    break;
                }
            case "/":
                {
                    int quotient = Divide(number1, number2);
                    Console.WriteLine("The quotient is: " + quotient.ToString());
                    break;
                }
            default:
                {
                    Console.WriteLine("You did not enter a valid operator.");
                    break;
                }
        }
 
        Console.ReadLine();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
        Main(args);
    }
}

This is good enough to run. Try out your calculator. Since I’m pretty good at playing clueless user, I found an inconsistency pretty quickly. Normally, you can only run the calculator once (which is annoying – we’re going to set up an infinite loop in a little bit to make our calculator more useful), but if you try to divide by zero, an exception gets thrown, which doesn’t look very good:

Divide by 0 Error Image

On the bright side, your program didn’t crash!

To provide a nicer-looking error, we’re going to throw our own exception. But how do we know when to do that? Introducing the if statement – a more useful version of the switch statement. Don’t get me wrong. The switch statement has its place (it runs faster than an if statement), but when it comes to really complicated logic or where there are only a few options, the if statement is just plain better.

In the Divide method (the only place where we’ll have issues) we’re going to use an if statement to make the exception message look like any other message.

static int Divide(int num1, int num2)
{
    if (num2 == 0)
    {
        throw new Exception("The quotient is: Infinity (Cannot divide by 0)");
    }
    else
    {
        return num1 / num2;
    }
}

There three parts to an if statement. The first is “if”. It is the first condition to be checked; if whatever is between the parentheses is true, then the code will run. The second (not used here) is else if. Else if statements are just like if statements except they are not checked first. They are checked in order from top to bottom. If none of the other conditions are true, the else statement executes.

The == operator in C# compares two things to determine if they are equal. Do not use = to determine equality! I’ll say that again. Do not use = to determine equality! Using = to determine equality will assign your variable and will always return true or false, which isn’t what you want.

The throw new Exception(“”) statement throws an exception that will be caught by our try…catch block. Normally, tossing exceptions around like this is a bad idea, but for the sake of this tutorial, we can get away with it.

There’s only one thing left: moving Main(args) out of the catch statement so that it is only inside the Main method at the end. This will create an infinite loop that will let users use your calculator as long as they want. They will just have to use the X button to exit. It’s far more convenient. That’s it!

Finished Calculator Image

I’m not very good at using this thing, but it does math.

Here’s the finished source code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace Hello_World
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                int number1;
                int number2;
 
                Console.WriteLine("Enter a number, then hit enter:");
                number1 = int.Parse(Console.ReadLine());
                Console.WriteLine("Enter another number, then hit enter:");
                number2 = int.Parse(Console.ReadLine());
                Console.WriteLine("Which operation do you want? (Choose +, -, * or /, then hit enter):");
                switch (Console.ReadLine())
                {
                    case "+":
                        {
                            int sum = Add(number1, number2);
                            Console.WriteLine("The sum is: " + sum.ToString());
                            break;
                        }
                    case "-":
                        {
                            int difference = Subtract(number1, number2);
                            Console.WriteLine("The difference is: " + difference.ToString());
                            break;
                        }
                    case "*":
                        {
                            int product = Multiply(number1, number2);
                            Console.WriteLine("The product is: " + product.ToString());
                            break;
                        }
                    case "/":
                        {
                            int quotient = Divide(number1, number2);
                            Console.WriteLine("The quotient is: " + quotient.ToString());
                            break;
                        }
                    default:
                        {
                            Console.WriteLine("You did not enter a valid operator.");
                            break;
                        }
                }
 
                Console.ReadLine();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);  
            }
            Main(args);
        }
 
        static int Add(int num1, int num2)
        {
            return num1 + num2;
        }
 
        static int Subtract(int num1, int num2)
        {
            return num1 - num2;
        }
 
        static int Multiply(int num1, int num2)
        {
            return num1 * num2;
        }
 
        static int Divide(int num1, int num2)
        {
            if (num2 == 0)
            {
                throw new Exception("The quotient is: Infinity (Cannot divide by 0)");
            }
            else
            {
                return num1 / num2;
            }
        }
    }
}

For homework, use comments to label what everything here is doing, just so we’re clear. By the way, this program is a full 91 lines of code! Our programs are getting more complicated!

Keep up the good work!

Creating a Calculator with C# Part 2: Creating Variables, Getting User Input, Doing Math, and Handling Exceptions

Welcome back. Hopefully the last tutorial on C# sparked your interest. If it didn’t, then I commend you for still giving this tutorial a shot. We’re going to learn how to use variables, get input from the console, and then conduct mathematical operations on the input. We’ll even display the result. Yes, we’re building a simple adder.

To begin, either create a new project or (gasp!) delete your Hello World project. I recommend the former; you probably haven’t been able to show it to your grandkids yet. Then, in the main method (just like before), we’re going to declare two variables: number1 and number2. How do you declare variables, though? Like this:

[type] variableName;

What’s [type]? Type is class the variable is. C# is called a strongly-typed language because you can’t mix and match types. If you declare a variable as an integer (using “int” or “System.Int32″ or “Int32″ as the type), you can’t put a string in it. This prevents errors down the line and encourages you to code better. Now, declare those variables!

static void Main(string[] args)
{
    int number1;
    int number2;
    // More code goes here!
}

This also seems like a good time to tell you two more things about C#:

  1. Every code statement you write (like int number1) has to end with a semicolon. Semicolons are so important that you can have a line containing nothing but a series of semicolons and your project will run properly! Try it if you don’t believe me.
  2. The line beginning with // is called a comment. Comments are ignored by the compiler and contain information to make your code easier to read. You don’t need a semicolon after a comment. C# also has what are called block comments. Block comments start with /* and end with */. Everything between the start and end is ignored. No matter how nicely you ask the computer to work in your comments, they will be ignored.

So, we’ve got our variables. We’ve got more knowledge about the C# syntax. Let’s fill those variables with numbers. Remember Console.WriteLine() and Console.ReadLine()? We’re going to use them again. We’re also going to use another method called int.Parse() which takes a string as an argument. Recall that I told you C# is strongly typed. The Console.ReadLine() method returns a string value, even if the user types in numbers. The int.Parse() method converts the numbers a user types in to a real integer. Here we go.

static void Main(string[] args)
{
    int number1;
    int number2;
 
    Console.WriteLine("Enter a number, then hit enter:");
    number1 = int.Parse(Console.ReadLine());
 
    ; ; ; ; ; ; ; ; ; ; ; ; ;
}

Just for fun, I threw in a line of semicolons; semicolons are awesome anyway. We’ve seen Console.WriteLine() before, but look at the line below that. Console.ReadLine() returns a string, and we’ve used it as the string argument for int.Parse. The value the user enters will be passed to int.Parse, and then the integer version is stored in number1. Now let’s take care of the other number.

static void Main(string[] args)
{
    int number1;
    int number2;
 
    Console.WriteLine("Enter a number, then hit enter:");
    number1 = int.Parse(Console.ReadLine());
    Console.WriteLine("Enter another number, then hit enter:");
    number2 = int.Parse(Console.ReadLine());
}

The two lines we’ve added are identical to the two we added before. Next, let’s do something with our new-found numbers. We’re going to add them together and write them to the console. Let’s create a new variable called sum and assign it to the sum of number1 and number2. C# spoils you because it follows order of operations, unlike other languages I post about like PBASIC. The addition operator in C# is +, and using it is rather intuitive:

static void Main(string[] args)
{
    int number1;
    int number2;
 
    Console.WriteLine("Enter a number, then hit enter:");
    number1 = int.Parse(Console.ReadLine());
    Console.WriteLine("Enter another number, then hit enter:");
    number2 = int.Parse(Console.ReadLine());
 
    int sum = number1 + number2;
}

We’ve created another variable called sum and immediately assigned it to the sum of number1 and number2. Sum is an int (32-bit integer – .NET has loads of other numbers like 8, 16 and 64-bit integers, decimals, and single and double-precision floating points), so we make sum an int as well. If you wanted to use multiplication (*), subtraction (-), division (/), or any other operation, you would substitute the corresponding operator in for the plus sign. Now, The last thing we have to do is print the sum to the console and wait for the user to exit.

static void Main(string[] args)
{
    int number1;
    int number2;
 
    Console.WriteLine("Enter a number, then hit enter:");
    number1 = int.Parse(Console.ReadLine());
    Console.WriteLine("Enter another number, then hit enter:");
    number2 = int.Parse(Console.ReadLine());
 
    int sum = number1 + number2;
    Console.WriteLine("The sum is: " + sum.ToString());
    Console.ReadLine();
}

What on earth is this ToString() thing? And why is there a plus sign on the string!? I thought C# was strongly typed, and the + goes with numbers!! Whoa there. I’m glad you’re thinking about this typing thing; it will save you a lot of headaches later on. We’ll start with the plus sign. + has another purpose besides addition: concatenation. Concatenation is the process of appending one string on the end of another. If you were to concatenate “hello” and “world” by writing “hello” + “world”, the result would be “helloworld”.

The ToString() thing should make a little more sense. Remember that sum is an integer, not a string. Calling ToString() lets us use it as a string. Every single class you can declare as a variable in the .NET framework has a ToString() method. Even System.Object, the basis for every other class in .NET (if you want to understand this better, look up inheritance. It’s sort of an advanced topic but there’s nothing wrong with being exposed to advanced topics!) has a ToString() method. Return values vary; ToString() tends to work well with numbers and poorly with more complicated classes like System.Windows.Forms.Form. Anyway, back on track – once sum is usable as a string, we append it to the end of the other string. Go ahead and run your code by hitting F5.

Adder Program Console Image

Yay! It works!

We only have one topic left to cover in this lesson: handling exceptions. What’s an exception? Exceptions are how your program handles errors. Errors happen all the time. Even the almighty Google has to handle errors.

Google Exception Image

I wonder why that page can’t be found?

In this case, Google’s server code searched for whatever file would normally be served for google.com/the long file name that doesn’t exist, and didn’t find it. In .NET, a FileNotFoundException would result. When an exception occurs, it has been “thrown”. If an exception is thrown and not caught, it will cause your program to come crashing down, just like a baseball that isn’t caught. You might be thinking that this program is way too simple to have to worry about exceptions, but every application that handles user input should have very careful exception handling because to write bulletproof code, you have to assume your users are less technically competent than you are. You have to assume they don’t know what they’re doing and will send you angry emails about how your application is full of bugs. Let’s pretend to be a dumb user right now. Run your application again (close it then hit F5 in Visual C#), and type in some gibberish instead of a number.

Exception in Visual C# image

You don’t have to send yourself any angry emails.

Congratulations, you’ve just seen your first exception. If you haven’t followed the code here exactly, it may not be your first. The question is, how do you keep your program from crashing when a user puts random input is? You can encapsulate your code in a try, catch block. A try, catch block lets you run code and have code that is run in the event of an exception (but not otherwise). We’ll print the exception message to the screen and then try again with our try, catch block. Modify your code to look like this:

static void Main(string[] args)
{
    try
    {
        int number1;
        int number2;
 
        Console.WriteLine("Enter a number, then hit enter:");
        number1 = int.Parse(Console.ReadLine());
        Console.WriteLine("Enter another number, then hit enter:");
        number2 = int.Parse(Console.ReadLine());
 
        int sum = number1 + number2;
        Console.WriteLine("The sum is: " + sum.ToString());
 
        Console.ReadLine();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
        Main(args);
    }
}

Just like a method, a try, catch block uses curly brackets ( { and } ) to signify where the associated code goes. One of the wonderful things about C# is how the curly brackets let you format your code the exact way you want it, as opposed to Python which forces you to adhere to its own indentation requirements. Anyway, The code in the try block remains unchanged and if there are no errors, users will not know the difference from before. If, however, there is an exception, the user will see the message (which is a property of System.Exception – more on this in another lesson) and then get another shot at entering numbers, because the method Main calls itself, which causes the program to start over.

Image of exception handling

That’s way better than crashing.

Be careful when you instruct a method to call itself. If there is no way to exit the method (in this case, if the user successfully adds two numbers then hits enter), you will end up in an infinite loop. That’s fine in a simple application like this, but more complicated applications could crash.

I know you have one last question – why are we catching an Exception when Visual C# clearly told us that we were dealing with a FormatException? C# is strongly typed so we should have to catch what we throw? This is like catching a soccer ball with a baseball glove, right? Not exactly. It’s closer to catching a baseball with yellow stitches with a baseball glove.

FormatExceptions (and every other exception you will ever handle) are Exceptions because of something called inheritance (remember, I put a link at the top of this post). If you catch Exception ex, then you are catching every conceivable exception that could ever be thrown in that block of code. So, if you bother to watch for exceptions, why not take care of all of them?

That’s it for this installment. If you want to go a little farther, change this application to multiply three numbers together. Thanks for reading!