public class Lesson6_GoFish_Pt2

{

void StartingTheGame()

{

This is a continuation of Lesson5_GoFish_Pt1. The full project code can be viewed or downloaded at https://github.com/TimPurdum/GoFish. In the previous post, we created a model of all the pieces needed to play the game, namely a Deck of Cards and Players with Hands and Sets.

 

For this part, we will be describing and programming the action or gameplay. Since the project is short, we will do this all within the Program class, although you could certainly create a Game class and move most of the code there. Let’s start by instantiating two players (one human and one computer) and a deck of cards as class fields that can be accessed from any method. The readonly tag means that these objects cannot be recreated (written to) later, although the methods and properties within are still writable.

        static readonly Deck Deck = new Deck();
        static readonly Player AI = new Player();
        static readonly Player Player = new Player();

 

Now let’s look at our Main method. Of course, you could put the entire logic into this method, but that would be poor design, and harder to read. Instead, we will simply deal with the introduction, shuffling the deck, and starting a while loop to create the game turns.

        static void Main()
        {
            Console.WriteLine("Let's play Go Fish!");
            Console.WriteLine("Type the letter 's' to shuffle the deck.");
            if (Console.ReadLine()?.ToLower() == "s")
            {
                Console.WriteLine("Shuffling...");
                Deck.Shuffle();
                Console.WriteLine();
                Deck.Deal(new List{Player, AI}, 7);

                while (Deck.Count > 0)
                {
                    ShowHand();
                    Guess();
                    AIGuess();
                }

                GameOver();
            }
        }

 

Notice that just like in our ChatBot project, we are using Console.WriteLine and Console.Readline to communicate with the user. Of course, you don’t have to introduce the game at all, or you could make it more involved (get the player’s name, for example).

 

The while loop represents rounds of the game. In each round, first we will ShowHand to the player, so they know what cards they have. Then, they will make a Guess, and we will deal with the results of that guess. Finally, the computer player (AI) will make their AIGuess, and the loop starts over. It ends when the deck is empty.

}
 

void ShowYourCards()

{

Each turn, we want to tell the player what cards they are holding.

        static void ShowHand()
        {
            Console.WriteLine("Here is your hand:");
            foreach (var card in Player.Hand)
            {
                Console.WriteLine($" - {card.Rank} of {card.Suit}");
            }
        }

}
 

void PlayersTurn()

{

Now it’s time for the player to take a turn. For this, we need to use Console.ReadLine() again. The player must have that rank in their hand (and if they have none, they simply draw). If the card is found, it is removed from the AI’s hand and given to the player. If not, the player must draw.

        static void Guess()
        {
            if (Player.Hand.Count == 0)
            {
                Console.WriteLine("No cards, you must draw this turn!");
                Deck.Draw(Player, 1);
                return;
            }
            
            Console.WriteLine();
            Console.WriteLine("Ask me if I have a card...");
            Console.WriteLine("(e.g., Ace, Two, Three, Four, King...)");
            var guess = Console.ReadLine();

            while (Player.Hand.All(c => c.Rank.ToString().ToLower() != guess?.ToLower()))
            {
                Console.WriteLine("You may only guess card numbers that you already have.");
                Console.WriteLine("Ask me if I have a card...");
                guess = Console.ReadLine();
            }
            
            Console.WriteLine();
            var cards = FindCards(guess, AI);
            
            if (cards != null)
            {
                var message = $"You got {cards.Count} {cards.First().Rank}!";
                if (cards.Count > 1)
                {
                    message = $"You got {cards.Count} {cards.First().PluralName}!";
                }
                Console.WriteLine(message);
                
                Player.Hand.AddRange(cards);
                foreach (var c in cards)
                {
                    AI.Hand.Remove(c);
                }
                LayoutSets(Player);
                Guess();
            }
            else
            {
                Console.WriteLine("No! Go Fish!");
                Thread.Sleep(1000);
                Deck.Draw(Player, 1);
                var newCard = Player.Hand.Last();
                Console.WriteLine($"You drew the {newCard.Rank} of {newCard.Suit}");
                LayoutSets(Player);
            }
        }

 

There are two places here where we have called new methods. The first is FindCards, which will search the AI player’s hand for the rank that was guessed. We are making heavy use of LINQ lambda expressions here, which you can learn more about. Any and Where are two LINQ statements that allow you to query a collection, such as a List or Array. Within each one, we declare an internal variable c, which represents each Card in the List, similar to a foreach statement. If the rank isn’t found, we can simply return null, which means no List was found.

        static List FindCards(string guess, Player p)
        {
            var cardGuess = guess.Trim().ToLower();

            if (p.Hand.Any(c => c.Rank.ToString().ToLower() == cardGuess))
            {
                return p.Hand.Where(c => c.Rank.ToString().ToLower() == cardGuess).ToList();
            }
           
            return null;
        }

 

The second new method is LayoutSets. This is where we will check to see if the player has four matching cards, and if so, move those sets to the Sets List.

        static void LayoutSets(Player p)
        {
            Console.WriteLine();
            
            var numberGroups = p.Hand.GroupBy(c => c.Rank);
            foreach (var numberGroup in numberGroups)
            {
                if (numberGroup.Count() == 4)
                {
                    var numberCards = numberGroup.ToList();
                    p.Sets.Add(numberCards);
                    foreach (var c in numberCards)
                    {
                        p.Hand.Remove(c);
                    }
                }
            }
            
            if (p.Sets.Count == 0)
            {
                return;
            }

            ShowSets(p);
        }

 

Notice that both FindCards and LayoutSets take a Player as an argument. This means that we can reuse these classes when it comes to the AI’s turn.

}
 

void ComputersTurn()

{

Once the player has finished, we give the computer (AI) a turn. Using Thread.Sleep() here and there can give the game a more pleasant pace, as modern computers are so fast that they will run through all these commands in less than a second.

 

Of course, in order to guess, we have to have the AI choose a random card rank from its hand. Luckily, .Net has a function called Random() that can do just that!

        static void AIGuess()
        {
            if (AI.Hand.Count == 0)
            {
                Console.WriteLine("No cards, I must draw this turn!");
                Deck.Draw(AI, 1);
                return;
            }
            
            var randomGenerator = new Random();

            var guessCard = AI.Hand[randomGenerator.Next(0, AI.Hand.Count - 1)];
            
            Console.WriteLine("My turn.");
            
            Console.WriteLine($"Do you have any {guessCard.PluralName}?");
            Thread.Sleep(2000);
            Console.WriteLine();
            var cards = FindCards(guessCard.Rank.ToString(), Player);
            
            if (cards != null)
            {
                if (cards.Count == 1)
                {
                    Console.WriteLine($"Yes? I'll take that {guessCard.Rank}!");
                }
                else
                {
                    Console.WriteLine($"Yes? I'll take those {guessCard.PluralName}!");
                }
                
                AI.Hand.AddRange(cards);
                foreach (var c in cards)
                {
                    Player.Hand.Remove(c);
                }
                LayoutSets(AI);
                AIGuess();
            }
            else
            {
                Console.WriteLine("No? I have to draw...");
                Thread.Sleep(1000);
                Deck.Draw(AI, 1);
                LayoutSets(AI);
            }
        }

 

As mentioned above, we re-use FindCards and LayoutSets for both players. Code re-use is an important principal in good programming.

}
 

void GameOver()

{

Let’s wrap up the game by totaling up the sets laid out and declaring a winner!

        static void GameOver()
        {
            Console.WriteLine("Game Over!");
            var playerPoints = 0;
            Player.Sets.ForEach(set => playerPoints += set.Count);
            Console.WriteLine($"Your score is {playerPoints}");
            var aiPoints = 0;
            AI.Sets.ForEach(set => aiPoints += set.Count);
            Console.WriteLine($"My score is {aiPoints}");
            if (playerPoints > aiPoints)
            {
                Console.WriteLine("You Win!");
            }
            else if (aiPoints > playerPoints)
            {
                Console.WriteLine("I Win!");
            }
            else
            {
                Console.WriteLine("Tie Game!");
            }
        }

 

If you have cloned the GitHub GoFish repository, and made changes to your version, feel free to create a pull request, to share your improvements back to our main repo! Or if you have a variation (maybe a new card game), you can share a link in the comments below.

}

}

