Tag Archives: Application

Whoops.

I know I haven’t posted for far too long. It’s really embarrassing, especially since I now aspire to be an admissions blogger at MIT.

Wait, what?

Yeah. I committed to MIT. I’m going to be a Beaver (or maybe an Engineer or an IHTFPer or whatever), and I couldn’t be happier! So now that the college admissions process is done until I (hopefully don’t have to) apply to grad school, what am I up to? Moreover, what have I been up to for the past month and a half? Why haven’t I been blogging?

I could post myriad excuses, and depending on how the rest of this blog post goes, I very well might. However, for the time being, I think it would be more appropriate if I directed your attention to Hawgrade!

Hi, Hawgrade!

Hi, Hawgrade! What the heck are you, anyway?

You can actually see the live version of this website at www.hawgrade.com. Now, to answer the caption’s snarky question, Hawgrade is grading for the Twenty First Century, developed with the help of one of the social studies teachers at my school, Dave Hawley. Mr. Hawley also goes by Hawley, hence the name Hawgrade. The website will eventually join forces with an iPad app, and the two will offer the following functionality:

  • Easy, paperless submitting of student papers.
  • Grading that stores data remotely. Teachers can keep their students’ papers anywhere!
  • Corrections for the most common student mistakes built in. This makes grading most papers as simple as highlighting passages and pressing a few buttons.
  • Recording voice comments to end the time consuming process of actually writing comments on students’ work.
  • Returning students’ corrected papers over email.

Most of that functionality has been implemented by now. It’s a wonderful culmination to my high school career, although it is unfortunate that I (a second semester senior) actually have to work on something! It’s also an enormous project. Maybe I’ll post some of my secret, proprietary code samples on this blog.

Regardless, I’ll definitely start posting more!

It serves!

Writing a Working Web Server in Under 100 Lines of Code

UPDATE 12/30/12: You must run the compiled executable as an administrator on systems with UAC. Otherwise, the program will crash and exit.

I was reading some coding blogs last night and I happened across a guy who had written a minuscule web server in C# over his lunch break. I knew right away that I had to have one, too. A server like this one serves little practical purpose; it does not support any sort of server-side scripting (though adding a BASIC interpreter to it would be extremely cool). It does, however, serve a wide variety of documents (and will detect their MIME type prior to serving them.

The first thing I did was write a Log method to make console output look fancy:

static void Log(string message)
{
    Console.WriteLine("[{0}]: {1}", DateTime.Now, message);
}

That was quick. Next was to create an actual server method, which would continuously loop and be started asynchronously by the Main() method.

static void RunServer(int port)
{
    HttpListener listener = new HttpListener();
    listener.Prefixes.Add(string.Format("http://+:{0}/", port)); // Where to listen
    listener.Start(); // Fire up the server
    while (true)
    {
        HttpListenerContext context = listener.GetContext(); // Get a connection
        Log("Requested: " + context.Request.Url);
 
        if (context.Request.RawUrl.EndsWith("/")) // Just asking for index; redirect
        {
            context.Response.StatusCode = 301;
            context.Response.StatusDescription = "301 Moved Permanently";
            context.Response.RedirectLocation = context.Request.RawUrl + "index.html"; // Just send browser to index.html
            context.Response.Close();
            Log("Redirected client to /index.html.");
        }
        else
        {
            byte[] retVal;
            try
            {
                retVal = File.ReadAllBytes("www" + context.Request.RawUrl); // Give the client the requested page
            }
            catch
            {
                context.Response.StatusCode = 404; // File not found; tell the client.
                context.Response.StatusDescription = "404 Not Found";
                Log("404: " + context.Request.RawUrl);
                context.Response.Close();
                continue;
            }
            string mime = GetMimeType(context.Request.RawUrl);
            context.Response.Headers.Add(HttpResponseHeader.ContentType, mime); // Give response a MIME type
 
            Stream respStream = context.Response.OutputStream; // Response stream we'll write to
            respStream.Write(retVal, 0, retVal.Length);
 
            context.Response.StatusCode = 200;
            context.Response.StatusDescription = "200 OK"; // Let client know stuff is okay
 
            respStream.Close();
            context.Response.Close();
            Log("Served: " + context.Request.RawUrl + " as " + mime + ".");
        }
    }
}

There’s quite a bit going on here; I’ll try to explain it all. The beginning of this method configures an HttpListener to wait for connections and starts it. It then starts an infinite loop (the user can stop the server by closing the console window) of continuously waiting for and serving requests (listener.GetContext() blocks until something makes a request). A client can ask for three things in this simple server (since we’re not running server-side scripts):

  1. A page that exists (e.g. /index.html)
  2. A page that doesn’t exist (e.g. __++++_____-sdasfash1234.abcdf)
  3. A directory root that may or may not exist (e.g. /mysite/)

