Common Concepts of Programming Part 6 – Object-Oriented Programming Concepts 1

Introduction

Before we get into the grit of this topic, I suggest setting up a new project in our HelloWorld solution. We can call the project HelloObjects. Object-oriented programming is a vast topic, and there is a LOT of ground to cover. The actual depth of this topic goes far beyond what I can put into a single article. So we’ll start here just by creating a single object and interacting with it a bit.

Advanced concepts will be covered down the line to build on this topic; so understanding what we cover here is critical to the process in the long term.

What are Objects?

The concept of object-oriented programming is, as mentioned before, vast. But really what it boils down to is the simple concept that every structure in your program is an object. Well, that sounds interest, but what does it mean?

An object, in programming terms, is a programmatic structure that describes a related set of properties (variables) and methods (functions). Additionally, an object can contain other objects. In more advanced cases, objects can also consist of events – notifications that fire when something has happened within or to the object. That’s something we’ll discuss much later in this series of articles.

Objects also provide the ability to support ENCAPSULATION, which is a way of protecting access to the data that is part of the object, restricting direct control over that data, and more. In many languages, including C#, objects are commonly described in the form of a CLASS. A lot of languages use the CLASS structure t collect a series of related properties and methods, and make them available as a complex data type – they can work much like the string or numeric data we already have used. But whereas a string or numeric value is relatively simple, and really only represents a single value, classes typically are intended to be containers of more complex data.

A simple example of an Object

A great way to examine this concept is to define an object that describes a person. You’re a person (or perhaps a cat walking on the keyboard). I’m a person (most of the time, anyway). You may have a child that is an example of a person; a spouse that is an example of a person. Your mom and dad are also examples.

What do we have in common? We all have a first name, a last name, a date-of-birth, and probably a middle name, too. Those values, our names and date-of-birth, are all properties we have in common. We can all communicate. We can all listen. We can all move (or at least we all have a defined capacity to move). An adult person can have a job. A child person can be a student. A much older adult may have a former occupation. These can be properties as well. But let’s start out by talking about the simple common parts of all (or most) people.

Creating a person class

A person, in programming terms, could be defined with a class containing some properties that all people should have in common. So if we wanted to make a simple C# class for a person, it might start out looking like this.

class Person
{
    public string firstName;
    public string middleName;
    public string lastName;
    public DateTime dateOfBirth;
}

The above code indicates that we have a class called person. This class has 4 properties; 3 strings representing names, and a DateTime data type representing dateOfBirth. This code doesn’t represent a specific person, but is essentially a template for what a person consists of. If we had an application that was going to make sure of this, we could then create a variable of type person.

using System;

namespace MyNamespace
{
    class Program
    {
        static void Main(string[] args)
        {
            //Create a variable of myPerson; the type of the variable is a Person.
            Person myPerson = new Person();
            //Set value of names
            myPerson.firstName = "John";
            myPerson.middleName = "Michael";
            myPerson.lastName = "Doe";
            //Set date of birth for person
            myPerson.dateOfBirth = new DateTime(2000, 01, 01);

            //Dsiplay back out the person variables values.
            Console.WriteLine("Person's Name: {0} {1} {2}.  Born on {3}", myPerson.firstName, myPerson.middleName, myPerson.lastName, myPerson.dateOfBirth);
            Console.ReadKey();
        }
    }

    // Person class - this is a template of a "person" object
    class Person
    {
        // A property for a person's first name
        public string firstName;
        // A property for a person's middle name
        public string middleName;
        // A property for a person's last name
        public string lastName;
        // A property for a person's date of birth
        public DateTime dateOfBirth;
    }
}

The output of this application would be:

Let’s break down our application example. By now you should recognize that we are using the System library for output. Additionally, you’ll already be familiar with the idea of having a namespace that matches the name of our project: namespace HelloObjects.

And of course, you’ll recognize having a class named Program, with the usual static void main in it. We’ll discuss what’s happening in here in a moment. Let’s jump past it to line 24 and beyond. On line 25, we declare the creation of a class called “Person”.

On lines 28, 30 and 32 we create three string variables; firstName, middleName and lastName. In the terms of object oriented programming, these variables are part of our “Person” object, so we will refer to them as properties of the person object. Finally on line 34, we are creating a property of the type DateTime called dateOfBirth.

You will notice that all of these properties start out with the keyword PUBLIC. We will discuss this keyword and it’s meaning more at a later time. For now, we just need to understand that these properties are directly accessible any time we create a “Person” object. You might also notice that, unlike the “string” keywords, DateTime has a capital D and T, and instead of being blue in Visual Studio, they’ll be green (the colors might be different depending on the theme you selected for appearance, but the significance of a different color is more important than the colors themselves).

A DateTime is a complex type of variable / property. Rather than being something simple like a numeric value, like an INT or FLOAT, or even a STRING, a DateTime is a complex object that has additional properties of its own. Essentially, a DateTime is another type of class, just like our “Person” class. That means it has methods and properties that are part of its structure.

It also should demonstrate to you that an object can actually have other objects as child elements. This is a big deal, simply because it means you can create many different types of structures, which become part of other structures, which in turn become part of other structures, allowing for all sorts of possibilities for complex problem solving.

For now, we’re just treating this as a simple property of our person, and we’ll use it as one more piece of data associated with the Person. I also want you to pay close attention to the fact that our person class does not sit within the program class, but sits separate from it, but still within the same “namespace” container. This means that the Person object is a class that exists independent of the program itself. Later on, we’ll learn how to put these classes in a general space that makes them available in other places in a program.

I also want to note, quickly, that you COULD in theory put the Person class inside of the program class, but that would prevent you from being able to use the person at any point other than inside of the program class. While it might not seem like a big deal, it’s something you should probably avoid doing, as it can lead to all sorts of headaches when you’re trying to solve problems.

Now that we have a definition of a Person object, we’ll go back to the main method for our program, and look at what we do with this object. It’s not a lot, yet, but it’ll demonstrate the basics pretty easily.

On line 10, I create a new “Person” variable called myPerson. We are setting it to a new instance of a Person object. What if we just did the first part and created the myPerson variable, but not the “new” part? Well, nothing would go wrong on that line, but as soon as we tried to set a value of firstName, we’d have a problem. Attempting to assign a value to a property of an object that is not initialized to a new instance of the Person object would give us an error: Use of unassigned local variable myPerson. When we create a variable of a complex type, we need to actually set it equal to a new copy, or sometimes an existing copy, of that object. Without doing this, we’re really saying that we are reserving a placeholder for that type of object, but not really indicating that there is an actual object in that space.

Think of it light a parking space. We say that a parking space is for a vehicle. But if someone tells you to get into the vehicle that is in that parking space, and there is no vehicle there, you have a problem… you can’t get into what doesn’t ACTUALLY exist. So if we were to instead say “This is a parking space with a parked vehicle in it”, we have now initiated the space to have a vehicle that we can then interact with.

So line 10 creates our variable, it creates a new instance or copy of a Person, and we are ready to proceed.

Lines 12 through 14 each set the property of first, middle and last name equal to a value.

Then, we get to line 16. Many of the properties of the DateTime objects are read-only. Year, month, date, hour, minute, second… these are all properties that we cannot directly change. We can only set these values directly when we initialize the DateTime object, which is what I’m doing on that line. I am saying that the value for dateOfBirth will be a new DateTime object with a year of 2000, a month of 01, and a day of 01.

What if you needed to change it later? The simplest solution would be to just set the property equal to a new DateTime with new values. We’ll worry about that sort of complexity at another time.

Finally, we get to line 19, where we print back out the data we stored into our object. Since all of our properties are public, we can just directly pull those values by calling the myPerson object with the .property approach. And of course, line 20 is there so we can see output on the screen without the program immediately exiting.

Conclusion

Although it might not seem it, yet, we just took a MAJOR step in programming. Object-oriented code is a big piece of the underpinnings of most programming languages, especially those used in the software side of development. They are important in hardware development, too, but the value of creating objects and instances will become manifest as time goes on.

The next phase of this process will build on our “Person” object by introducing the idea of “access modifiers”. That is, we start to learn about the significance of the PUBLIC keyword we used above, and start learning the alternative options.

Common Concepts of Programming Part 5 – Loops and Repetition

Introduction

During the prior article, we looked at the basics of using logic to control the flow of our program. The logic involved testing for certain values in variables, and executing different blocks of code based on the outcome of those tests.

This is valuable, to be sure; but what are we to do if we need to repeat a particular segment of code multiple times? Do we want to set the same code into our application over and over? Unless we have a fixed number of repetitions that is very small, this is anything but efficient.

For example, what if we wanted to execute our HelloAdvancedWorld project multiple times without needing to restart it each time? What if we wanted to say hello to multiple people at once? What if we want to force a person to enter a name to say hello to, and we refuse to move forward until they do?

What we’re describing in each of these cases is a case of repetition; and we accomplish the process of repetition in programming by using a loop. For the following lessons, we’re going to set up another new project, this time called HelloLoopWorld. Make it part of the same solution, yet again, and make sure to set it to be the default project, using the drop-down menu next to the Start / Play button. If you need, go back and look at how we did this in the prior article – you should be able to do this in a fairly straight forward manner now.

After that, we’ll be ready to start diving into loops.

What is a loop?

There’s actually only a few things to discuss when it comes to the subject of loops. Essentially a loop is a block of code that repeats until some condition set is met or while some condition set is not met.

In some rare cases, a loop may actually be continuous. This is referred to as an infinite loop. In most cases, this is something that should be avoided; infinite loops can potentially cause a system to lock up, or to run out of available processing power or memory, leading to a crash of the computer. However, there are some instances in programming where such loops are necessary.

For our purposes, we’ll look at normal loops; those that are terminated by condition sets.

Loop Structures

Loops are generally accomplish with one of 3 general approaches: while loops, do-while loops, and for loops. Each of these approaches involves a key word or key words, with a set of brackets used to contain the code that is to be repeated. They key words will be accompanied with a set of conditions inside of a series of parenthesis, similar in many respects to the if statements we encountered in the prior lesson on conditions. In fact, the syntax within the while and do-while loop is identical in every respect to the conditional controls, because a loop’s translation is “if this condition is not met, do this again” or “if this condition still exists, do this again”. So when you have a handle on the if statement, you have a major portion of the while and do-while loops already figured out.

The other loop, the for loop, is a little bit more complex, but ultimately, the approach to coding with them can achieve the same thing. We’ll examine this in more depth later in this article.

It’s also good to note, there are a few other specialty case loops we’ll encounter in more advanced coding later on. A variation of the for loop, called the foreach loop, is found in more intricate programming methods. It’s not really any more difficult than the standard loops we’ll start with, but it requires some more elaborate data work to be of any significance to us.

Additionally, we’ll learn about a more sophisticated topic, RECURSION, which can be a bit tricky to get a handle on, but offers a LOT of valuable functionality with more advanced types of data.

In this lesson, we’ll discuss the FOR loop, but we’ll only do a serious implementation of using a WHILE or DO-WHILE loop. Seeing this form in use will give us a handle on the concept, and being aware that there are other approaches will suffice for a solid starting point.

While Loops

As stated before, loops are simply a method of repeating a set of instructions until some condition is met. And a “while” loop is as simple a loop as possible. The general structure of a while loop translates into “While this condition needs to be tested, do these instructions”. Here’s an example that will “count” to 10, taking a break each time.

//Created a "counter" integer and set it to 1
int i = 1;
while (i <= 10)
{
    Console.WriteLine("I am at {0}.  Press any key to continue", i);
    Console.ReadKey();
    i++;
}
Console.WriteLine("We have completed the loop.  The value of the incrementer is {0}", i);
Console.ReadKey();

You can put the code above into our Main method, and execute it. Each time a line is printed, you can press your enter key, until you see our final message. indicating the loop is completed.

So what happens is that we initiate an integer variable named “i” and set it equal to a value of 1. The next line indicates that we are creating a WHILE loop that will repeat while the value of “i” is less than or equal to 10. The loop consists of writing to the console the value of i, and instructs the user to press any key for the next step.

The method of print the message here is generating a sort of preformatted message. We are indicating that the line will print out message with a placeholder at {0}. By doing this, we can then substitute in a value, by adding that value at the end of the command, before the closing parenthesis. We could do similar things by printing a message like:

Console.WriteLine("This is variable 1 {0}, this is variable 2 {1}", var1, var2);

And the contents of var1 and var2 would get substituted into {0} and {1} respectively.