public class Lesson5_GoFish_Pt1

{

void LetsPlayAGame()

{

It’s time to tackle a more complex assignment. We will start with a simple card game, “Go Fish.”


 

If you’ve never played, take a look at the directions at https://www.bicyclecards.com/how-to-play/go-fish/. We will be using a simple version of these rules to make our game. And if you would like to download or view the completed code project, go to https://github.com/TimPurdum/GoFish.

}
 

void ModelTheWorld()

{

Object-Oriented Programming is excellent for creating models of the real world, which, after all, is made up of objects. Let’s start by creating a model of a deck of cards. Actually, though, a deck of cards is just a collection of card objects, and we already know how to create collections! So, let’s start by creating a card object. What defines a card?

  • Suit – The color and symbol of the card. Hmm…maybe we need to represent suits as an object too. (In some other card games, the red suits are interchangeable, as are the black suits, so color might be important as well.)
  • Rank – The number or name of the card.

One simple way to create a list of value options is to create an enum. We will create two enums, one for Suit:

namespace GoFish
{
    public enum Suit
    {
        Hearts,
        Diamonds,
        Spades,
        Clubs
    }
}

 

And one for Rank:

namespace GoFish
{
    public enum Rank
    {
        Ace,
        Two,
        Three,
        Four,
        Five,
        Six,
        Seven,
        Eight,
        Nine,
        Ten,
        Jack,
        Queen,
        King
    }
}

 

In VS Code, go to File => New File, and add the code above for Suit. Save as Suit.cs, and then repeat and create Rank.cs. You should see these files added to your sidebar explorer, as well as the tabs at the top.

 

Now let’s create our Card file, saving it as Card.cs. Add the code below. Notice that this is now a class, out of which we can create all our cards. I’ve also created a property called PluralName so that I can return a string representation of the rank in its plural form.

namespace GoFish
{
    public class Card
    {
        public Suit Suit;
        public Rank Rank;
        
        public Card (Suit suit, Rank rank)
        {
            Suit = suit;
            Rank = rank;
        }


        public string PluralName
        {
            get
            {
                if (Rank == Rank.Six)
                {
                    return Rank + "es";
                }

                return Rank + "s";   
            }
        }
    }
}

 

Once we have the Card class, it is easy to build a collection of cards into a Deck. But instead of creating a collection by hand, I am using inheritance to create a special SubClass of List. Notice in the class declaration line, : List<Card>. This means that a Deck will inherit all the properties and methods of a List, such as Add and Remove. But in addition, we can add our own methods, like Shuffle and Draw.

using System;
using System.Collections.Generic;
using System.Linq;

namespace GoFish
{
    public class Deck : List
    {
        readonly Suit[] suits =
        {
            Suit.Hearts,
            Suit.Clubs,
            Suit.Diamonds,
            Suit.Spades
        };

        public Deck()
        {
            for (var i = 0; i < 13; i++)
            {
                foreach (var suit in suits)
                {
                    Add(new Card(suit, (Rank)i));
                }
            }
        }


        public void Shuffle()
        {
            var rnd = new Random();
            for (var i = 0; i < Count - 1; i++)
            {
                Swap(i, rnd.Next(i, Count));
            }
        }


        public void Deal(List players, int numberOfCards)
        {
            foreach (var player in players)
            {
                player.Hand = new List();
                Draw(player, numberOfCards);
            }
        }


        public void Draw(Player player, int numberOfCards = 1)
        {
            for (var cardNum = 0; cardNum < numberOfCards; cardNum++)
            {
                player.Hand.Add(this.First());
                RemoveAt(0);
            }
        }


        public Card Peek()
        {
            return this.First();
        }


        void Swap(int a, int b)
        {
            var temp = this[a];
            this[a] = this[b];
            this[b] = temp;
        }
    }
}

}
 

void ReadyPlayerOne()

{

We will create one more data model class, to signify a Player. Very simply, each player needs to have a Hand and Sets, or laid down 4-of-a-kind matches. Rather than create subclasses like we did for Deck, Hand uses the default List<Card> definition. Sets, however, is a List of a List, which allows you to track multiple groups of cards.

using System.Collections.Generic;

namespace GoFish
{
    public class Player
    {
        public List Hand { get; set; }
        
        public List> Sets { get; } = new List>();
    }
}

 

In our next post, we will explore how to lay out the action of the game!

}

}