The first thing we check for is the directory root case. We check the URL to see if it ends in a slash. If it does, we redirect the client to whatever the path is, plus “index.html.” We could simply serve the “index.html” off the bat, but we’re (poorly) code golfing right now! That would take more code and accomplish essentially the same thing!

If the RawUrl does not end in a slash, we’re serving a page! Anyway, the server stores all its files in a “www” folder that lives in the same directory as the executable. Fetching “www” plus the raw path with File.ReadAllBytes gets the data of the file we are looking for. The try statement is used in the event we can’t find the file. If an exception does get raised, the server returns a “404 File Not Found” error to the client. If this server were fancy, it would also serve a 404 error page.

If the server can find the file, it determines the MIME type through a simplistic process I will detail in a moment, sets the MIME type in the header, writes the data to the client stream, gives the client a “200 OK” (I am not sure if the order matters for all this, or if all the data simply gets flushed when the HttpResponse gets closed, but this code worked fine in Chrome and IE 9), and closes the connection.

The last thing is to determine the MIME type of the file. Rather than using WIN32 interop calls, I decided to write a simplistic method of my own based on the file extension being served.

static string GetMimeType(string fileName)
{
    // Fast way of determining if the lowercase file name ends with something
    Func<string, bool> fendw = new Func<string, bool>(inp => fileName.ToLower().EndsWith(inp));
 
    // Use our function to figure out the mime type
    if (fendw(".htm") || fendw(".html")) return "text/html";
    else if (fendw(".ico")) return "image/vnd.microsoft.icon";
    else if (fendw(".png")) return "image/png";
    else if (fendw(".jpg") || fendw(".jpeg")) return "image/jpeg";
    else if (fendw(".gif")) return "image/gif";
    else if (fendw(".js")) return "text/javascript";
    else if (fendw(".css")) return "text/css";
    else return "application/octet-stream";
}

This method wouldn’t be very interesting were it not for the Lambda Expression (remember those things I love?). The Lambda Expression takes as a string as an argument and returns a Boolean of whether the lowercase version of the provided file name ends with the specified text. In other words, it checks to see if the file has whatever extension you pass to it and ignores case. The “fendw” name, although cryptic, is short for “file ends with;” it prevented me from having to type fileName.ToLower().EndsWith(…) over and over again!

That’s it. The web server works — we just need to add a Main() method:

static void Main(string[] args)
{
    Console.WriteLine("On what port should the server run?:");
    int port = int.Parse(Console.ReadLine());
 
    Task server = new Task(() => RunServer(port)); // Start the server async
    server.Start();
    Log("Server started on port " + port.ToString() + ". Close this window to stop it.");
 
    while (!server.IsCompleted) ; // Wait infinitely
}

The first part of this method gets the port the user wants to run the server on. I used 2013, since it’s almost New Year’s! Next, it creates an asynchronous task (using a Lambda Expression again!) to run the server on, then fires it up and blocks indefinitely. The use of the Lambda expression is unnecessary here (since the thread Main() runs on will just loop forever), but if you wanted to listen on more ports, you could create more tasks to run new instances of the server on. It makes the code more extensible, right?

It serves!

It serves!

Serving a real web page from a website I built for a charity organization last year!

Serving a real web page from a website I built for a charity organization last year!

If you desired, you could actually open a port in your router and let your friends connect to your cool new server. I should probably warn you that doing so would be a terribly risky idea, even if you only have the port open for a short while. You wouldn’t run through wolf-infested woods with a steak or swim at the Great Barrier Reef with a gaping leg wound for ten minutes, so why would you do the same on the Internet? In other words: this code is provided “AS-IS” with no express or implied warranty, especially since I do not really know how secure this server is. My guess is that it isn’t. Still, it’s hard to go wrong with a 100-line server!

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)

A Fun JavaScript Game I Threw Together

Perhaps you have heard of some keyboarding speed-improving websites such as 10fastfingers.com and TypeRacer, perhaps not. At any rate, my friend David Chen (follow him on Twitter – @Ninchendoz95) has been playing these games a lot, and I was inspired to create something similar. For once, I didn’t go over the top. There’s no glorious database of the most common English language words, no web service that sends the JavaScript behind the game a JSON string full of words to put in, no leaderboard, and minimalist styling on the game web page itself.

You can play my little game here.

I should warn you – there are some issues with TextRacer. It uses the KeyPress event, so words are always somehow one character behind. You can change “keypress” to “keyup” but that introduces another slew of bugs: multiple keys pushed down at once and repeated characters (from holding keys down) registering incorrectly. Luckily, TextRacer more or less works and is amusing to try out a few times.

The code is by no means production-worthy! I was attempting to build something extensible at first but then just started hard-coding the names of divs I was using into the JavaScript.