Back to the loop. We wait for the user to press any key, and then proceed on. In this case, we increment the value of i. Since it is a numeric value (specifically, a whole number) we can either write i = i + 1; or i++; Both of these accomplish the same thing – adding 1 to the current value in ‘i’. Then our condition in the while loop tests again. If the value of ‘i’ is less than or equal to 10, the process will repeat.

This brings up an important lesson as well. This test is happening before each set of instructions. In this case, we started with a value of 1. We print 1, then we increment to 2. The value is tested again, and is less than or equal to 10, so we print 2, increment to 3. Then the value is tested again, resulting in a 3, which is less than or equal to 10. So we print 3, and increment to 4. This continues through the point where we increment ‘i’ to 10. We do the test, and find that ‘i’ is less than or equal to 10, so we print 10, then increment again to 11. Now, the value of i is no longer less than or equal to 10. It’s 11. So we skip past the loop code, print out our “completed” message, and wait for a key press to end the program.

Now, what will happen if we put i++; BEFORE our ConsoleWriteLine to print out the value?

while (i <= 10)
{
    i++;
    Console.WriteLine("I am at {0}.  Press any key to continue", i);
    Console.ReadKey();
}

You can give it a try to see how the output changes; just make sure to restore our application to this before you move on. Our full application should look like this:

using System;

namespace HelloLoopWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            //Created a "counter" integer and set it to 1
            int i = 1;
            while (i <= 10)
            {
                Console.WriteLine("I am at {0}.  Press any key to continue", i);
                Console.ReadKey();
                i++;
            }
            Console.WriteLine("We have completed the loop.  The value of the incrementer is {0}", i);
            Console.ReadKey();
        }
    }
}

Do-While Loops

As mentioned before, the WHILE and DO-WHILE loops are fairly similar in nature. So if we wanted to write the above code with a DO-WHILE loop, the code would look like this:

//Create a new counter integer and set it to 1
int j = 1;
do
{
    Console.WriteLine("I am at {0}.  Press any key to continue", j);
    Console.ReadKey();
    j++;
}
while (j <= 10);
Console.WriteLine("We have completed the loop.  The value of the incrementer is {0}", j);
Console.ReadKey();

The code looks remarkably similar to the regular WHILE loop. In fact, the only major change is that we moved the “while” part to the end of our loop block, and ended it with a semi-colon, then put the word “do” before the loop block. The only other change of any sort is that we changed the name of the variable “i” to “j”, just so we could keep them distinct in the same program. If you put THIS into the application and run it, it’ll do the first set of repeats, then do the second set, and they’ll come out exactly the same.

So what is the point of having two different structures for the exact same thing? Well, the truth is, they’re not EXACTLY the same. to understand what I mean, change the lines for int i = 1; and int j = 1; to both have an initial value of “11”. Right now, the code will look like this (note that I commented the value of i for each integer so I know what the original value is supposed to be).

using System;

namespace HelloLoopWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            //Created a "counter" integer and set it to 1
            int i = 11; // normally set to 1 - changed to 11 for demonstration;
            while (i <= 10)
            {
                Console.WriteLine("I am at {0}.  Press any key to continue", i);
                Console.ReadKey();
                i++;
            }
            Console.WriteLine("We have completed the loop.  The value of the incrementer is {0}", i);
            Console.ReadKey();

            //Create a new counter integer and set it to 1
            int j = 11; // normally set to 1 - changed to 11 for demonstration;
            do
            {
                Console.WriteLine("I am at {0}.  Press any key to continue", j);
                Console.ReadKey();
                j++;
            }
            while (j <= 10);
            Console.WriteLine("We have completed the loop.  The value of the incrementer is {0}", j);
            Console.ReadKey();
        }
    }
}

Now, when you run the code again, you’ll get this:

Wait, the first loop skipped and just gave us the expected message of the incrementer being 11. The second one actually printed a message at 11 and then told us the incrementer as 12. What happened here?

The answer is fairly straight forward. If we initially ran through with the value started at 1, loop 1 would run through, and after i became a value greater than 10, it would skip the loop and print out the post-loop message. When we ran through the second loop in the same fashion, it would start at 1, print the messages through 10, and then when it was greater than 10, print the post-loop message.

When we changed the starting values to 11, the first loop immediately tested and found the value greater than 10, bypassed the loop entirely and went to the post-loop message. On the second loop, the value started at 11, and the message was printed, and then it was tested to see that the value was greater than 10, so it did not repeat.

The short version is, a WHILE loop tests before it ever executes the loop. DO-WHILE loops execute 1 time BEFORE the test is performed. So in summary, a WHILE loop will immediately test before it attempts to run through the looped instructions, and a DO-WHILE loop executes the instructions at least once BEFORE it attempts to test. If you want a piece of code to execute once before you test for some value, use a DO-WHILE loop.

Input Loop Demonstration

Let’s see if we can demonstrate the value of this a bit more. Create another new project called HelloLoopInputWorld. When the project is created, we’ll create some code in the Main method to demonstrate WHILE and DO-WHILE logic.

First, let’s create a variable called myName of type string. Then, use the console commands to request the user’s name, and to read in their input to our variable

string myName;

Console.WriteLine("What is your name?");
myName = Console.ReadLine();

Next, we need a loop to check the value of the input, and determine if it has been populated with a non-blank character.

while (myName.Trim().Equals(string.Empty))
{
    Console.WriteLine("You must enter a name.");
    myName = Console.ReadLine();
}

Finally, we can put in a post-loop command to say hello. And after that, add a ReadKey() command to hold position in the program until we’re done.

Console.WriteLine("Hello, {0}!", myName.Trim());

Console.ReadKey();

If you’ve written your code properly, you should have a program that looks like this; I’ve added comments to clarify each section in relation to the lesson.

using System;

namespace HelloLoopInputWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            //Create Variable
            string myName;

            //Request user enter name
            Console.WriteLine("What is your name?");
            myName = Console.ReadLine();

            //Check if name is an empty string when trimmed, and repeat until it's not
            while (myName.Trim().Equals(string.Empty))
            {
                //Prompt user to re-enter their name
                Console.WriteLine("You must enter a name.");
                myName = Console.ReadLine();
            }

            //Post-loop response
            Console.WriteLine("Hello, {0}!", myName.Trim());

            //Wait for any key to end
            Console.ReadKey();
        }
    }
}

If you run the application a few times, you can test to see what’s happening with the logic. On the first run, enter a value, like your name, or even the word “Test” immediately when prompted. The application will never display the line about how “You must enter a name.” If you run it a second time and hit enter, or a few spaces followed by enter, you’ll notice that it keeps prompting the user until they put in an actual, acceptable value.

Now that we have done a WHILE loop this way, let’s make a DO-WHILE loop as well. We can use the same project for this. After the Post-loop response, but but before the final Console.ReadKey() command, add in a few blank lines.

We can re-use the myName variable since we don’t need to preserve that information for anything else. However, we’ll set the variable to NULL. NULL is a value that means that the myString is set to non-existence, which is actually different from saying it exists, but is empty. Doing this is as simple as sying “myName = null;” Create a DO-WHILE loop, and make the condition the exact same as it was in the WHILE loop. After the loop, we can place our message to print out the name, exactly as we did for the WHILE loop.

//Set myName to non-existent value
myName = null;

//DO WHILE loop
do
{
    //REPEATED CODE IN HERE
}
while (myName.Trim().Equals(string.Empty));

//Post-loop response
Console.WriteLine("Hello, {0}!", myName.Trim());

Now there are a number of ways we could handle getting the data from the user and printing responses. We can have the input read into the variable, and if the input is empty, print out a message. We could use a condition to check if this method is a repeat. and if it isn’t provide a different message. We could do an IF-ELSE approach to checking for what was put in. The truth is, there’s no single way to do it that’s necessarily “better” than another, so long as we keep it as simple as we can.

In this case, since I have already set the value of the variable to NULL before the loop starts, I can use a check on that to change the message that comes out inside the loop. Like so:

//REPEATED CODE IN HERE
if (myName != null)
{
  Console.Write("You didn't enter a name. ");
}
Console.WriteLine("Please enter your name.");
myName = Console.ReadLine();

The entire program should now look like this:

using System;

namespace HelloLoopInputWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            //Create Variable
            string myName;

            //Request user enter name
            Console.WriteLine("What is your name?");
            myName = Console.ReadLine();

            //Check if name is an empty string when trimmed, and repeat until it's not
            while (myName.Trim().Equals(string.Empty))
            {
                //Prompt user to re-enter their name
                Console.WriteLine("You must enter a name.");
                myName = Console.ReadLine();
            }

            //Post-loop response
            Console.WriteLine("Hello, {0}!", myName.Trim());

            //Set myName to non-existent value
            myName = null;

            //DO WHILE loop
            do
            {
                //REPEATED CODE IN HERE
                if (myName != null)
                {
                    Console.Write("You didn't enter a name. ");
                }
                Console.WriteLine("Please enter your name.");
                myName = Console.ReadLine();
            }
            while (myName.Trim().Equals(string.Empty));

            //Post-loop response
            Console.WriteLine("Hello, {0}!", myName.Trim());

            //Wait for any key to end
            Console.ReadKey();
        }
    }
}

If you’ve put together your code properly, when you run it, you’ll be prompted for your name, and then get a response. Then it’ll prompt for your name again. The new approach will Tell you that you didn’t enter a name, and prompt you again, repeating this until there is a non-emtpy, non-null value.

For Loops

FOR loops aren’t really a drastic difference from the WHILE / DO-WHILE loop logic; in general they can accomplish many similar things. Though there are a few, small, key differences in how they work and are used. First, let’s talk about the setup.

FOR loop controls typically consist of 3 pieces of logic: initialization, condition test, and iteration. So rather than having to create an initial value on one line of code, then do a loop for testing that condition on another line of code, and having a place where logic increments a value like a counter on a third line, we can do them all in one comprehensive step. So for example, if we wanted a simple counting loop like so:

int i = 0;
while (i < 100)
{
    Console.WriteLine ("Loop value {0}", i);
    i++;
}

We can instead combine all of these into

for (int i = 0; i < 100; i++)
{
    Console.WriteLine("Loop value {0}", i);
}

These example will produce the same exact code; but there are differences in what a WHILE and FOR loop do to accomplish things. First, in a WHILE loop, the actual iteration (in this case, the incremental increase of an integer) happens as part of the body of the loop, where as in the FOR loop, it’s a part of the loop structure itself. This means that in a WHILE loop, you’re responsible for that step at some point in the logic of the body of the loop itself.

Second, in FOR loops, the logic of the iteration happens after the body of the loop is created, and can not be skipped in any fashion; it’ll be precisely the same increment at each step. In a WHILE loop, however, we can use conditions to change what happens in each loop cycle; we can use this to prevent iteration, or iterate by more than a default value.

Finally, if you write a FOR loop without a condition to test, you can lead to an infinite loop; you might desire this, but you do need to be careful of the impact of such code. Meanwhile, in a WHILE loop, you MUST have a condition to test, or you application will not build.

It’s not uncommon to hear people say that for loops are best when you know a select number of iterations that will be needed for a loop, and while loops are best used for instances where you don’t know what the number of repeats will be, but that’s not entirely true. Most types of iterative objects (objects that can be looped through) provide a mechanism to get the size, or length or some other value indicating the maximum number of times to iterate through something, so in most cases, this isn’t a concern, strictly speaking.

And in most cases, you can actually go with either approach. Realistically, the alternate logic for iterations is probably the most important aspect of such logic. This will become more obvious in later lessons when we work with more advanced data structures. For now, seeing the different approaches is the most important lesson to be learned.

Conclusion

As we wrap up this lesson on the fundamentals of loops and looping, you might wonder why it is that we didn’t do any more detailed examples than what we have so far. We really didn’t implement an example of a FOR loop in a project, we didn’t really do a whole lot with even the WHILE or DO-WHILE loops.

The reason is that we have a few more things we’ll need to cover to make more effective use of these logical blocks. We could write a simple demonstration, and that would be all well and good, but it would be a LOT of work to set up static loops to accomplish very little of value. The next lesson we’ll have will introduce us to working with OBJECTS, and a further lesson will expand on that topic. When we’ve done both of those things, we’ll have more information and have a better use for the techniques of looping.

Common Concepts of Programming Part 4 – Conditions

Introduction

In this segment of the introduction to programming concepts, you’ll learn about the basics of some additional common programming elements by adding in some conditions. When this section is done, you’ll be ready to start discussing more significant programming concepts, and will be able to handle the solid fundamental lessons, building some simple programs that build up core skills.

Hello, World – enhanced

Up to this point, we’ve only worked in a limited fashion with actual code; it was very important to discuss key concepts before we dove right in. Now that we have looked at concepts like data types, we’re ready to expand the function of our HelloWorld program. Rather than modifying the existing code, however, we’re going to add another project into the solution we started, and use that to build a slightly more advanced version of the original application.