public class Lesson4_Classes

{

void WeNeedMoreClass()

{

While it’s nice to see all of your code in one place, as programs get larger, organization can become a hassle with long files. Just as we split up our Program class into multiple methods, we can also split up our code into multiple class files.

Actually, a class is just another OOP encapsulation, and multiple classes could live in the same file.

 

This allows me to show you two classes functioning in dotnetfiddle (which is limited to one file for console apps), but it mostly defeats the purpose of separating the code into classes. Traditionally for larger projects, classes are saved each to their own file. In VS or VS Code, you can manage these files just like any other file-based application. Right-click over the Explorer sidebar and choose New C# Class from the dropdown.

 
Once you’ve named your new file, it should open for you in the editor, and you will see tabs at the top to switch between files.

 

Note that although the classes are in separate files, as long as the Namespace at the top of each file is the same, and they are in the same folder, they will have no trouble communicating with each other.

}
 

void InstantiatingAClass()

{

Once you have created a class file, in order to access the code in that file from another class, such as Program, you must instantiate, or create, an object of that class type. The class itself is a description, but you could have as many objects created with that type as you wish.

To instantiate an object, you use the new statement, and save the result to a variable.

 

var classObject = new ExtraClassy();

 

Then, to access features (methods, properties) on that object, use the dot syntax.

 

classObject.ClassyString = "Set the string";

 
}
 

void Constructors()

{

In the example above, the parentheses following ExtraClassy represent an empty Constructor. Every class has an empty constructor by default. However, sometimes we want to pass in parameters when instantiating an object, just like we pass data to methods.

 

Notice that a constructor, unlike a method, has no return type, and its name is the same as that of the class.

}
 

void Properties()

{

Above, you’ve seen several examples of a new item called a property. Properties are designed as accessible variables that can be set or get (retrieved) from outside the class. This is in contrast to fields, which are used primarily within a class.

A property always requires either a getter or setter, and can have both as well. An auto-property is one with the simplest form of these accessors, { get; set; }. This tells us that the property can be simply written to and read from. Sometimes, more complex logic might be used in either the get or set block, in which case they are encapsulated in curly braces and include a return like a method. These properties are often paired with a private field, which actually stores the data.

}
 

void DesignPrincipals()

{

Many amazing books and blog posts have been written about Object-Oriented Design principals, and it is not the purpose of this site to make you an expert in these. However, one simple design principal I have found extremely useful is to separate my classes into two groups: Data Transfer Objects (DTOs) and Business Logic classes. The examples on this page so far have been DTOs. That is, they exist primarily as a repository to store, transfer, and retrieve data, in the form of properties.

A Business Logic class, on the other hand, is one that does something, in the form of methods. In a short program, this might be all handled by the Program class, but it should be separated out into other classes for more complex designs.

}

}

