Coding Basics – Deceptively Simple Programming
In my last post on coding basics, I talked about turning an algorithm into code and used Euclid’s Algorithm as an example of programming a sequence of steps. There’s an even simpler type of algorithm that I want to look at this time.
A formula, such as the one for converting Fahrenheit to Celsius, is also a series of steps that must be performed in order to achieve the needed result. These calculations can be represented within C# or other programming languages to include the formula as part of a larger program.
If you’re doing a one-time conversion from Fahrenheit to Celsius, you’re probably going to pull out your pocket calculator or find a good conversion website and enter the necessary numbers. You can do that because either of those resources has the necessary interface to get the necessary input from you. If you’re including this calculation in a program, you need to design your own interface, process that user input from it and return the result to the user in some way. In the case of the pocket calculator or website, other programmers pondered these issues at some point and now it’s your turn.
Chances are, a formula this simple will be buried within a much larger project and called by the program as needed to process entries from an input form. It’s a minor function in the program’s collection. In this demonstration, I want to show you how this one calculation involves a number of decisions on the part of a programmer. This process might seem complicated now but after a year or two of experience, it becomes second nature.
The Formula
Different programmers approach a task in different ways. I personally like to start with the core functions of the program and let it grow organically so let’s start with the formula itself:
Celsius = (Fahrenheit – 32) * 5 / 9.
The C# language uses many of the same math operators that you’re accustomed to. It also has an Order of Operations which means that certain operators take precedence over others and are processed first. This makes the difference between the following conversion formulas:
75 - 32 * 5 / 9 = 57.22 (wrong) (75 - 32) * 5 / 9 = 23.89 (right)
As you probably remember from school, portions of the formula within parentheses are calculated first so the bottom formula subtracts 32 from 75 and then uses the result to move on to the multiplication and division. The top formula handles the multiplication and division first since those comes before addition and subtraction.
So now we can represent the formula in C# and we can even put it into a simple function that can be called by the program.
static double FahrenheitToCelsius(double fValue) { double cValue; cValue = (fValue - 32) * 5 / 9; return cValue; }
The function accepts and returns a Double value which allows for multiple decimal places. It could accept an Integer, restricting it to whole numbers but this actually makes it easier since the result will probably not be a whole number. The three lines of the function itself declare the return variable, assign the result of the function to it and then pass it back to the code that called it, like so.
int tempCelsius = FahrenheitToCelsius(80)
Of course, the temperature passed to the variable is probably not going to be hard-coded as a number but as input from somewhere else so we have to decided where it’s coming from.
The Interface
Normally, the input for this function would come from a data entry form of some kind, maybe a web interface; the user enters a value in a textbox or with another type of control, the program reads it from there and processes it as needed. For this example, I’m going to use a Console application that collects the data through text prompts and responses from the user. Generally used for utility programs, these also make a good tool for quickly testing some code with inputs and outputs.
In order to get input from the user, the Console program needs to prompt for the needed input and then read the user’s response.
Console.Write("Enter the temperature in Fahrenheit. > "); lineInput = Console.ReadLine();
The Console.Write and Console.WriteLine commands simply output text to the console. The difference between them is that the WriteLine command begins a new line afterward. The corresponding Console.Read and Console.ReadLine commands read the user’s input into the program as a String (alphanumeric) value. Once that value is in the program, it needs to be processed. Since we’re carrying out a calculation, the user input needs to be converted into a number. Some languages would allow what’s called an implicit conversion where the value could just be used as a number, trusting that its content was entirely numeric. C# doesn’t allow this.
parseSucceed = double.TryParse(lineInput, out fValue);
The Parse and TryParse methods will read a String value and output a numeric value if possible. The TryParse function actually returns two values to two separate variables shown here, a True / False (boolean) value indicating if it was successful and an out variable that holds the actual numeric value. The Parse method simply tries to return a number and throws an error if it can’t. There are situations in which the Parse method is fine if you’re certain that the value is numeric or that you can catch the error if it’s not. The TryParse method adds insurance.
if (parseSucceed) { cValue = FahrenheitToCelsius(fValue); Console.WriteLine("The temperature in Celsius is: " + cValue.ToString("#.##") + "."); } else { Console.WriteLine("Please enter a number."); }
Now the program has a decision to make. If the TryParse statement worked, do the conversion and display the result. Otherwise, tell the user to shape up and enter a number that can be converted rather than their dog’s name. Since we don’t want the user seeing values like 27.77777777777778, the function’s result is converted back to a string and formatted to just display two decimal places.
As it stands now, the program will convert one value and then end. We probably want to try out a few values before having to stop and reload so it’s best to throw this into a loop of some kind. One important rule in programming that most programmers will end up learning the hard way is that every loop must have an exit. Infinite loops will either end in program crashes, unhappy users or both. Therefore, we wrap the whole thing in a conditional loop. I’ll go ahead and show the whole program at this point.
static void Main(string[] args) { // Declare the variables to be used. double fValue = 0; double cValue = 0; bool parseSucceed; string lineInput = ""; // Start the program loop. do { Console.Write("Enter the temperature in Fahrenheit. Type 'quit' to exit. > "); lineInput = Console.ReadLine(); if (lineInput != "quit") { parseSucceed = double.TryParse(lineInput, out fValue); if (parseSucceed) { cValue = FahrenheitToCelsius(fValue); Console.WriteLine("The temperature in Celsius is: " + cValue.ToString("#.##") + "."); } else { Console.WriteLine("Please enter a number."); } } } while (lineInput != "quit"); } static double FahrToCelsius(double fValue) { double cValue; cValue = (fValue - 32) * 5 / 9; return cValue; }
The Do … While loop (shown in bold) continues while the user input does not equal ‘quit’. Another IF decision statement tests for the quit command before doing anything else. So long as the user wants to continue, it will test any input and convert it if possible.
Uh-oh … do you see that? The fourth number entered is 32 which returns 0 Celsius but it’s blank! That’s not quite what the program’s supposed to do but it does show the importance of testing with as much data as is possible and practical.
I have an idea where the error might be but I need to test that so I set a breakpoint in the program and run it, entering 32.
At the bottom of the screenshot, you can see that the cValue variable actually does have a value of 0 from the conversion function. It’s not blank – a number is actually returned. This means that the error is probably in the WriteLine statement after it, probably in that ToString conversion I got from an online example. While it probably worked well enough for whoever posted it, it’s not working for me so I do a little more research and, sure enough, the # character will not show a 0 so I change the line to the following.
cValue.ToString("0.##")
The function will now actually show a zero if there is one or will replace it with any other digit returned by the function. Of course, I still tested to make sure that the program would show not only the value that had cause the previous problem but other potential problems.
Lessons Learned
This probably seems like a lot to go through for a simple Fahrenheit to Celsius conversion and it is … because that’s the nature of programming from scratch. Programmers of any skill will dash something like this off in a few minutes and they will consider all of the things I’ve written about here as well as things I haven’t such as formal error handling and commenting. So let’s review what we’ve learned here …
- Coding from scratch takes time and those programmers who you think are just watching YouTube are doing as much work on a relatively simple program as you did on your recent tax return.
- Programming is about problem solving and the ability to analyze the needs of the users or a larger program and respond to those needs.
- Mastery of any given language is useless without the supporting skills to use it well. This is why math classes are important. Computers just do what they’re told. The programmer who does not know about things like Order of Operations will not think to look them up on Google before writing a program that spits out the wrong answers. That results in bugs which cost time and money to track down. Sometimes, when they’re buried deep within a program, they’re not noticed and therefore not found before release and that costs more money and time to fix when they are found. Sometimes, it costs a lot more.
- Test, test again and then test some more. Yes, it’s tedious but it’s better to find your own mistakes than to let someone else find them.
- You can’t be a programmer by copying code from websites. Smart programmer’s don’t put ‘black box’ code that they don’t understand into production and no company wants to pay a programmer’s salary to someone who can’t write their own.
Sign up for our newsletter to receive updates about new projects, including the upcoming book "Self-Guided SQL"!
We respect your privacy and will never share your information with third-parties. See our privacy policy for more information.
0