Open up Visual Studio 2019. You’ll end up at the launch menu, where you should see the HelloWorld.sln solution we made in our prior lesson. Go ahead and click on that entry to get started.

Our existing application should open up with the source code for the HelloWorld file.

We’re going to create a second project within the solution, and use that to make our expanded program. From the File menu in the upper left hand corner of the window, select New > Project. Since we have already created a Console App (.NET Framework) before, it will show up under “Recent project teamplates”. Click it once to highlight it, and click the “Next” button.

We are presented with the “Configure your new project” screen.

For Project name, enter HelloAdvancedWorld. Change “Solution” from “Create new solution” to “Add to solution”. The location should default to the fold containing the existing HelloWorld solution. The solution name field will be grayed out, but will say “HelloWorld”. Finally, make sure you’re set to the latest Framework. For my system, this is .NET Framework 4.7.2. Click on the “Create” button. A quick note, it is also possible to add projects in using the “Solution Explorer” panel on the right side of the Visual Studio Screen. You simply right click on the solution name, scroll down to “add” and click on “New project”. The process will be nearly the same, though the “Configure your new project” window will look like the one below, instead of the one we saw above.

You should now notice a few changes. First, in the “Solution Explorer” panel, we’ll see our new project, “HelloAdvancedWorld”, along with the existing “HelloWorld”. Each project will have a few elements underneath: Properties, References, App.config and Program.cs. Now at first, it might seem odd that there are two entries for each of these, but realize that each project has it’s own folder in the solution (both in the application and on your hard drive), and the elements of each project are independent of each other.

Additionally, the main toolbar up above now has an additional drop down menu in it. After “Debug” and “Any CPU”, we should now see “HelloWorld”, followed by the play arrow / Start button.

If you click on that drop-down, you’ll see our other project, HelloAdvancedWorld, as an option.

If you change to our new project, you’ll be able to run that project instead of the original one. And you can always change back if you need to. Also note; if you change which project is the Active one in this menu, the title of that project will take on a bold font face in the Solution Explorer.

In the new Project.cs, replace the existing code with this:

using System;

namespace HelloAdvancedWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello, world!");
            Console.ReadKey();
        }
    }
}

This is the same as the code from the original project, with two small differences. First, we’ve removed all of the using statements we don’t need. Second, you should see that the namespace on this version is HelloAdvancedWorld. If you recall in the Getting Stated with Visual Studio 2019 article, I mentioned that a namespace is a sort of container for code. The common practice in C sharp and many other C-styles languages is to have a namespace that matches the project name. A namespace allows you to have multiple blocks of code in there which are then all part of the same “package”. The advantage of this is, if you use a meaningful naming convention for your namespace values, if you have a component that has a similar name to a component from another project or library, the C sharp compiler will understand that you mean this specific version; it’s a way of clarifying which blocks of code you are referring to when names of those code blocks could overlap.

For now, HelloWorld and HelloWorldAdvanced are sufficient. In later projects, we’ll look at better ways to organize using the namespace approach, and you’ll be able to see how it benefits you to have unique namespace values.

If we run this program, nothing new is going to happen yet, because it matches the original HelloWorld application exactly. It’s time to change that a bit.

Let’s replace lines 9 and 10 with some new code:

Console.Write("What is your name? ");
string myName = Console.ReadLine();

Console.WriteLine("Hello, " + myName + "!");
Console.ReadKey();

Make sure you switched that drop-down to “HelloWorldAdvanced”, then go ahead and run the project.

You should be prompted for your name. Go ahead and type in your first name, then hit enter.

It might not seem like much, but you actually did accomplish something important. You received input from the user, and you used it to display back out a message. It’s an important first step in building something much larger. Go ahead and exit the application by pressing any key, or closing that window.

So what did we do? Let’s look at the code. I’m only going to focus on the 4 critical lines, but here’s the total code we have.

using System;

namespace HelloAdvancedWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.Write("What is your name? ");
            string myName = Console.ReadLine();

            Console.WriteLine("Hello, " + myName + "!");
            Console.ReadKey();
        }
    }
}

Line 9 – We’re writing out the message “What is your name? “. The extra space character at the end is to allow us to make the input look a bit neater. Note how this line is “Console.Write” instead of “Console.WriteLine”. I mentioned in a prior article that WriteLine automatically adds a carriage return, or a new line character, at the end of the display process. Write does not add on the character. By using the “Write” command, we can then read in the input directly after the display; it’s a nice way of setting up an input form. It doesn’t affect anything, logically, but it’s nice to know we have that sort of option.

Line 10 – We start out by declaring a variable named myName, with a type of “string”. This means we’re creating a placeholder and assigning it an easy to remember name. Next, the = sign indicates that we’re going to store something into that variable. In the simplest of terms, we’ll need to store in a value that is of the string type. Remember that numbers can be included in a string, but if you use them, they’re being used for non-calculation functions; in other words, they hold no significant mathematical value, they’re just more character that we’re going to display.

Line 10 finished off with Console.ReadLine(), followed by a semi-colon. The Console object, part of our System library, allows for both input and output to the command line / console window. In this case, Console.ReadLine() indicates that the program will continue reading in characters until it encounters a carriage return / new line character – indication that you have pressed your enter key. So the entirety of this line reads as: create a new string variable, call it, myName, and use it to hold the value that the Console reads in, up until the point that the user presses the enter key. It might sound like a lot, but the syntax actually is pretty simply if you stop to think about it.

Line 11 is just a blank line, and remember that the computer will just ignore those blank lines and spaces. It’s convenient to us for organizing code, but the computer doesn’t care if you’re not ordering it to do anything there; it just moves to the next instruction.

Line 12 – Now that we have a value for “myName”, we are going to print it out as part of a message. We indicate that we are going to perform a Write to the Console. We’ve used Console.WriteLine before, so let’s take a look at the information that we’re sending in between the parenthesis. “Hello, ” + myName + “!” turns into “Hello, Greg!” if we type in my name when prompted. The data in the parenthesis is a string; but it is one that is concatenating a variable into the rest of a hard-coded string; in other words, we’re using the actual text “Hello, ” and concatenating (or adding on) the value of the myName variable; then we add on another actual text string, the final exclamation point. When working with string, you can concatenate multiple string together by using a + and either a literal string encased in double quotes, or a variable that can output data as a string. It is possible to output actual numeric variables as string as well. There are other ways of printing out the data, using essentially a substitution approach. I’ll cover that in just a little bit.

Line 13 – This should also be familiar from the original HelloWorld application. This command is essentially pausing for more input; the difference is that this time, the input will be any single character. Whatever we press will qualify as a read key, and the program will move to the next instruction. However, given that there aren’t any more instructions, the program will simply end. If we did not include this line, the prior line printing our message would execute and the program would exit immediately. And in all likelihood, no one would have been able to read the message fast enough to know what it said. So this is useful to make sure you can see everything that appears on the screen, and not quit until you’re really ready to do so.

So much code, so little action

It might seem like we had to go through a lot to make that little bit happen; and in some ways, that is very true. However, the fact is that we’ve learned how to process both input AND output, and that covers a big chunk of what we do with programming. Remember that a computer is primarily a device to speed up mundane, repetitious processes, or to handle complex calculations rapidly without error. So being able to read and write output is a major part of the process; having the ability to process data would be of little use if you could never set up what to calculate, or never see the results of those calculations.

And the truth is, as we build more sophisticated programs, some (or much) of the code will be repeatable and reusable, so while a simple program like Hello, World seems like a lot of work for a very minimal payoff, remember that it’s really serving as a foundation for building something more meaningful. Boiling water isn’t exactly exciting or special, but if you don’t learn how to boil water properly, there are a lot of dishes you’d never be able to cook properly, if at all.

Success doesn’t mean having an answer…

So what do we do if a person is prompted for data and just hits enter? Well, under our current program, the output would be: “Hello, “. Well, that’s not really correct, is it? They could put in any sort of value and it would at least seem plausibly correct. But what about if they leave it blank? Maybe we should do something different. Let’s use a condition to handle that.

We’re going to modify our code a bit. Replace the code on line 12 with the following:

if (myName == string.Empty)
{
    Console.WriteLine("Hello.  You didn't tell me your name!");
}
else
{
    Console.WriteLine("Hello, " + myName + "!");
}

Now, run your program again, and when prompted for your name, just press enter.

Now, by not putting in any value, we get a different message. Let’s break down the new code.

Line 12 – This is a test for a condition; commonly, we can use the key word “if” to indicate that we need to test one or more conditions for truth – hence the name “if statement”. If statements are one type of conditional test; we check to see if one or more conditions evaluates to true, and if they do, we will execute the code nested in curly braces following the “if” line.

Now, some languages will let you state “if” followed immediately by the condition. Most proper languages, however, require you to put your test inside at least a single set of parenthesis. So in this case, we’ll check to see if myName is equal to an empty string. “if (myName == string.Empty)” is literally able to translate into “if the value of myName is equal to an empty string”. The double equal sign is critical here. Remember from earlier, we used a single equal sign to set myName to the value of the Console.ReadLine. If you used a single equal symbol during the condition test, you’d be trying to say “if I store an empty string into myName”. First, this would mean that you’re overwriting the value that was already stored in your variable; second, it would conceivably mean that any time you hit this logical test, the result would always be true – you’d always be able to store the variable. Some languages allow this sort of syntax; C Sharp, however, will thrown an error, because it is expecting the conditions in the parenthesis to be something it can evaluate. Storing a variable is an action, not an evaluation, so the compiler won’t even let you do this. A double equal (==) always indicates comparison. The string.Empty portion of our condition actually is a property that translates into a string with no characters. This means that there is technically a string, it’s just that it has no significance. It is possible to have a string variable that is set to nothing (also called null) which has a different meaning. Null values are something we will discuss another time. For now, we’ll move on.

Line 13 is an opening curly brace that is matched by the closing brace on line 15. And the line in between is what will happen when we have met the condition of an empty string.

Line 16 – Else is the alternative, default condition that is assumed if the conditional check is not met. It is a ways of saying “if any other test we did did not succeed, we’ll do this instead”. The else statement must always follow the closing curly brace of a prior “if” condition. Then the bracketed code following it will execute instead of the initial conditional block.

There is a problem with this code, however. If you run the application, a user might decide to hit the space bar instead, and then hit enter. This is a problem; we’re only alerting them that they didn’t enter a name if they have a string that has no characters. We haven’t accounted for a string that has characters that are all blank spaces.

Go ahead and run the application and you’ll see what I mean.

Well, that isn’t any good. What we need to do is test to make sure they’re not just entering a string consisting of blank characters. But there is a problem; that string could be up to 2 billion or more characters in length; and if we want to check for a string with that many possible spaces, it means we’d need to test each case individually. That means having to check for 2 billion possibilities!

Fortunately, we don’t need to do something crazy like that. Instead, we’re going to modify line 12 from this:

if (myName == string.Empty)

to this:

if (myName.Trim() == string.Empty)

Trim() is a method that exists on all string variables, and on all methods or functions that generate a string as a return value. The Trim() method in it’s basic form removes any blank characters before the first non-blank character, and after the last non-blank character. So for example, if you had a string with a value of: ” Test “, the Trim() method would turn that into “Test”, without any spaces before or after the first and last T. By applying that method to our variable, we will only print our hello message if we have a value in myName that consists of visible characters.

Comment your concerns

Let’s be honest; you’re probably not going to carry this website around with you all the time – so you won’t necessarily have my documents ready to explain what we did here handy immediately. If only there was a way to leave a note for ourselves in our programs that explains what we did, but will not actually be treated like instructions for the program itself. Well of course, we can do that!

The notes we want to leave for ourselves are called “comments”. And every language has them in some form. In most C-styles languages, comments can be made in one of two ways. The first, is to put to forward slashes next to each other, like so:

//this is a single line comment

The single line comment starts the moment you have the two slashes, and continues on until the end of that line. The nice thing about this is that you can put them after an actual programming command, like so.

int i = 0; // Initialize the variable to 0

The second option is to use /* and then use */ at the end of the comment. This allows for multiple-line comments. This way, if you have a longer explanation, you can prevent a need to scroll sideways a long distance to read the whole message.

/* This is an example of a multiple-line comment.  It makes it
   very easy to read this comment if you don't need to scroll sideways
   to read all of it.  This is a great way to leave detailed explanations
   in your code.  That's a very good habit to get into. */