public class Lesson3_ChatBot

{

void HelloAnyone()

{

We are going to create a simple chat bot, using the Console in DotNetFiddle or VSCode and a new command: Console.ReadLine().

Feel free to personalize the opening message and greeting. Can you add a second prompt? Maybe a follow-up question? (Typing anywhere in the code window will also reset the console output).

}

void DictionaryResponses()

{

To create a good list of responses to user input, it’s helpful to use a Dictionary, which is a new .NET Type, similar to the List, but with a matched pair of variables (key and value). Don’t forget to import System.Collections.Generic!

Here are some challenges for you

  1. Add more commands and responses to the dictionary.
  2. Can you make the program smart enough to understand both capitalized and uncapitalized strings? (hint: check for a method on the input variable by typing a period after and seeing what pops up)
  3. Use a for loop to have the program ask for commands more than once.
  4. Can you figure out a way to prevent the error message if someone types in an unknown command?

Don’t peek ahead until you’ve at least tried to solve #3-4!

}

void WhileLoops()

{

If you succeeded at creating a for loop for challenge #3 above, it probably looked something like this:

This saves us from writing out the code five times, but what if we want to keep going as long as the person is interested? That’s what a while loop is for. While loops continue as long as a certain variable or formula is true.

We’ll also take this time to introduce a new kind of variable, the field. The only difference between a regular variable and a field is that fields are created and maintained at the class level, so they are accessible from any method in that class.

}

void SafetyChecks()

{

No one likes seeing error codes pop up when running a program! To avoid the error that occurs when someone types in random commands, we need to understand why it is happening. In this instance, we have sent an input as a key to our Dictionary. The dictionary looks, but finds that key doesn’t exist. It doesn’t know what we want to do, so it throws an exception. Notice that even with the while loop code, the program terminates at the exception.

 

There are several ways to handle this problem. First, we can check to see if the key exists ahead of time. Luckily, the Dictionary class has a method for that purpose, called ContainsKey, that returns a boolean value to tell you whether or not to proceed.

The other approach is to use a Try/Catch block. The advantage of this approach is that we don’t need to check ahead, but we can still continue running if an exception is thrown. You can choose whether to print the exception, log it, ignore it, or have it trigger some other code. If there is no exception, the catch block is skipped.

}

void SaveYourWorkAndShare()

{

By now, hopefully you have lots of ideas of what your chat bot could do. Make sure to save your work! You can go to DotNetFiddle.Net and create a free account to save your fiddles.

 

Of course, if you are using VS Code, the files are already saved on your machine. If you want to share your local code, you should learn about using Git and GitHub with VSCode. Github also allows you to accept pull requests, or code contributions from other programmers.

 

Want to share your ideas with us? From DotNetFiddle or GitHub, you can simply copy the address of your code and paste it in a comment on this page! Let us know what your chatbot can do.

}

}