Here’s TextRacer in action:

TextRacer in action

It almost looks kind of good…

As always, I am amazed by how useful jQuery was in this whole development process. I tested TextRacer in Firefox and Chrome, and the code worked just as well in both.

Have fun tinkering!

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.

And so Begin the Crazy College Apps

Today is August 2, 2012. Yesterday was August 1, 2012. Why is that special, other than that I can now say later this month, I will be entering my senior year of high school? Ladies and gentlemen, this year’s Common App is out. The essay topics aren’t any different, but the release comes as a reminder that college crunch time is coming (and has helped me realize that there are limitless alliteration possibilities with the word “college”).

I have two shots at the SAT to get my score up just a little bit in hopes that it will give me just a little edge. I also have to take an SAT Subject Test on the date I don’t take the real deal. I will need to figure out which test is right for me. I have realized in the last 36 hours or so why the autumn of one’s senior year is so crazy. Come August 29th, I will have to balance fall golf, four AP classes, SAT studying, “Common Apping” and applying to two non-Common-App schools. My amazing 10:30 bedtime from junior year is beginning to seem out of reach, at least in the short term. It’s a classic case of “pick two of friends, sleep or grades” situation, except I only have time to pick one.

At the moment, my big concerns lie with the SATs and application essays – I want to make the best impression I possibly can. Unfortunately, I can’t rely on chance to bring my SAT scores up. However, I have a study book and I’ll be working from that. One thing that has really stuck out to me about the entire college process is its expense. The SAT is $50 to take and costs extra money to send your score to more than four colleges. College application fees are in the $75 range. I will probably end up spending something in the $900 range on applying to schools, an amount in pales in comparison to the $40,000+ per year that college will cost, even with financial aid.

Because of the already immense cost, it is hard to justify spending in upwards of $150 per hour on an SAT tutor or a thousand more on an essay reader. Does it bother me that I will have to work excruciatingly hard to get into one of the schools I want to attend? Not in the least. I’ve never been a stranger to effort, and all my extra work will make (hopefully) getting in all the sweeter.

With all that said, I still have a month of summer – one last month of freedom. I’ll blog regularly about my progress.

.NET Applications: Open Source by Default

If you have been developing .NET applications for much time, I hope you have come to realize that your Windows applications are not very secure. What do I mean by that? Let’s take a very simple application as an example:

using System;
 
namespace InsecureApp
{
    class Program
    {
        static void Main(string[] args)
        {
            for (; ; )
            {
                Console.WriteLine("Enter your password:");
                if (Console.ReadLine() == "secret")
                {
                    Console.WriteLine("Logged in. My social security number is 123-45-6789.");
                    Console.WriteLine("Your session has expired. Logged out.");
                }
                else
                {
                    Console.WriteLine("Incorrect password.");
                } 
            }
        }
    }
}

I realize this example is trivial, but I am trying to illustrate a point. I’ll do it in two ways: first, using ildasm.exe and second by using Telerik JustDecompile. No, this isn’t a product endorsement. I just needed to find a free decompiler.

You can run IL DASM with the Visual Studio Command Prompt. Here’s the output from my test program:

IL DASM Example Image

Please don’t sign me up for too many credit cards!

Not that scary, right? Potential crackers can only see the login password and your social security number. In an actual application, an email address, password, or authentication token could be visible in plain text. Remember, I did this with a free tool. I didn’t even have to download anything! What if I did, you ask?

Decompiled Code

Oh, bother.

Not only is the code reasonably close to what it actually was (to the point where it is easy-to-understand), I could look at the code in VB.NET if I wanted to and there is syntax highlighting! This is another free tool that you can use without even understanding CIL. But, say you did. Back in the day (and I do mean “in the day”, perhaps four or five years ago), I became interested in what was going on behind-the-scenes in .NET and learned some CIL. I also learned that you can use /OUT=”location” with IL DASM to actually output CIL to a file. Oh, I forgot to mention – there is a corresponding IL ASM to put the program back together.

Let’s say I’m a lazy cracker, so I am going to just jump to being logged in and then never log out. I changed the CIL for Main to look like this:

  .method private hidebysig static void  Main(string[] args) cil managed
  {
    .entrypoint
    // Code size       81 (0x51)
    .maxstack  2
    .locals init ([0] bool CS$4$0000)
 
	ldstr "Cracked by 1337 H4x0r or something"
	call void [mscorlib]System.Console::set_Title(string)
 
    IL_0026:  ldstr      "Logged in. My social security number is 123-45-6789."
    IL_002b:  call       void [mscorlib]System.Console::WriteLine(string)
 
	call string [mscorlib]System.Console::ReadLine()
	pop
	ret
  } // end of method Program::Main

I then reassembled my program and ran it. There was no need to log in, and the program conveniently waited for me to hit enter before closing!