All of those lines will be ignored by the compiler now. There is one other great use of the commenting system – it’s good for temporarily disabling a block of code for testing, or to disable a block of code if you’re replacing it with a new block of code, so you can compare what was there previously. Like so:

   /* if (i == 0)
   {
       Console.Write(" Print out a value ");
   } */

   if (i < 1) // Changed to this to handle negative values - less than 0
   {
        Console.Write(" Print out a value ");
   }

Now that you know this, I will give you a piece of advice – DO NOT HESITATE TO LEAVE YOURSELF COMMENTS. Trust me when I say, commenting your code, regardless of the language, regardless of the platform, is an invaluable capability. Never feel that it’s ridiculous to leave yourself a lot of notes. The more effort you put into leaving detailed, meaningful notes, the less of a strain it is later to remember what you did, and why.

Nesting Code

We’ve already discussed nesting code to some extent, using the curly braces { and } to block out code. Let’s take that a step further by getting some additional information from the user and nesting our code to process it. First, comment out the “if… else” block on lines 12 – 19. You can either do a series of single line comments, or use the multi-line comment approach by placing /* at the start of the block and */ at the end of the block.

//if (myName.Trim() == string.Empty)
//{
//    Console.WriteLine("Hello.  You didn't tell me your name!");
//}
//else
//{
//    Console.WriteLine("Hello, " + myName + "!");
//}
/*if (myName.Trim() == string.Empty)
{
    Console.WriteLine("Hello.  You didn't tell me your name!");
}
else
{
    Console.WriteLine("Hello, " + myName + "!");
}*/

One neat trick to make you aware of with Visual Studio is that you can select a bunch of lines, press the control key (Ctrl) and then press the k key, then release and press the c key. This will turn all of the selected lines into comments. By using the Ctrl key, pressing k and then u, you can un-comment those same lines. It’s a handy shortcut to know.

OK. Let’s add a comment in to keep track of out code. On line 10, before the creation of our variable, hit your enter key, so we can put in a new line. Then go back to the new, blank line, and type in a comment that says “Get variable for name”. That should leave your variable creation on line 11. Create an extra line on 12 so we can space out the next block of code. Then add in a console write for “What is your gender (m/f) ?” Go to the next line and leave a comment that says “Get variable for gender”. Finally, add in a line to create another variable of type string, call it myGender, and set it equal to “Console.ReadLine();” When you’re done, the new block of code should look like this.

Console.Write("What is your name? ");
//Get variable for name
string myName = Console.ReadLine();

Console.Write("What is your gender? ");
//Get variable for gender
string myGender = Console.ReadLine();

Next, let’s write some more code to handle using this input. First, we’ll determine the output based on the gender. This will introduce us to a few concepts. We’re going to do a test for multiple conditions. We want to see if the gender is equal to an ‘m’, an ‘f’, or any other value; we will then print out an appropriate message. Here’s the code we can plug in to do this.

//Check if myGender is set to an f or an m
if (myGender.Trim() == "f" || myGender.Trim() == "m")
{
    //Start printing the message for a specified gender
    Console.Write("You specified a gender of: ");
    
    //If gender is f
    if (myGender.Trim() == "f")
    {
        //finish print - female
        Console.WriteLine("female.");
    }
    //If gender is m
    else
    {
        //finish print - male
        Console.WriteLine("male.");
    }
}
//If gender is not f or m
else
{
    //Print alternative message
    Console.WriteLine("You specified a gender of other or did not specify a gender.");
}

Phew! That’s a lot of code, isn’t it? This code should follow the line where we read in the myGender variable. I put in an extra blank line just to keep things a bit easier to read. Go ahead and run the application 3 times. For each run, enter a different value for the Gender question. Try m, f and o. If you want, you can try any other value for the 3rd test. You can even leave it blank.

You should be able to get an answer of male, female and our “other” message. Now, try running it one more time, and this time, make your gender a capital M or capital F. You might see something you don’t want.

We put in M. Why didn’t we get the male message? Our condition was case sensitive. We have a few ways we can deal with this. The first is to do multiple tests, the second will allow us to streamline our coding. But first, let’s talk about our “if” statements.

When we did our first test, we said:

if (myGender.Trim() == "f" || myGender.Trim() == "m")

This translates into: if we trim the value of myGender of blank space and get a value of f, or if we trim the value of myGender of blank spaces and we get a value of m, we’re going to proceed into this part of our logic. The alternative condition(s) will be met about 18 lines later, with the line that simply states “else”. The double pipe characters || indicates a logical “or” statement. On most models of keyboard, the pipe characters are found on the same key as the backslash key \, which is usually near the backspace key. A pair of these characters will always be a logical OR. If you wanted to say AND, you’d use two ampersands instead &&.

So here we’ll checking for an f or m, and a failure to match those values will jump down to the else statement. Inside, we print out the star of our message about the gender. Note that I used the Console.Write and NOT Console.WriteLine – this way we can print the actual answer on the same line. This isn’t necessary, it’s just an aesthetic choice. The only problem here is, a user might put in a capital M or F… and though it’s the same letter, the fact that it’s capital means that our code will not execute.

One way we could do this is to test for those two additional conditions. First, we could modify our initial test to say this:

if (myGender.Trim() == "f" || myGender.Trim() == "F" || myGender.Trim() == "m" || myGender.Trim() == "M")

This works, and if you do that, you’ll have part of the solution we need. Of course, we’ll also need to modify the blocks that finish the print, specifically the condition that tests for female. Our else will handle either option for male. But there is an easier way.

C sharp allow for operations that are “chainable”. In other words, we can have the results of one operation passed to another operation on the same data object. And with data types like strings, there are actually a number of additional methods that we can chain on. In this case, we can use a method called “Upper” or “Lower” to transform all the characters in the string to one case, and then we can compare against just that single case. So we could convert our logic to this, which will be shorter, and yet perform the same exact operation.

if (myGender.Trim().Upper() == "F" || myGender.Trim().Upper() == "M")

We could then do the exact same thing for the further test for printing the female message. Again, we don’t need to do anything for the male message, because we’re not testing an individual condition.

Now, that we have that part done, we can expand our “alternative” answers. What if we wanted to differentiate between non-specified and other? Enter the next step of conditions… else if.

Else if let’s us chain a series of conditional tests, one sequence after another. In this case, we can modify our block to work like this (please note, I am skipping the internal content for the male and female option to focus on the else if portion).

//Check if myGender is set to an f or an m
if (myGender.Trim().ToUpper() == "F" || myGender.Trim().ToUpper() == "M")
{
    //Our logic to clarify M and F still goes in here.
    //I omitted it to keep this shorter.
}
//If gender is not f or m, but was specified
else if (myGender.Trim().ToUpper() != "F" && myGender.Trim().ToUpper() != "M")
{
    //Print alternative message
    Console.WriteLine("You specified a gender of other.");
}
//If gender is not f or m or other value
else
{
    //Print unspecified message message
    Console.WriteLine("You did not specify a gender.");
}

If you run a series of tests, you’ll see our logic split out more, and the answers are a bit more detailed when it comes to the other / no answer options. Likewise, a capital M or F will yield the correct response.

Another way we could write this code would be to split out the Male and Female options, like so:

//Check if myGender is set to an F
if (myGender.Trim().ToUpper() == "F")
{
    //Write female
    Console.Write("You specified a gender of: female");
}
//Check if myGender is set to an M
else if (myGender.Trim().ToUpper() != "M")
{
    //Write female
    Console.Write("You specified a gender of: male");
}
//If gender is not f or m, but was specified
else if (myGender.Trim().ToUpper() != "F" && myGender.Trim().ToUpper() != "M")
{
    //Print alternative message
    Console.WriteLine("You specified a gender of other.");
}
//If gender is not f or m or other value
else
{
    //Print unspecified message message
    Console.WriteLine("You did not specify a gender.");
}

We could also switch the “non-specified message” and the “other” message and simplify the cases as well.

//Check if myGender is set to an F
if (myGender.Trim().ToUpper() == "F")
{
    //Write female
    Console.Write("You specified a gender of: female");
}
//Check if myGender is set to an M
else if (myGender.Trim().ToUpper() != "M")
{
    //Write female
    Console.Write("You specified a gender of: male");
}
//If gender is not specified
else if (myGender.Trim() == string.Empty)
{
    //Print unspecified message
    Console.WriteLine("You did not specify a gender.");
}
//If gender is populated, but not recognized
else
{
    //Print alternative message
    Console.WriteLine("You specified a gender of other.");
}

There is even an option so we don’t need to use the double equal == sign for comparison. There is a chainable method on string objects called “equals” which take in the parameter of a string, or can take the string.Empty property.

//Check if myGender is set to an F
if (myGender.Trim().ToUpper().Equals("F"))
{
    //Write female
    Console.Write("You specified a gender of: female");
}
//Check if myGender is set to an M
else if (myGender.Trim().ToUpper().Equals("M"))
{
    //Write female
    Console.Write("You specified a gender of: male");
}
//If gender is not specified
else if (myGender.Trim().Equals(string.Empty))
{
    //Print unspecified message
    Console.WriteLine("You did not specify a gender.");
}
//If gender is populated, but not recognized
else
{
    //Print alternative message
    Console.WriteLine("You specified a gender of other.");
}

Why are there so many alternative ways to do this?

At this point, you’re probably wondering why all these alternative methods exist for accomplishing essentially the same thing? The answer is that more elaborate conditions to test for are more optimally achieved through the use of alternate tests. Much like you can often describe the route to get between two different places using a number of different streets and routes, you can use different combinations of logic to achieve a desired outcome.

Which is the right way to do it? The answer may annoy you at first, but it’s the one that works. What I mean is, the approach you take needs to be the one that accomplishes what you want, but your best bet is to lay out the conditions on paper, and try to keep the rules as simple as you can. When you do that, you’ll fine that the conditional logic will be easier to handle.

Frankly, that last sample of logic is probably the simplest looking of all the ways I’ve shown you. It kept each condition to its own block, and minimized the number of cases to test for. This might not be the best way to do it in all cases, but given that it’s simple to walk through, this approach works just fine here.

Go ahead and add back in the responses to the name, however you’d like to. You can just uncomment the code we had before, though if you’d like to specify more details, or to play around with the logic some more, go ahead! This will help you to get a better handle on playing with logical conditions.

Our final version of this file will look like this:

using System;

namespace HelloAdvancedWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.Write("What is your name? ");
            //Get variable for name
            string myName = Console.ReadLine();

            Console.Write("What is your gender? ");
            //Get variable for gender
            string myGender = Console.ReadLine();

            //Check if myGender is set to an F
            if (myGender.Trim().ToUpper().Equals("F"))
            {
                //Write female
                Console.Write("You specified a gender of: female");
            }
            //Check if myGender is set to an M
            else if (myGender.Trim().ToUpper().Equals("M"))
            {
                //Write female
                Console.Write("You specified a gender of: male");
            }
            //If gender is not specified
            else if (myGender.Trim().Equals(string.Empty))
            {
                //Print unspecified message
                Console.WriteLine("You did not specify a gender.");
            }
            //If gender is populated, but not recognized
            else
            {
                //Print alternative message
                Console.WriteLine("You specified a gender of other.");
            }

            //If no name was specified
            if (myName.Trim() == string.Empty)
            {
                //Tell us that we didn't remember the name
                Console.WriteLine("Hello.  You didn't tell me your name!");
            }
            //Otherwise
            else
            {
                //Say hello to the name.
                Console.WriteLine("Hello, " + myName + "!");
            }
            Console.ReadKey();
        }
    }
}

It’s a lot of code, and it doesn’t go too much; but we’re actually accomplishing a few things here that make for a good demonstration. At this stage, we have a good starting point for our logical demonstration. We understand a bit about multiple conditions, we’ve looked at how we can simplify that process, and we’ve learned about how we can have multiple cases with a fair amount of ease (using the if…else if…else approach).

Conclusion

So far we’ve expanded our functionality from a very simple hello application that just prints a message into one that processes some input and churns out responses based on what we typed in. Our next step will be to learn about another step of programming; namely loops and repetition. That will be another long lesson, but it’s another major step towards being able to produce more expansive projects.

Common Concepts of Programming Part 3 – Structure

Introduction

In this article, we’ll examine the anatomy of a C Sharp program in a bit of detail, and relate in some of the concepts we’ve discussed prior to this.

A Basic Application

If you recall the prior application we wrote, our “Hello, world” application, we had a bunch of lines of code that were used to make something relatively simple happen. We will use this simply application to understand what elements are essential for an application. The answer is, not much.

Open up Visual Studio and when you are prompted to open an existing project or start a new one, click on the solution for the prior application we created (the one called HelloWorld). You should see our code from last time open again.