public class Lesson2_MethodsAndArguments

{

void Methods()

{

So far, everything we’ve been doing has been in the Main method. However, one of the features of good code writing is that methods are kept small and organized. One method may call another, and another, and another, with each one achieving a specific task.

}
 

void AccessModifiers()

{

If meant to be accessible by another class (file), the method declaration should begin with the public modifier. The default access level is private which means the method can only be called from within the same class.

}
 

void Static()

{

Static is a more advanced concept, yet it is always used in the Program class for any methods called via Main. Static means that the method belongs to the Type of the class, not to a particular object instantiation. We will return to it at a later point.

}
 

void MethodName()

{

The method name can be anything, but it is good to make it a clear description of what the method does. Method names cannot have spaces or special characters, so most .NET programmers use either PascalCase (capitalize every word) or camelCase (capitalize every word except the first).

}
 

void ParametersAndArguments()

{

When creating a method, you can pass variables to it by way of parameters listed in parentheses. When calling the method, these same variables are referred to as arguments.

}

}

public class Lesson1_BasicsAndLogic

{

/* These projects can be done in both dotnetfiddle.net and VS Code, but for the sake of immediacy, examples using DotNetFiddle have been embedded.*/

 

void UsingStatements()

{

Every file in C# uses using statements at the top of the page to import types and classes from other sources. If you try to copy something from one of these projects and get an error, check to see if there is a using statement you need to add. Often, the IDE will tell you what to add. For starters, you always need using System;

}
 

void Variables()

{

A variable is a saved instance of a type or class object. The simplest variable declaration is

var message = "Hello World!";

 

Note how this is used in the example below to pass the variable content to Console.WriteLine:

 

C# is intelligent enough to know that message is of Type string, since we assigned it to a string value. Try deleting the “Hello World” line above and replacing with var message = 43; or var message = true;. Notice that true is a bool, but "true" would be treated as a string, and likewise 43 is an int, but "43" would be a string. This is important to remember, because even though they can all be printed to the console, you can’t do math with a string, or ask whether a string is true or false.

}
 

void BasicTypes()

{

The basic types in C# are important to know, as these will represent much of the data we pass around a program. There are many types in .NET, but we will stick to the most common and useful.

}
 

void Math()

{

Performing math in C# is relatively straightforward, as can be seen by the example below. Try your hand at changing the formulas.

Did the last answer surprise you? Remember, all of our variables were declared as whole numbers, or integers, and so the answer will also be an integer. If you want the accurate decimal equivalent, at least one of the numbers in the division problem must be a double. Try replacing the 7 in line 21 with 7.0. This is a common mistake for beginning programmers, so be aware.

}
 

void StringConcatenation()

{

There are several ways to combine strings. Concatenating or interpolating is convenient, but if adding a lot of pieces together, using a StringBuilder is more effecient.

}
 

void IfElse()

{

Many times, a program must make a decision based on some user action, such as clicking a button. This is where boolean values and If/Else logic comes into play.

}
 

void Loops()

{

The loop is an important concept in programming, as it allows us to call a block of code multiple times. There are while and do while loops, but the more useful ones are for and foreach:

}

}