Simple Program Cracked

It took a surprising number of tries to assemble this application properly.

So, what can you do? Can you strong name your assembly? Sure, but it won’t do much to anyone that knows his or her stuff. Can you obfuscate it? Sure, but it’s only a roadblock. I did some reading about protecting .NET Windows applications from piracy, and the consensus seems to be that much protection isn’t worth it. Would you rather spend your time keeping people that will not pay for your software from using it or adding features to make more people willing to pay for it?

The important thing to take away from this post is to realize that anyone can see and modify what you write. You should not handle tasks that should be secure (such as anything that requires password or key storage) on the client side. Server-sided code is much better suited to secure tasks (since you cannot download ASP.NET binaries from a server unless something is seriously wrong), so anything that has to remain a secret should remain remote. Remember, transmitted data can be intercepted, so I am not telling you to send your passwords from the server to the client. I am telling you to have the client ask the server to do its dirty work.

The bigger message I wish to convey, though, is that you should minimize the amount of data that needs to be protected.

 

Will it Rain this Weekend?

While browsing MIT+K12 open projects, I came across an entire course proposal about probability. Now, I have very little formal probability training outside of one unit in precalculus last year, but I was intrigued by the idea of writing a program to simulate 10,000 trials. Obviously, 10,000 trials isn’t enough to get a really good data set so I added a few zeros to my C# for loop and ran 1,000,000 trials.

So, in keeping with the MIT course proposal, I checked the forecast for the weekend and found out that this weekend, the chance of rain on Saturday is 10% and the chance of rain on Sunday is 30%. My first reaction was mild aggravation because I went camping last weekend in the rain and I simply could’ve waited a week. My second reaction was, “Alright. Let’s get started.”

Probability Tree Image

Mr. Whalen, I hope you’re proud of me.

The next step was to write a program to test my calculations. I came up with a program structure that I hope is “random” enough. I am going to use System.Random instead of RNGCryptoServiceProvider because it is way faster and I believe it fine for something this simple. When I originally wrote this program, I used lists, populated them with true or false values, randomized them, and picked from them over and over again. I am not sure what kind of awful state of mind I was in when I wrote that code (whatever it was, there wasn’t enough caffeine), but I’ve come up with a way more elegant solution – Random.NextDouble(). If the double is less than the probability of rain, it rained. Otherwise, it didn’t. We also need three counters – one for when it rains sometime during the weekend at least once, one for when it rains exactly once and one for when it rains twice.

There is one other case: when it doesn’t rain, but 1,000,000 – the number of times it rained at least once takes care of that. Some operators make determining which case we’re dealing with easy – XOR is true if exactly one of two cases is true, OR is true if at least one case is true, and AND is true if both cases are true.

With that taken care of, all that was left was to write the code in a console application:

static void Main(string[] args)
{
    double probRainSat = 0.1;
    double probRainSun = 0.3;
 
    int rainyWeekends = 0;
    int oneDayRainyWeekends = 0;
    int bothDayRainyWeekends = 0;
 
    Console.WriteLine("Simulating one million weekends...");
    Console.WriteLine();
 
    Random rand = new Random(Environment.TickCount);
 
    // one million trials
    for (int i = 0; i < 1000000; i++)
    {
        if (i % 100000 == 0)
        {
            Console.WriteLine("{0}...", i);
        }
 
        bool rainedSat = rand.NextDouble() < probRainSat;
        bool rainedSun = rand.NextDouble() < probRainSun;
        if (rainedSun || rainedSat)
        {
            rainyWeekends++;
        }
        if (rainedSat ^ rainedSun)
        {
            oneDayRainyWeekends++;
        }
        else if(rainedSat && rainedSun) // We can use else if because it can't rain on exactly one and both days.
        {
            bothDayRainyWeekends++;
        }
    }
 
    Console.WriteLine("Rain on only 1 day: {0}/1,000,000 ({1})", oneDayRainyWeekends, oneDayRainyWeekends / 1000000);
    Console.WriteLine("Rain during the weekend: {0}/1,000,000 ({1})", rainyWeekends, rainyWeekends / 1000000);
    Console.WriteLine("Rain on both days: {0}/1,000,000 ({1})", bothDayRainyWeekends, bothDayRainyWeekends / 1000000);
    Console.WriteLine("Rain on neither day: {0}/1,000,000 ({1})", 1000000 - rainyWeekends, (1000000 - rainyWeekends) / 1000000);
    Console.ReadLine(); // Keep the program from closing.
}

Now you can run your new creation:

Probability Simulator Results

You just simulated about 19,200 years worth of weekends.

Not bad, huh? If you round, you’re spot on with the calculations. The math predicted almost exactly what the program would do. That, my friends, is pretty cool.

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!!