using System;
using System.Collection.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HelloWorld
{
	class Program
	{
		static void Main(string args[])
		{
			Console.WriteLine("Hello, world!");
			Console.ReadKey();
		}
	}
}

This example, which I covered in the article where we set up Visual Studio, is a simple application which opens up a console (command line) window, prints “Hello, world!” and then waits for you to press any key on your keyboard. When you do, the program ends. Simple, right? It’s not fancy, but it demonstrates that applications need to be complex.

In the case of this application, we’re not really intending for anything critical to happen. So let’s look at the actual breakdown of what’s happening, and why.

The first 5 lines of the application all start with “using”. and have some text after it. The first line in Visual Studio will be bright, whereas the other 4 will be more of a gray color. These lines are declarations of libraries that will be used in this particular file of the application. Or rather, these are the 5 default libraries that Visual Studio THINKS we’re likely to need for our application. The 1st line is the only actual one that is used. That’s why it’s shown with lighter text.

Initially when we created the application, the file did not include the lines that start with “Console”. At that stage, all of the “using” statements were dimmed to indicate that none of them was in use. If we remove the 2 – 5 lines and press the play button at the top of our Visual Studio window, the application will run exactly the same as it did the last time, without any errors. So does that mean we didn’t need those lines? Yes… in this case. If you stop the program, try removing the “using System;” line and try running the application again. You’ll get a message that says that the build failed, and will ask if you’d like to run the last successful build. You can answer no and let’s look at the code again.

You should now see a red, rippled underline on both of the Console lines. That red underline indicates that there is an issue with the code. If you hover over it, you’ll see a warning that “The name ‘Console’ does not exist in the current context”.

If you click on the link that says “Show potential fixes”, you’ll get a further menu.

This gives you options for how you can fix your code. The first option is “using System;” and clicking it will re-add the line to the top of the file for the System library.

Now, if you hit the play button again, the application will build and run.

Libraries

You really don’t want to have to create all of the necessary underlying code necessary to print text on a screen. It’s actually a lot of work to build a fundamental base set of functionality like that; it’s a lot of effort, and frankly, there are already sets of code that do the work for you. That’s what a library is. It’s a collection of logic and instructions for how to perform one or more operations, conveniently packaged up for your use.

In simpler terms; all the stuff you need to regularly do are available to use without you needing to manually create it for each project. The System library contains many of the basic functions that are used throughout your application, especially in terms of handling input from a user and displaying output back to them.

Other libraries exist which handle functions of a different nature. When we need those functions, we can add them simply by adding the appropriate library with a using declaration.

The significance of the semi-colon

You may have notices, looking at the code in the demonstration program, that numerous lines ended with a semi-colon. The semi-color character ( ; ) is used as an end-of-instruction indicator. This is actually a common trait in many languages that follow the syntax of the programming language of C – C Sharp is one such language.

The semi-colon is not used on every line. You’ll notice that it’s not at the end of the line that states “namespace HelloWorld” or “static void Main(String args[])”. They are found at the end of all of the using lines, and at the end of the Console lines. These are the lines that actually indicate a step to be taken. Other lines like the namespace or static void main are indicators of a point within a program, or a collection of instructions, but do not actually act as direct instructions themselves.

You’ll come to understand that in time, when you are explicitly indicating a function the computer is to perform at that step, THAT is when you shall need a semi-colon.

Curly Braces

Much like the semi-colon, the curly braces { and } are a special character used for structuring an application. The curly braces are, in fact, a matched set. They indicate a block of code. If you look carefully, you will notice that after we have the namespace HelloWorld text, the next line down is a left-hand or opening curly brace. At the very end of the program is a right-hand or closing curly brace. This is one of the simplest points about organizing your code. These curly braces indicate that everything contained within them is a part of whatever it is that precedes the opening brace.

In other words, the void static main and everything else within the first set of curly braces are a part of the namespace. Additionally, everything within the curly brace set that follows void static main is a part of void static main.

This is known as nesting or blocking – we are indicating that the contents are nested as part of a structure, and that block is nested in a larger structure. The finer details of this we will cover over time, but for now, the most important thing to note is that whatever you open, you must close, and in the appropriate order. The appropriate order is something we’ll cover over time.

One More Pass

So we’re going to look at HelloWorld one more time, and dissect this code with a bit better an understanding of what some of this is. So going back to our full code:

using System;
using System.Collection.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HelloWorld
{
	class Program
	{
		static void Main(string args[])
		{
			Console.WriteLine("Hello, world!");
			Console.ReadKey();
		}
	}
}

Line 1 – indicate that we need the System library

Line 2 – indicate that we need the System.Collection.Generic library

Line 3 – indicate that we need the System.Linq library

Line 4 – indicate that we need the System.Text library

Line 5 – indicate that we need the System.Threading.Tasks library

Reminder: we included the libraries on lines 2 through 5, but we didn’t ACTUALLY make use of them, so they will show in a dimmer coloring in Visual Studio to indicate that they are not in use. We will discuss at a later time when it’s appropriate to remove those statements.

Line 6 – a blank line. This is not a requirements, but it makes it far easier to organize your code if you segment it some. And extra line returns don’t end up meaning anything in this language, so having some extra space might just make it easier to read.

Line 7 – Indicates that all of the code within the next paid of opening and closing curly braces is part of the namespace of this application. We’ll talk about namespaces more at a later time, and once we do in the proper context, you’ll see a tremendous value in them as an organization and containing element.

Line 8 – the opening curly brace for the HelloWorld Namespace.

Line 9 – indicates that this is a class; a sort of advanced data structure object which we will cover in the near future. The class is of type “Program”. Again, this will be important in the near future. For now, just be aware that the line of code is there.

Line 10 – the curly braces indicating all the following content is part of our “Program” class.

Line 11 – a static method named ‘Main’ that returns nothing (void). Inside of the parenthesis are the words string args followed by a pair of square brackets [ and ]. This is an indicator that our ‘Main’ function (actually method) takes in a parameter that is a string – if you recall from the last article, a string is a group of characters. The [ and ] indicate that the value being passed in is something called an array. We’ll talk about arrays more soon as well. As this is a void function, when it is completed, no data comes back from it. There are other options as well when it comes to this.

Line 12 – a curly brace indicating that the following content is part of the “Main” method;

Line 13 – a call to the Console object that is part of our System library, telling it to write a line of Text to the output window. The output is the literal text “Hello, world!”. This method also automatically causes a carriage return (new line) at the end printing the output. There is another version of this method called “Write” which works very similar, but does NOT include a new line at the end. If you were to have another Console.Write command following it, the text would begin immediately after the end of the first block of text, with no space, and no new lines.

Line 14 – this line is a call to the Console object to wait for the first key to be pressed on the keyboard. Once a key is pressed, the program will continue on to the next instructions. This is a simple way to have a “press any key to continue” hold in your program. And you can make it fun for yourself by waiting to see if a friend searches for the “any” key.

Line 15 – end of the structure that belongs to line 11; closing to the open brace on line 12.

Line 16 – end of the structure that belongs to line 9; closing to the open brace on line 10.

Line 17 – end of the structure that belongs to line 7; closing to the open brace on line 8.

Conclusion

Believe it or not, we actually now have enough fundamentals down to start working on a program in more detail. The next lesson of the introduction will be to modify the HelloWorld program to take a bit of user input and then to return output as a result. After that, you’ll be ready to start working on more intricate and advanced topic. Check back soon for part 4 of the introductory articles.

Common Concepts of Programming Part 2 – Data Types

Introduction

In the prior article, I introduced you to some common concepts and terms in programming. In this article, I’m going to expand on that a bit further. You’ll learn about data types and their affect on functions and methods.

What is a Data Type?

Simply put, a data type is an indicator of what sort of values are used in a particular situation. The simplest way to examine this is to consider variables. In the last article, we learned that a variable is a placeholder for some piece (or pieces) of data. It can be any sort of value we wish to store. But we must understand that there are different types of values. This shouldn’t be entirely surprising. Your first name and last name may be similar types of values, but your birthday is NOT.

What I mean is that if you wanted to store your name into some piece of memory on the computer, your first name and last name would consist of similar types of data; characters. You can’t add your name, or subtract your name. You can really only check if your name matches a certain value, or see if your name contains certain characters. However, there are mathematical functions that can be used with your birthday. We can see how many years have passed since you were born, how many days it is before your next birthday, and more.

Data types give us a way to store and process these pieces of data be forcing them to maintain a standard and structure. In that way, we can know what operations we can perform with that data, and just as important, we can know which operations we CAN’T.

Basic Data Types

There are a few common categories of values, and those common categories can then be broken down further into the specific data types that programming languages can handle. It’s important to note that although the general concept of data types apply through programming, some languages will differentiate data types further than others. We’ll talk about that more in a bit, but let’s start with the general categories.

Numeric
Fairly straight forward in concept, numeric data types are exactly what they sound like: those that hold numbers. Whether it’s a whole number (1, 2, 3) or decimal values (0.1, 0.2, 0.3), numeric fields are obviously important because they serve as the foundation of performing computations – and that’s a primary purpose of computer programs.
Character
Character data refers to everything from alphabetic characters (a – z) to punctuation (?,!) to numbers… wait, numbers, too? Yes. Technically, a number can be part of a character data set. In this capacity, you don’t generally use them for mathematical calculations. Your phone number doesn’t play much of a part in a mathematical formula; it doesn’t have to do with alphabetic order, it doesn’t translate into the position of your house… adding 1 to a phone number doesn’t give you any indication of who that number is or where that person can be found; not directly, anyway. So a number as a character is more about recording a value, not about performing a calculation.
Date and Time
Date and time are generally treated as another explicit category of data type, separate from numeric or character data. This is because there are aspects of both numeric and character data combined in these forms of data. You can use dates for calculation, but they can also be about recording a discrete value and not about specific mathematical functions.
Boolean /ˈbo͞olēən/
Boolean values are both a utterly mundane yet very important form of data. They’re utterly mundane in that a boolean value contains one of two values, and that’s it. Their importance is that the two values are TRUE and FALSE. This might not seem like such a big deal, but realistically, they are the basis of every single logical step of a program. Comparing data and determining if it meets certain criteria ultimately always results in a form of a TRUE / FALSE value, and as a result, a boolean value is essentially the indicator of what way to proceed.

Interestingly, you can also look at booleans as a representation of ON and OFF, 1 and 0, YES and NO, and any other bipolar choices. In fact, the entire idea of how computers work is a form of a boolean. Power flowing through a circuit means it is on… this also means that the presence of power is 1, indicates a value that is true, and a value that is YES. If there is no power flowing, it is FALSE, OFF, 0 and NO.

Even more interesting, next time you are in your kitchen or bathroom, take a look at some of your appliances (small ones like blenders, hair dryers, etc). You may notice that the power switch has a 0 and 1 on it, to indicate Off and On. In some cases, the power switch will have a symbol that looks like a 0 with a 1 running through it; those tend to be found on switches that are push button, where as flip buttons tend to have the separate symbols.

Now you have some idea of what they do that. Your appliance is on or off. This will make for a great example later on with our programming.

Specific Data Types

Now that we have a starting idea of how data is defined, we can talk about the specific data types that exist. We’ll start by talking about the data types associated with numbers.

Numeric Data Types

The numeric data types, as described above, cover the range of data used in mathematical calculations. That means everything from simply addition and subtraction all the way to complex formulas like those used in calculus. Don’t worry, we’re not going to make you do all sorts of crazy math problems here. In fact, the whole point of using the computer is to reduce that load to a manageable format.

Integer (Int or Int32)
Integers are whole numbers. That is straight forward enough. The limit to use of integers is that they can only be up to a certain size. That size is a total of 4,294,967,296 values. What that means is that you are limited to what the largest (and smallest) numbers are that you can hold. Integers, as with all numeric fields in programming, are either signed (meaning they have a positive or negative) or unsigned (meaning only positive numbers are possible). If you’re using an unsigned integer, that means you have a range from 0 to 4,294,967,295. If you’re using an unsigned integer, you can hold from -2,147,483,648 to 2,147,483,647.