public class Lesson0_HelloWorld

{

void ASimpleProgram()

{

The first program most coders learn to write is a “Hello World”. This simple program is very short and easy to understand. Below is an interactive example, using dotnetfiddle.net, a useful online C# compiler.

Here is the same program with comments for each line. Notice that a comment is created with two forward slashes. Anything written in the line after the two slashes will be ignored by the compiler.

Use one of the frames above to try changing the code that is printed. It should update as soon as you begin typing. If you have trouble running here, you can try to open a new tab to dotnetfiddle.net.

}
 

void RunningLocally()

{

There are two Integrated Development Environments (IDEs) recommended for C#/.Net programming. While you can do a lot with dotnetfiddle.net, at some point you will find yourself wanting to create larger programs, and you will want to have an IDE.

 

Visual Studio is a full-featured IDE, which is used to create pretty much all Windows software on the market today, as well as a large amount of mobile and web projects. It is now available for Mac as well as Windows (although these are really still separate programs, so certain features may not be the same). While VS Community Edition is completely free, it is a very large program, and probably too much for starting out.

 

Visual Studio Code, despite it’s related name, is actually a much smaller program, with more focus on code writing/editing, and less features to support large projects. This actually makes it ideal for small projects and websites. VS Code is available for Windows, Mac, and even Linux.

// There is actually a third wonderful .NET editor, Jetbrains Rider. However, it doesn’t have a free version.

 

Download and install Visual Studio Code. If you are running on Windows, we will make a settings change to use the bash shell, so that the commands will be the same across platforms (skip to the next paragraph if you are on Mac/Linux). Go to File->Preferences->Settings and add this line between the curly braces in User Settings:

"terminal.integrated.shell.windows": "C:\\Program Files\\Git\\bin\\bash.exe"

 

Now, press Ctrl+` or use the menu View->Integrated Terminal to open the terminal window. Let’s create a new folder for working in. (For more info on terminal commands, see our Back in the Day post). Navigate to a place where you can create a folder, such as cd /Users/username/Documents/ (add c:/ to the beginning of the path for Windows). Make a folder with mkdir Projects and enter that folder (cd Projects

 

We will install one more piece of software, the .NET Core runtime, which is the cross-platform implementation of .NET. Once installed, return to VS Code, and type dotnet new console -o HelloWorld into the terminal.

 

Now use the VS Code File->Open Folder menu command and select your newly created HelloWorld folder. You should see something like this:

 

As you can see, this is essentially the same program that was written in DotNetFiddle, with a few variations. The namespace creates an encapsulation for multiple files/classes to be able to reference themselves, but have protection from other linked files. The `Main method now takes a string array of arguments, although currently they are not being used. We’ll show you what this is for later.

 

To run the program with .NET Core, you need to type the following command into the terminal: dotnet run. The computer should think for a moment (compiling your code), and then return “Hello World!”. If you make changes to the Program.cs file, such as updating the text to print, make sure you save the file before running again.

}

}