An integer is created as an INT, and an unsigned integer is created as a UINT
Long (Long or Int64)
A long is a second form of a whole number. The difference is that a long is actually able to handle a much larger range of numbers. The range of numbers allows for up to 18,446,744,073,709,551,616 values. So unsigned long values can go from 0 to 18,446,744,073,709,551,615 ; signed long values can go from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807. Variables of these types are created as LONG and ULONG.
Short (Short or Int16)
A short is a whole number with a range of 65,536 values. They are divided up similarly to the INT and LONG formats, and can be declared as SHORT and USHORT.
Byte (Byte and SByte)
Not quite as commonly used in every day calculations, the byte is a holdover, to some extent, from the early days of having to manually program hardware. A byte is a block of 8 binary bits. That means a range of values from 0 (represented as 00000000 in binary) to 255 (11111111 in binary). Binary is a separate lesson to work through, so for now it’s enough just to be aware that bytes are a data type that exist. One difference between these and the other forms above is that a byte is unsigned by default, and to get a signed version, you need to indicate sbyte; this is as opposed to all the other types that are signed in their default form with an explicit override for unsigned.
Decimal
Of course, we don’t only deal with whole numbers when it comes to mathematics in programming. Otherwise we’d never do anything with monetary values because, honestly, that would be a mess to keep organized. The decimal is a standard format for numbers that have, well, decimals. A decimal number has a range of -79228162514264337593543950335 to 79228162514264337593543950335. But wait, where’s the decimal in that?

Well, the decimal concept gets a bit trickier, because let’s remember that now instead of a fixed increment going up or down (whole numbers are fixed increments going up 1 whole unit or down 1 whole unit) we now have to consider all of the decimal places that appear before OR after a number, so they sizing can be a bit crazy. The fact is that you typically see an ability with a decimal number to go out to 28 or 29 places (before or after a decimal point, or combined before AND after). That means that a value like 0.0000000000000000000000000001 (28 places after the decimal) will actually print as it is. If you have one more decimal place before that 1, the one will disappear off the number. Likewise, if you add numbers BEFORE the decimal, the number of spaces AFTER the decimal will also be truncated (cut off).

0.0000000000000000000000543210
2.0000000000000000000000543210
22.000000000000000000000054321
220.00000000000000000000005432
2200.0000000000000000000000543
22000.000000000000000000000054
220000.00000000000000000000005

Line 1 and Line 2 have the same number of places, so even changing the ones place from 0 to 2 doesn’t do anything. However, adding a second place in front of the decimal means that a place at the end of the number is truncated. Keep in mind that truncation is NOT rounding. It is literally the place where the number just drops off.

While it is possible to have longer numbers using scientific notations, for the purposes of programs we’d write, this is more than sufficient, so we will not worry about those specialty cases. If you’re writing a recipe program, a check book program, and even a video game, the chances of getting to numbers more precise than this is limited at best.

Frankly, if you have a recipe calling for a measurement more precise than 0.0000000000000000000000000001 teaspoons of an ingredient, I don’t think I’m going to be following your recipes.
Single and Double
As is the case with the whole numbers, there are a few variations of these decimal numbers as well. The SINGLE and DOUBLE value are versions of a decimal that store numbers with lower limits to the number of places. A single (sometimes called a float) can hold 6 to 9 places, and a double holds 15 to 17).

So the question is probably brewing in your head: why all these versions of numbers? The answer is that in earlier days of programming, computer memory and processing power was far more limited than what it is today.

The processing power of machines at the advent of computing would seem almost laughable now. In fact, the average hand-held calculator holds as much processing power as some of the earliest computers. If you have a smart phone, you probably are holding more processing power in your hand than what the government had available in some of it’s best machines in the early 1950s.

Concerns of storage and memory space and processing power made it critical that values were only made large enough to hold what was really necessary. And it still makes sense to do that today. Why get a 3 ring binder capable of holding 1000 sheets of information if the only thing you intend to store is a piece of paper with your first, middle and last name?

While we don’t need to be quite so strict today in limiting use of memory as was needed 50 or more years ago, it still does slow down and use up the resources of a computer each time you declare a variable. While it might not be significant in one case, thousands of variables could begin to tax a computer over time.

So these different size data types still exist so we can program for what we will need, reasonably, in the future. And if we find that we do need to expand a variable’s size at some later point, it’s not a horrible ordeal in most cases to do that.

For most of the examples we’ll look at for the foreseeable future, we’ll use Int and Decimal values. If there is a special case where we need to use something else, we can review the reasons why at that time.

Character Data Types

As was the case with the numeric data types, there are a few different character data types to consider as well. For our purposes, we’re just going to look at two types for now.

Char
You might hear people pronounce this like the word describing the burned / black portion of barbecued meats. While people will probably overlook that, the truth is that the word is actually pronounced like “care”. It’s actually short for Character, and it is exactly what it sounds like – a single character value. The uses of single character fields might seem minimal, but in actuality, you can use them for quite a few purposes. For now, though, we’ll look at the more common data type.
String
The string is actually a more commonly used character-based data type in many languages. It is a block of character data, and can be used to hold up to 2 billion characters. Yes, you read that right, 2 billion character is the maximum theoretical limit. I saw theoretical, because it’s highly unlikely you’ll actually allocate that much, and frankly, it’d be bad to do so. 2 billion characters is a LOT of data, and having to load and process that much in a single value would be taxing to nearly any computer system. Even if you’re writing a novel that’s about 350 pages, you’re not going to get to those sorts of numbers. A typical page on a standard hard-cover book is about 300 to 350 words. At an average of 5 characters per word, plus one for a space, that translates into 1500 to at most 2100 characters. Even if you double that and say 2400 characters on a page, that still means 735,000 characters in total for a book. That doesn’t even come close to 1% of our memory max limit for a string.

So a string is a pretty versatile form of data in it’s capacity. Strings can be used for storage, can be searched, and compared against other strings. That allows us to do the vast majority of what we need to write most programs. We will use this data type a LOT.

Data Types and Functions or Methods

We’re just going to introduce this concept briefly for now, because there is a lot more we can and will learn about when it comes to data types. But it’s important to understand that data types have importance beyond use for variables. They also have significance in use with Functions or Methods.

When it comes to producing code, we tend to rely on functions and methods, as described in the prior article, to preform multiple tasks or steps that need to be repeatable. In other words, a task to calculate someone’s age based on a birthday is something we don’t want to have to write the code for manually EVERY time we need to use it; for one thing, programs that are meant to handle multiple people, a growing list of them, would never be manageable this way. For another, doing anything like that would defeat the purpose of using a computer at all – automation of process is a big factor in why computers are so valuable.

If we’re going to use functions or methods, it is likely that we’ll need to get feedback or results from those functions and methods at least some of the time. Data types are a part of that process, because they indicate what type of data will come back from a particular function or method. For example, a method that performs a calculation of the age of a person based on their date of birth could just spit out a number to a screen. But what we need that number for some other process later on?

The function could be set up to return the value to us, and we could decide what to do with it later. Initially, many methods are set up with a return type of VOID. Void means there is no return type. We perform some process and then move on. But if we had our age calculating function, we would set it up to take in a date, and return an integer indicating how old the person is; perhaps in years, perhaps in day; maybe it would go deeper depending on the time of birth.

But the fact is, we can set up our functions or methods to indicate what type of data will come back from a set of tasks. When we write code like this, we declare the return type of the method or function to use one of the aforementioned data types. How we do that is something we’ll cover soon. But for now, it’s enough to know that these pieces fit together. The how we’ll cover in time.

Conclusion

This is a good place for us to stop; there is a lot to absorb before we get into writing actual programs, so it’s important that we have groundwork laid out before we just start typing stuff up on our screens. The next article will discuss the actual anatomy of a program in more depth, and we’ll look at the structure of blocks of code and talk about how the terms of part 1 and the data types in part 2 fit into that picture. Once we’ve done that, we can begin to make some serious effort at writing a simple program, and know what we are doing, and why.

Wait! Do you know what you asked for?

I was going to write an article about the Coronavirus and how it is affecting the world, but I realized that 1) people are panicking enough about it that I can write about something else that can make people nervous and 2) people are apparently at risk of catching the Coronavirus just for discussing the Coronavirus. In fact, there was a doctor in China who died from the Coronavirus after talking about the Coronavirus; I’m not making this up, by the way. But you can look it up. I don’t want to talk about the Coronavirus any more and risk catching the Coronavirus.

Instead, I’ll write about something else. Like the fact that my son is now traveling with his classmates to Canada. They’re going on a very fancy bus, enjoying more comfortable accommodations than I do trying to fit in an airline seat (excuse me, I asked for the SMALL sardine can, thank you). They’re on a class field trip for 8th graders to Quebec, Ontario where the official motto is: Va-t’en, idiot américain / Go away, you American jerk. Remember, in Canada, everything needs to be written in French AND English, to increase the chances that people standing next to each other will be given conflicting information.

While there, the students have the opportunity to see how people from another country, who speak a different language, and a moderately different culture, hate the average American.

I can’t say I entirely blame people from other countries for hating us; after all, we tend to hate them, they tend to hate each other. Realistically, international relations could best be summed up as 195 sovereign nations staring at each other crossly while secretly giving each other the finger.

All that aside, my son is getting to travel to a place that actually has COLDER weather and potentially more snowfall than Buffalo, NY – and quite often, that’s saying a lot. Of course, it’ll be no surprise if after the trip he comes back feeling a bit run down; travel is taxing on the body; my wife and I could vouch for that fact after our honeymoon. That’s a story for some other time; like after getting proper therapy and medical treatment.

For the kids (probably not the chaperones), it’s one of those enjoyable trips where they will get to learn about variations to culture, and the significance of language in shaping the lives of people from a region. Or at least it can lead to miscommunication when you place an order at a restaurant by asking for what turns out to be “Tax Not Included in Price”. At least, that’s what would happen to me.

I was never really good at foreign languages. They always seemed so… different. Which I realize is the point to learning them. But there is a vast difference between being able to understand a few key words or phrases, being able to speak or write less than half of them, and being able to do something other than saying you don’t speak the language, ask where there’s a restaurant (or bar), ordering something, realizing you need to get to a bathroom FAST, and then asking where a hospital might be, because there was definitely blood.

My son and daughter seem to be much better at stuff like this than I am (I mean foreign languages; not bleeding from digestive trauma). I think that my wife is generally better than me at languages as well. Which is good; they all like to travel, and being that they enjoy traveling, the are likely that they’ll be fine. I, however, am not much for leaving my hometown (except, maybe sometimes if it involves trains). Statically, I will be the one in a position to require new kidneys, and perhaps to cause the declaration of a travel ban against citizens of the United States of America. It’ll be entirely an accident, I won’t be trying to anger anyone. I’ll intend to say “I really like your family’s tacos”, but it will likely translate into “I wish to fondle your wife’s taco”. You might see a problem with that statement; if not, do not attempt to complement anyone on sausage, either.

So of course, I’ll need the thing about where to find a hospital, in the local language. When trying to communicate with people who speak different languages, you’re probably in a different country or at least a different region of your own country; or you’re in Hell, where everyone is yelling at each other incomprehensibly until the end of time; or you’re in line at the DMV – which is like Hell, but without the ambiance, and lasts much longer. Chances are, too, that there is also a local water supply that your body is not acquainted with, and you will NEED to have some help with issues of a medical nature.

At any rate, my son is traveling abroad, and in 4 days he will come back and share his experiences with the family. He’ll have explored a new place; he’ll have photos of wondrous sites; he’ll have some gifts, perhaps, for family; he might have a case of pneumonia or hypothermia, because, remember, it’s Quebec. And we’ll all laugh. And then he’ll cough a bit and we’ll all freeze because we’re back to thinking about the c**********… if you know what I mean.

Common Concepts of Programming Part 1 – Terminology

Introduction

I’ll be forthcoming on this; programming draws a lot from mathematics. And while that may sound scary for some people, the truth is that most of it is no more complicated than the simple math that makes up daily life. For the average program, the math gets to nothing more than Algebra. If you were always one to struggle with math, don’t panic, and don’t let yourself get turned off by the idea of having math being a part of this process. I struggled at a lot of points in dealing with math education, and I can vouch for the fact that most applications won’t get that complicated on you.

At worst, if you have to deal with advanced math concepts, it’s only in developing something like a game. And even there, the computer is set up to help you a lot. You aren’t doing math so much as learning to plug in an equation. The computer will actually solve the problem, you just tell it which problem you want solved.

At any rate, programming comes down to some logic, and solving simple equations. Before we get to doing that, though, we need to understand some core concepts about programming languages.

This article will contain a list of common terminology.

Common Terminology

Most software is fairly complex when you look at it as a whole. But the simple fact is that programming is essentially a forest; and that means that a program consists of individual trees. Yes, trees have some complexity to them, but individually, they’re not so hard to understand. That vast majority of challenge comes from learning how these trees combine to become that forest.

There are a number of concepts that are common to nearly all programming languages. I say nearly all, because there are a few languages that may not have these as readily identifiable concepts. But the truth is, if you’re discussing a language that doesn’t include these concepts, that means you’re dealing with a highly unusual or very specialized language, and not one you’re likely to encounter outside of highly theoretical or advanced development work. I work as a software engineer, and I have for 20 years. I have never used those unusual languages in a professional context. However, what I am covering here is stuff I use on a daily basis.

Variable
A variable is essentially a placeholder for some piece of data. As an example, the name of a person can be a variable. So could a value such as X in a simple math equation such as 4 + X. If X is 1, the equation would be equal to 5; if we change X to a value of 3, the result is now 7.
Function
A function is a series of instructions that are used regularly for calculation or action; rather than having to write individual instructions repeatedly, we can build a function that can perform the process we need over and over again.

For example: if we needed a way to calculate your age based on your birthday and the current day, we could do the math for it in a single block of code. But what if we wanted to do that for multiple people with different birthdays, the amount of code we have to write would scale up very quickly, and make our program inefficient, bloated and messy.

A function could be put to take your birthday in as a variable, and return the resulting age.
Object
Objects are part of a concept called object-oriented programming. Building on the idea of reusable code, an object is a sort of structure that can be used to define complex re-usable idea. For example, you can create a person object, which would have space for a first name, last name, date of birth, address and phone number. Then, for each person, you’d create a new copy of this object, and populate it with its own data. The proper name for these copies is instances.
Property
Variables that are a part of an object are generally referred to as properties. They essentially are the same as a variable, but because they form a specific part of a type of object, we call them by this name to indicate that they are “owned by” that object.
Method
If a property is a variable in an object, a method would be a function in one. A great example would be to build that age method into the person object. Then when you needed a particular person’s age, you don’t need to get the date from the object and send it into a separate function to get back the age. You can call the method on the person and get their date back directly. In other cases, instructions for an object that is very specific to a person could be a part of the object. For example, you can have a stand-up function. When it’s called on a particular person, that one stands up.
Condition
Conditions are logical rules to help control the flow of information. Programs that can’t respond based on conditions are really not useful, because they would run in a linear way and not allow for different operations based on what a person can do.

For example, if a person’s age is under 5, a person goes to daycare. if they are over 5 and under 18, they go to school. Over 18, and they could go to college, trade school, get a job, and more.

If statements (sometimes referred to as if-else or if-else if-else) are a common control approach to provide choice control and reaction.
Loop
Loops are a control structure that allows for repetition of a task based on a set of conditions. For example, if you needed a person to take steps until they get to a door, you would need one of two things; either you need to know the number of steps to the door and have to program the take-a-step method to happen that number of times or; you could use a loop that checks to see “is the person at the door” and if they aren’t, they take another step. That loop would continue until the condition of that person being at the door is met.
Logical Operations
Commonly used as parts of conditions and loops are logical operations. These can be a bit tricky, but commonly, there are 3 that we start being concerned with: AND OR and XOR (also called exclusive or).

AND is pretty simple. You must meet all conditions for the AND statement to be met. For example: if the person is at the door and the door is closed, open the door. If the person is not at a door, the condition fails at that point and is skipped. If the person is at the door but it is already opened, the step of opening the door is still skipped. Only if the person is at the door AND it is closed can you open the door.

OR (also known as an inclusive or) and XOR are slightly more complicated, but only because the reality is that in a language like English, we tend to assume that we mean OR when we mean XOR. OR means that 1 or more conditions are met. XOR means that only one of the conditions is met.

The best way to understand this is with a “restaurant” example. If you go to a restaurant and order an entree (please get one for me, too), you will probably be asked if you would like soup OR salad. Now what English tells us is that we can have the soup, or we can have the salad, but we can’t have both. In programming, OR means you can. The translation of this would be “You can have the soup” or “you can have the salad”. If the first case is true, then you don’t even worry about the second one..

With an exclusive or, if you have the soup, it is exclusive, so you cannot have the salad. If you have don’t have the soup, then you can have the salad. If you have both or if you have neither, the condition on that fails.

Most programming languages have a direct implementation of AND and OR (in logic, they are displayed as && and ||, respectively). However, not a lot of languages have a direct XOR operation. However, you can emulate that process by saying “if soup is true and salad is false, do something; if soup is false and salad is true, do something else. And if the person tries to say soup AND salad, or neither soup, nor salad, nothing at all is triggered.

Of course, I don’t recommend that if the waiter says “would you like the soup or a salad” that you answer with “sure”! They might not find it funny.
Comment
A comment isn’t actually a part of code, in the sense that it doesn’t “do” anything. A comment is exactly what it sounds like; it’s a statement of a generic sort – when you build a project, you can use comments to note what you did and why. The compiler just ignores them, and go right on past them. But if you used a comment properly, then in several months when you go back to look at your code, you can leave a note for yourself on why you did something, when you made or changed something, where things come from and more.

Comments are the most useful ignored feature in programming, precisely because they let you track what’s going on, exactly where it’s going on, without actually doing anything to influence the outcome of the program itself.

Conclusion

This isn’t our only terminology; not by a long shot. But this is enough for the moment. In the next part of this set of articles, we’ll talk about the various types of variables, and their relationship to the concept of functions and methods.

Getting Started with Visual Studio Community 2019

A few quick notes before I dive into the meat of the article.

  1. I will not automatically show you the best technique for advanced programming; not because I want to make you inferior, but because I want to slowly introduce you to more and more advanced concepts over time. So there may be some things I show you now that I’ll later tell you not to do normally. Don’t panic or get upset; those lessons are meant to help you understand important concepts, and it’s just as important to learn what NOT to do as it is to learn what you CAN do.
  2. Most of the stuff I’ll show you will be using Visual Studio 2019 Professional. For the most part, you’ll see the same tools as I would, but if something is missing or seems odd, don’t worry! I won’t use anything that isn’t available for the Community Edition – and if somehow I manage to do that, just send me a message and let me know; I’ll get you the info you need to proceed.
  3. Don’t panic about the complexity of what you’ll see. Remember that a key to something complex is to focus on the small pieces. If you don’t panic and worry about the big picture, you’ll have the Sistine Chapel before you realize it.

Launching Visual Studio

Assuming you’re using Windows 7 or 10, go to your Start menu and look for “Visual Studio 2019”. You’ll get asked if you’d like to sign up for a Microsoft account.

You can skip past (click Not now, maybe later). Then you’ll get presented with this screen:

This will let you select the configuration options for using the software in an optimal way. for the “Development Settings:” drop-down menu, choose Visual C#. You can choose the color scheme you think you’ll like. You can always change it later if you like. At some point I will do an article on playing with the preferences for the IDE; and there are a LOT of options. For now, I’m going with Dark. It’s easier on my eyes, so that’s what I tend to stick with. The theme won’t affect what tools are available, so just pick whatever seems best to you for now.

Welcome to… another menu screen…

OK, this is actually a good thing. From here, you’ll be able to start building your first application. You won’t initially see anything on the left side of the screen under “Open recent”; that’s because you haven’t done anything yet. In the future, programs you’ve written will be available here for you to reopen.

For now, we’re going to Create a new project (the button on the lower right of the screen). Good grief! What is all this?

Again, relax. This is where we select the type of project we’re going to work with. This give you an idea though of what sort of capabilities you’ll have for development. You may not see as much as I have here, but you’ll still likely see a lot of options in that right-hand list. Let’s filter down to something more manageable. Under “All languages”, select C#. Under “All platforms” select Windows, and under “All project types”, select Console. At this point, you should see a MUCH smaller set of options. The ones you’ll most likely see are “Console App (.NET Core)”, “Console App (.NET Framework)” and “Workflow Console Application”. As long as you see the first two options, we’re in good shape. Select “Console App (.NET Framework)” and click “Next”.

This is the option to set up a project that will work specifically on Windows, and run in what you may recognize as a command-line interface (some people will call it a DOS interface, and while that’s fine, understand that DOS really refers to an operating system that is really no longer in use). Regardless of whether you call it command line or DOS, this will let us build a simple text based application.

Egads, another screen?! Yes!

Yes. But don’t worry, we’re almost through this initial set of steps. On this screen, we’ll have a few options for what we can do. First, let’s give our project a name. It default to ConsleApp1, but that’s not an entirely useful name. You’d like to have SOME idea of what the app is for. It’s not going to be much, in this case, but we should have something better than ConsoleApp1. Change this to say HelloWorld. Note, there shouldn’t be any spaces in this field if you can avoid it. You will probably notice that as you renamed the project, the Solution name field also changed to HelloWorld. Let’s explain this just a bit.

Projects? Solutions? Huh?

OK, this isn’t really all that bad, but it’s valuable to know. Most of the time when you want to build a larger sort of application, you won’t want to slap everything into a single big file. It makes it hard to sort through problems, it makes the program potentially WAY larger, and if you want to make some of your code re-usable, this isn’t going to make that task easier.

A Solution is a container for a series of related projects. Some projects will be actual applications. Some will be collections of functions you may choose to reuse later. Some projects might be for building a website. So you could, for example, say you have a project for an application, a project for a website, and a project that has some code used by both. Each part is it’s own project, but they are all part of the solution. Later, you might have an entirely new solution, but you’ll want to reuse the library project; can you can do that, by copying it from one place to another.

If you want an analogy: imagine you’re hungry. You want to make dinner, and a dessert. You have ingredients in your fridge. Well, some ingredients (like milk or eggs) are used in many different recipes. You probably don’t keep separate batches of eggs and milk in different fridges. You keep them together, and when you need an egg, you get it. When you need milk, you get it. What about salt or sugar? Well, you don’t need to keep them in the fridge, but you’ll have them in another cupboard. Again, not all recipes need sugar or salt, but if you do, you can get them out of the right place. You’ll have a recipe, which is the instructions of how to use those ingredients to make your recipes. And you don’t just mix all the ingredients for both recipes together (if you think strawberry jelly goes well with fish, maybe you would, but frankly, your nuts).

So you follow your recipes, produce each of the parts of your meal. And when you’re done, you can now enjoy the fruits of your labor. Congratulations; you solved the problem of being hungry.

The places we store ingredients, and cookware and whatnot; those are all library projects. The recipes might also be a form of library. The actual process of preparing the recipes are also projects, but instead of being libraries, they’re programs. They are the direct control over the process of making your meal. And the entirety of making the meal and dessert? Well, your problem was that you were hungry. The solution was to make the recipes.

So a solution is a container for projects. In the case of HelloWorld, we don’t need to separate them any more than this, because we’ll only have one simple project in here. They can have the same name and it won’t be an issue.

For the Location, you can leave it to default to wherever it is. More than likely you’d see something like “C:\Users\someuser\sources\repos”. For the time being, that’s just fine. Later on we can look at other ways and places to store things.

You may have noticed a checkbox that says Place solution and project in the same directory. Frankly, I don’t recommend that. If you leave it unchecked, you’ll have a folder for the solution, and then each project will have it’s own sub-folder. I find that easier to deal with, personally. Finally, you’ll see a drop-down box that is labelled for Framework. If you click on that, you’ll see a ton of entries like .NET Framework 2.0, .NET Framework 3.0, etc. It’s not likely you’ll ever need to go to a much older version than what’s current, but it is useful to have all of the options in there in case you later download a project from the web and want to try to update it to what’s current. As of this article, the current version is .NET Framework 4.7.2. If you did your install of Visual Studio right in the last article, you can just select this value if it’s not already set, and click “Create”.

You’ll now have a much more complex looking screen, with a big window in the center with a lot of text in it.

Before you can say “What is all this?” let me explain what all of this is.

The Visual Studio Interface

Remember, first, that Visual Studio is an IDE (integrated development environment) and that means that it’s a collection of tools related to the task of writing programs. So there’s a lot of stuff that will show up on your screen. I’ll cover the important ones to be aware of here; don’t panic if you see some additional stuff on my screen and you don’t have it on yours. I do a lot of development in here, so I’ve moved some stuff around for convenience. You’ll be able to see the most important stuff right away, and at another point, I’ll describe what you can do to switch things around. Don’t worry, it’s not likely that you’ll hurt anything by doing this.

Across the top is a typical menu bar. File, Edit, View, etc… all things we see in most of the programs on a computer. Below that is a toolbar with a set of icons. Initially you’ll see ones you recognize, like new, open, save and the undo and redo buttons. Next to that you’ll see a couple of drop-downs. Once will probably say “Debug”, the next will say “Any CPU”. Then you’ll have a Play button (a green arrow on my screenshot) and the word “Start”. And then there will be some more icons. The biggest one to be aware of is that Play / Start button. We’ll use this to actually run our first program. Over to the right of the screen, you’ll see a panel called “Solution Explorer”. You may also see a tab for “Team Explorer” and “Properties”. You can switch tabs if you’d like just to see what’s in them, but make sure you’re back on Solution Explorer when you’re done.