public class GettingStarted

{

public void SelectingALanguage()

{

There are dozens of modern programming languages to choose from, and they all have their advantages and disadvantages. I’m going to share my preferences, feel free to disagree. However, at least to get started, this site will focus on one language.

}

void ObjectOrientedProgramming()

{

The most popular form of modern programming is Object-Oriented Programming (OOP). OOP models everything in code as objects, which can have features (fields, properties) and abilities (methods, functions). For example, a Person class can be created to store a user, with properties such as FirstName, LastName, and PhoneNumber. Another class could be a RegisterUser class, with methods likeCreateNewPerson. For reasons of readability and maintainability, classes are often separated into data objectsdata structures, like Person, with few or no methods, and functional classes, like RegisterUser.

 

There are many websites with information about programming languages. I like this one, with it’s descriptive links and tree graph.

}

void FunctionalProgramming()

{

There is another model, known as Functional Programming (FP), that is gaining recognition and use. However, it does not currently have the deep history and proven usability for many different applications that OOP does. FP is especially useful for math-intensive programming, as opposed to User Interface (UI)-focused projects. In addition, the two models can be used together in large projects. This site will begin with OOP, but FP is mentioned for completeness.

}

void SelectC#()

{

There are many OOP languages, and no one language is the “best.” They vary widely in syntax, functionality, support

My go-to OOP language, that I find easy to read, powerful, and useful across any type of application, is C#, which runs on the .Net platform. C# and .Net code can currently run on any major operating system (Windows, Mac, iOS, Android, Linux), and will soon be able to be used in the browser, in place of or alongside javascript.

A few features of C#, besides being cross-platform compatible:

  • Static Typing: Every variable, field, parameter, and property in C# is a defined class type. This allows the IDE and compiler to know even before running code if there is an unsafe action, such as sending a text string where a number is expected.
  • Encapsulation: There are clear boundaries in C#, such as the curly braces {} that show the start and end of each namespace, class, and function, parentheses () around all parameters and arguments sent to each function, and the semicolon ; that declares the end of a line of code. Some languages prefer to use only line breaks, spaces, and indents to identify these boundaries, but I find the use of these character boundaries easier to read.
  • Support: C# is the first-class language of Microsoft, and has been in development and support for nearly 20 years. It is constantly being improved and updated, and I have no doubt that it will still be a first-class language 20 years from now.

This site will walk you through using C#. However, if you find anything confusing, or want more detail, check out Microsoft’s site Get Started with .NET and C#.

}

}

public class BackInTheDay