If that panel looks like the next image, you can click and drag the “Properties Tab” down; you’ll see a little set of icons appear, shaped like a plus. Drag over the lowest box, and it’ll separate so you can see it AND the Solutions / Team Explorer tabs separately.

On the left side of the screen, you’ll see a panel labelled “Toolbox”. That’s something we’ll cover later. At the bottom of the screen you’ll see “Output” with two tabs. One is called “Output” and the other is “Error List”. You might see some more tabs, too, but again, we’ll worry about that all later.

Finally, smack in the middle of the screen, you’ll see a window labelled “Program.cs” and have the results of a cat running across your keyboard… no, not really. You’ll see a bunch of text with some different colors and a series of numbers down the left side.

This is called the source code of your program. If you have a solution that has lots of libraries and files to it, you’ll see more tabs open across the top bar over time; but for now, we’ll just focus on what’s here.

The numbers on the left side of this window are actually line numbers. If you’re writing a program and something fails, this will help you to find where your mistake is.

Lines 1 – 5 on my example start with the word “using” followed by a few more words, and then a semi-colon. These are usually called “directives” or sometimes “includes”. Essentially, this is a collection of libraries of common code that your application may (or will) need. They’ll probably all look kind of dim-colored; that indicates that we aren’t actually using any of them just yet. This program will only really use one, but we can leave this as is.

Next, you’ll see the word “namespace” followed by “HelloWorld”. A namespace is a sort of container used for coding. We’ll get into more detail on that later as well.

Next, we see “class Program”. This the starting point of the actual application. We’ll discuss classes more soon, but something you’ll here in a lot of languages is the phrase “everything is a class” or “everything is an object”. What this really just means is that every part of a program written in these languages is essentially a sort of component that is used for operation. The initial class for C sharp is Program. That indicates that this is the program container.

Next, you’ll see “static void Main(string[] args)”. If you’re wondering what all this means, don’t worry, we’ll get to it when we’re ready. Lastly, you might notice a series of characters that look like this: { } Commonly they’re referred to as curly braces or brackets. Note how they’re placed. They indicate a sort of start and stop to a logical “container”. As we expand our skills, we’ll see their relevance quite quickly.

OK. What does this program do? Nothing! If you tried to run it now, it’d start and end… and chances are it would happen so fast you might not even see a window show up for it. If you do, it’ll be a sort of black box, and it’ll immediately disappear.

Let’s actually make something happen.

One Quite Note

Be aware that programming languages are typically case sensitive, especially when it comes to the names of functions, variables, and the like. Make sure you’re careful about names and spacing when you type things in, because quite often you can make a mistake by forgetting to make something uppercase. A key example will be the commands “Console.WriteLine” and “Console.ReadKey”, which we will use below. If you forget to capitalize the L in WriteLine, or the K in ReadKey, the program will NOT work.

One nice feature that helps with this is called IntelliSense. It’s a feature in Microsoft products (along with numerous others for programming) that will help you to select the right command and instructions. As you type, it will pop-up a list of possible values and try to guide you to the best choice. I’ll cover that in more depth at another point, but based on some feedback I received, I figured it was important to note that before we got too far into this.

Adding To The Code

In between the curly braces under the “static main” line, hit your enter or return key a few times. Go to the first line after the opening curly brace { and type in the following:

Console.WriteLine(“Hello, world!”);
Console.ReadKey();

Your program will look like this:

Go ahead and hit that “Start” button at the top of the screen.

Congratulations – you just wrote a program. It doesn’t do very much, but that’s not a problem. It actually did something. To exit, you can either hit the “Stop” button in Visual Studios, click the X on the windows to close it, or press any key on your keyboard and it’ll finish and close itself.

Down at the bottom of the screen, you’ll see in the “Output” window something like this:

This indicates that the program ran; when our programs get longer, we’ll see more information here that we can use to track through steps and do what’s called “debugging”. If you look at your code window, you’ll notice now that the first line “using System;” is now brighter than the other lines. That’s because we’re actually using code from that library. The Console.WriteLine and Console.ReadKey code is part of a general library called “System”.

We’ll dissect this program in more depth in a few articles. But for now, “Hello, world!”. Go ahead, and show it off! You made a computer program.

Preparing to Get Into Programming

If you’re entirely new to programming, this post will help you get set up to do your first project. We won’t do any coding just yet; for one thing, we have no way to turn the code we write into an actual program. To perform this process, we need a tool called a compiler. Compiling is a term that defines the process of transforming human-readable code from a language like C# (read as C Sharp) into machine usable code. If you’ve ever heard of the terms “binary code” or “machine code” or even “assembly language”, these are the low level instructions that the physical hardware of your computer understands. You could write programs in those languages, but frankly, it is a very slow process at best, and most of the time, there is no need to use a language so granular as that.

What is C#?

C# is a programming language that follows a general series of structural rules and approaches that make up what is known as the C family of languages. These languages include: C, Objective C, C Sharp and C++. The structure of the code written in these languages (referred to as their syntax) is relatively similar, but while some (C Sharp and Objective C) are relatively easy to use, others (C and C++) are far more elaborate. The complex languages are commonly used for building the operating software of your computer (Windows, Mac OS, etc), advanced video game development, and especially intensive mathematical or scientific programming.

There are a lot of other languages that also share the style and format common to the C languages, so once you’ve started using this format, it becomes much easier to start learning the other languages.

Why are there so many other languages if they all work in such a similar fashion? In addition to the uses I mentioned above, some of the languages are specific to working on certain platforms (Windows, MacOS, iOS, Android, etc) and some of them are meant for uses for specific types of development (desktop applications, websites, mobile device applications, and more). As a result, different languages evolved to specifically handle those various needs.

Think of it this way: why are there so many different types of road vehicles? Cars, pickup trucks, tractor trailers, tanker trucks, fire trucks… each of these vehicles serves a different purpose; they are used for personal transportation, moving heavy loads, or carrying the equipment to handle emergencies. I doubt very much that you’d want to try to plow snow in a place like Buffalo, NY or Denver, CO with a small sports car with a giant plow mounted on it. By the same token, you aren’t going to be taking a person who was in an serious accident to a hospital using your motorcycle.

Setting up an IDE

While it is possible to write the code for most languages in a simple tool like Notepad or another simple text editor, the fact is that you’d need another set of tools to actually perform the steps for compiling that code into an application; and the process can be lengthy, to the point that it can be a nightmare to manage.

It can be done that way, but it’s a painful process. Fortunately, there is a much easier alternative; the IDE – Integrated Development Environment. An IDE is a program that is generally graphical in nature that allows you to write your code, correct syntax errors (like spell check in a word processor), and test and fix logic (debugging). An IDE will almost always come with a compiler (or will help you to set up an external compiler program) that will then take your code and perform the necessary transformation into an actual program. In more advanced IDEs, they may have built-in tools to help you optimize your program, connect to other systems for more extensive development, and provide many more features to make advanced development much easier to handle. One of the best features of an IDE is that they usually perform things like syntax highlighting and color coding – they will actually display the language with colors to help denote what you’re seeing, which makes it easier to tell if you’ve made a mistake.

There are many IDEs on the market today. Some can be VERY expensive, and others are free. In some cases, like the one we’ll use, there is a free edition and more advanced professional versions you can upgrade to if you need the advanced functionality. Chances are, if you’re working through this material, you’re not a professional, so the free edition is all you need. In that case, you can use the tool I’m introducing here.

Microsoft Visual Studio Community Edition

Microsoft released Visual Studio was first introduced in 1997, and supported several languages. At the time, there were only professional or enterprise versions of the software. Since then, Microsoft has released many updates and new versions to the software. As of now (February 2020) the most recent stable build is Visual Studio 2019.

One of the great things about Visual Studio is that there are versions for all of the major computer platforms, so you can technically develop along the same vein if you’re an Apple user instead of a Windows person. There is a catch, however. You are limited to the types of projects you can do outside of Windows. Simply put, the graphical applications you use on a Mac require libraries and functionality that is different from Windows, so if you want to write applications for Apple machines, you’ll need to do a bit more.

Getting Up and Running

For now, I am going to run with the assumption that you’re a Windows user. Keep in mind, if you have a relatively modern Mac, there are options to set up Windows on the machine. One approach is to use a Virtual Machine. This is a program that lets you create a “virtual” computer that resides on your physical machine. In essence, you simulate having a computer with it’s own disk space, memory, programs, etc. That machine can be turned on and off at will and can be set up with any number of different operating systems and virtual hardware configurations. The best part about a virtual machine is if you royally screw up, you can delete the copy of the system and build a new copy. That approach to doing all this is beyond the scope of this article, but you can easily find a TON of information on the topic by going through you’re preferred search engine and looking for the term Windows virtual machine on MacOS, or Linux, or whatever you may be using.

But assuming that you are either on a Windows machine or at least a virtual machine, we can get ourselves started. Go to your preferred search engine and look for “microsoft visual studio community edition” or you can go directly to https://visualstudio.microsoft.com/downloads/.

Select the option to download Visual Studio Community edition. The file that downloads will help you set up the program, so once it finishes downloading, open it and you’ll get a screen that contains a list of options.

It will then be replaced with the following:

These are the general groups of components you can install. If you have the room, you can feel free to install the whole package, but that’ll take up a SIGNIFICANT amount of space on your hard drive, so check to make sure you have the space to do that. As you click on options, a small label at the bottom of this screen will tell you how much space is required. If you check against your C drive, you’ll see how much you have available.

Start by selecting .NET desktop development, Universal Windows Platform Development, Data storage and processing, and .NET Core cross-platform development. Then, up near the top, you’ll see “Individual Components”. Click this and you’ll get a VERY long list of individual features.

Make sure to check all of the options in the images above. There are actually more options beyond that third image, but we don’t need to concern ourselves with that for now. In the lower right-hand corner of the window is a drop-down box that will default to Install while downloading; the other options is Download all, then install. In theory, if you have a slower machine / connection, the second option is better, because it won’t slow down the overall function of your machine trying to do both at the same time. Now, just click the “Install” button to the right and the process will start running.

This will take a while, especially depending on your connection and computer. I hope you’re not still on a dial-up connection. There’s a LOT there to download and you’ll be at it all day. If you’re on a better connection though, the typical install time is somewhere between 5 minutes and half-an-hour. You can do something else in the meantime; maybe read and try my article on baking a loaf of bread; or if you do have that slow connection, consider something that’ll take a bit more time… like learning to play the violin flawlessly, or drafting a workable peace plan for the entire world. OK, I’m just kidding, those things aren’t nearly as slow-moving as a dial-up internet connection.

Wait, what if I need something else?

The nice thing about the setup for Visual Studio is that you can always add on functionality later on if you need some additional tools or libraries. If you used the pictures above as a guide, though, that’s it! You’re ready to go.

Conclusion

If you’re disappointed that you didn’t actually write a program, don’t be! You can’t learn to write software if you don’t have the tools to do it properly; and you want to learn to do this properly, so one thing at a time. In my next article, I’ll give an overview of the program we just installed; then we’ll make a simple console app. It won’t do much, but it’ll hopefully start you on the path to having a neat hobby and some useful skills.

One Month Later…

Well, if you’ve been following my posts lately (and judging by the site tracking, you haven’t)… wait, I haven’t MADE any blog posts in nearly a month. OK, I will level with you, I just was too preoccupied with work and household stuff to get to much here; so it’s really no surprise that my traffic took a nose-dive, because my work on this site did first.

Right now I’m in the process of getting another site project wrapped up, so for at least a little while longer, there won’t be much to see. I haven’t really had an opportunity to do anything with the West Seneca Valley Railroad; I definitely don’t do woodworking during this time of year (winter is NOT a great time for me to try this stuff without a proper shop environment)… so that leaves me with time in the kitchen.

I’ve tried out a few small new things recently. I have improved on the approach I take to doing cinnamon rolls; mostly I just do them as freestanding rolls now instead of in one of those pan setups.

I’ve made some sour cream glazed donuts which turned out quite nicely, some pizza dough that was not too shabby, and I’ve pretty much stopped buying any bread at stores. I’m not supposed to have much of that anyway, but since the kids still can have some, the home-made stuff is a lot better than having God-knows-what stuff put into the bread in factories.

So anyway, I’m going to try to wrap up some work I have pending now and maybe in a month or so I’ll be able to get back to something else more – interesting. I’ll try to post up some other things in the mean time.

One side-note, I have been playing around with the Unity development engine, just for fun, so when I have a bit of time and experience, I might try my hand at making a small game. If I do, I’ll post it up for download from the site.

That’s it for now.