{

public void BackInTheDay()

{

// A Brief History of Computer Programming, and a Look at One Place to Get Started

When I was a kid, personal computers were new, exciting, and very, well, BASIC. Since earlier computers were designed by and for businesses and governments, it seemed logical that the thing to do with a computer was learn how to program that computer.

}

 

void Commodore64()

{

Try opening the emulator by clicking the image above, and typing in the following (note: on my keyboard I have to press Shift+2 to get quotes. I can’t remember if this was the placement on the old Commodore or not):

  1. 10 PRINT “HELLO WORLD!”
  2. RUN

We had GOTO statement loops, IF/THEN conditionals, and I remember having a lot of fun creating different screen art and quiz-games with just text. Since there weren’t a lot of possibilities, there also wasn’t a ton of We’re not going to dive into ancient BASIC here, but if you’re interested, check out https://en.wikibooks.org/wiki/BASIC_Programming.

}

 

void ModernUIs()

{

Coming back to programming as an adult, I was overwhelmed by the complexity of modern code. I bought books, watched videos, and googled for hours on end to try to make sense out of how to create an app or website.

While this approach definitely does work, there were many frustrating days of confusion. For example, to get started writing a new iOS app in Swift (which seemed like a nice, easy language), I had to learn about Storyboards, ViewControllers, Views, Delegates, and so on. Even a simple “Hello World” app would require multiple files.

Most of this complexity and confusion to getting started comes from the User Interface (UI), which has grown from the all-caps text on the Commodore into a graphical canvas with nearly limitless possibilities. There are wonderful WYSIWYG tools available, such as the Xcode Storyboard, which allows you to drag and drop controls like labels, buttons, and text fields.

“Hello World” is possible on iOS with no lines of code written at all!

Behind the scenes, however, the layout code is in the XML format, and it’s not so easy…

Can just about anyone make a new app? Definitely. However, I can attest to the fact that jumping in head-first this way can get you in trouble later. Using a tool like Storyboard does not prevent problems/errors, but it does limit your understanding of them and how to fix them. I’m not suggesting an app developer should ignore the tool, simply that they truly understand what they are doing. After several years of tinkering, I can read that XML, and it makes it much easier to know what is really going on in my UI.

}

 

void BusinessLogic()

{

Apart from the complexity, UI design actually has little or no bearing on the functionality of a program. Instead it is about display and ease of use. Separate from this is the Business Logic, which is where we use math, perform functions, and react to user actions and inputs. This was the heart of BASIC and early computer programs, before they got pretty graphics.

Wouldn’t it be nice if there were a way to separate the UI design from the Business Logic, so newcomers could first learn how a computer calculates, responds, processes?

}

 

void CommandLine()

{

Luckily, there is a way to write in modern programming languages with no UI to worry about. A Command Line Interface (CLI) takes us back to the old-school method of typing text to execute commands. These commands are executed by a shell program, that runs atop the operating system, and are accessed on most modern machines via a terminal emulator (Terminal in MacOS and Linux, Command Prompt in Windows).

}

 

void UsefulCommands()

{

Before doing any command-line programming, however, it’s necessary to at least know your way around the interface. Both Linux and MacOS use the BASH shell by default, and so they use the same set of keyword commands. The Windows Command Prompt, however, inherits from MSDOS, and has slightly different syntax.

(BTW, Windows 10 users can now also use Bash, so if you want one cross-platform solution, start there)

Commands Bash Terminal Windows Command Prompt Comments
 Change Directory

(Navigate)

cd cd You can go one folder “deeper” by typing just the folder name (e.g., cd Documents), or type in the entire path (e.g., cd C:/Users/Tim/Documents). To go “up” one level, use cd ..
List Files in Current Directory ls dir Lists all the files and folders in your current directory.
Make Directory mkdir mkdir Creates a new folder at your current location. mkdir NewFolder
Remove Directory rmdir rmdir Deletes a folder.
Copy File cp copy Follow the command with the file name to be copied and the new file name. You can include paths.

}

}