Gigi Labs

Please follow Gigi Labs for the latest articles.
Showing posts with label methods. Show all posts
Showing posts with label methods. Show all posts

Friday, September 20, 2013

VB .NET Basics: Input and Output

Sup people!

In today's article we're going to take a look at Visual Basic .NET (VB .NET for short, or even just VB if you're lazy). Like C#, VB .NET is based on the .NET framework, and so many classes and methods will be familiar. The syntax of the language, however, is quite different. Let's get our hands dirty and see for ourselves.

Fire up SharpDevelop (or Visual Studio, if you prefer). From the File menu, go to New -> Solution... so that you get the New Project dialog:


You'll need to open up the "VB" node in the Categories treeview to the left, select "Windows Applications", and then choose the "Console Application" template in the panel to the right. Select a name for the project, choose where on your filesystem to place it, and you're good to go. Hit the "Create" button.

You get the following code in SharpDevelop by default:

Module Program
    Sub Main()
        Console.WriteLine("Hello World!")
       
        ' TODO: Implement Functionality Here
       
        Console.Write("Press any key to continue . . . ")
        Console.ReadKey(True)
    End Sub
End Module

This is no different in functionality from what we saw in my first article here, C# Basics: Input and Output. Here's some example output:


Let's change code to achieve functionality similar to what we had in that article:

Module Program
    Sub Main()
        Console.WriteLine("What is your name?")
        Dim name As String = Console.ReadLine()
        Console.WriteLine("Hello {0}!", name)
        Console.ReadKey(True)
    End Sub
End Module

There are a few things to notice here. The Console methods are exactly the same as in C#, and even support the same {0}-style formatting. The general syntax, however, is very different:

  • There are no semicolons to end statements in VB .NET.
  • Variable declarations begin with the Dim keyword. Its etymology is pretty irrelevant - it's just an ugly way of saying "This here is a variable". Variable types, if included, go after the variable name.
  • Many blocks that are enclosed in braces ({ and }) in C# need an End statement in VB .NET instead (as you can see above). The same goes for things like If statements.
  • Module is like a class - in fact it's the equivalent of a static class. If you don't know what that means, don't worry about it.
  • In VB .NET, functions (also known as methods) come in two flavours. A Function is a regular function that returns some value. A Sub, on the other hand, is a subroutine that doesn't return a value (equivalent to void functions in C/C#/Java, or procedures in Pascal).
When it comes to variable declarations, you can actually leave out the data type, like this:

Dim name = Console.ReadLine()

That's perfectly valid, and name is automatically declared as a String since the type is deduced from the assignment. You can also declare just the variable name:

Dim money

However the type you want to use can't be deduced in this case, and is defaulted to Object.

I consider both of the above examples to be somewhat bad practice - I prefer to always include the variable type as it helps whoever's reading the code understand how that variable should be used. While there are legitimate reasons why you might want to leave it out, most of the time it's not a good idea (a very similar debate revolves around C#'s var keyword for the same reasons).

An important thing to note is that in many cases, VB .NET uses different keywords for data types. For example, you'd declare an integer like this:

Dim age As Integer

...and you declare your typical DateTime like this:

Dim dateOfBirth As Date

Woohoo! :) In this article, we've written our first VB .NET program, and taken a look at basic console input/output as well as dealing with variables.

Personally I don't like VB .NET much because its overuse of keywords, as well as their oddness (see Dim above) makes it a pretty ugly language to use if you're used to using languages with C-style syntax. However, you don't always get to choose which languages to use. So whether you're learning VB .NET as a first language or are switching over from C#, I hope you found this article useful! :) Be sure to check back here for more.

Friday, June 21, 2013

C#: Value Types vs Reference Types

Hi all! :)

I'll be writing a few articles about Object Oriented Programming (OOP), but before I do that, there's something I need to explain. In this article, I will be discussing the difference between value types and reference types, as well as the use of the ref keyword.

Let us first create a new console application using SharpDevelop (or Visual Studio, if you prefer). In this application, we declare a struct that represents a monster in a game (if you don't remember structs, look back at "C# Basics: Snake Game in ASCII Art (Part 1)"):

    struct Monster
    {
        public string name;
        public int health;
    };

This struct goes under the namespace, at the same level as class Program. We can now make instances of Monster in the Main() method:

            Monster wolf = new Monster();
            wolf.name = "Rex";
            wolf.health = 100;
           
            Monster steve = new Monster();
            steve.name = "Steve Ballmer";
            steve.health = 10;

Next, we define a couple of methods that work on a monster and modify its attributes:

        public static void RenameMonster(Monster monster, String newName)
        {
            monster.name = newName;
        }
       
        public static void HurtMonster(Monster monster, int damage)
        {
            monster.health -= damage;
        }

In Main(), we can test this:

            Console.WriteLine("Monster's name before: {0}", wolf.name);
            RenameMonster(wolf, "Wolverine");
            Console.WriteLine("Monster's name after: {0}", wolf.name);
           
            Console.WriteLine("Monster's health before: {0}", wolf.health);
            HurtMonster(wolf, 5);
            Console.WriteLine("Monster's health after: {0}", wolf.health);
           
            Console.ReadLine();

The output, however, is not quite what we were expecting:



If we change the Monster from a struct to a class and re-run the program, on the other hand, it works correctly:


So, what exactly is happening here? A struct is an example of a value type. When you pass it as a parameter to a function, a copy of it is actually passed to the function. If you modify it within that function, you are actually modifying the copy. When the function returns, the struct still has its old values.

A class, on the other hand, is a reference type. When you pass an instance of a class (i.e. an object) as a parameter to a function, the object itself is passed. You can make changes to the class's members and they are retained even after the function returns.

Most simple data types (such as integers, floats, etc), as well as structs and enumerations, are value types. Classes and strings are reference types, although a string behaves pretty much like a value type when passed to a function (see an explanation on Stack Overflow, if you're interested).

[Sidenote for purists: in C#, functions are actually called "methods". I consider the term "method" to be more of an OOP thing, and what we're doing here isn't quite OOP.]

It is, however, possible to pass a value type by reference. Let's say you have this function:

        public static void Increment(int x)
        {
            x++;
        }

If we try to call this function on a variable as it is, we're back to square one:


However, we can use the ref keyword to mark parameters that we want to pass by reference:

        public static void Increment(ref int x)
        {
            x++;
        }

...and do the same in the calling code:

            Increment(ref x);

This gives the result we want:


Wonderful. The bottom line is that structs and classes are very similar, but there are a few subtle differences (such as value type vs reference type, stack allocation vs heap allocation, etc) that can affect the way your code works. The differences are particularly clear if you know what pointers are. We will be using classes a lot for Object Oriented Programming (OOP), so it's important to know a little bit about them.

In the next article, we will dive straight into OOP! :)

Thursday, May 16, 2013

C# Threading: Bouncing Ball

Hi all! :)

I hope you've enjoyed the articles so far, and found the little ASCII art games both entertaining and mentally stimulating. Towards the end of yesterday's article, C# Basics: Snake Game in ASCII Art (Part 2), we discussed the problems with the Snake game. One of them was that the snake wouldn't move on its own - you had to press a key in order to make the program do something.

In today's article, we're going to begin learning about threads, and use them to overcome this limitation. This time we're going to draw a ball bouncing all over the console window.

Start a new console application, and add the following struct before the class Program:

    struct Vector
    {
        public int X;
        public int Y;
       
        public Vector(int x, int y)
        {
            this.X = x;
            this.Y = y;
        }
    }

You'll notice this is exactly the same as the Location struct in C# Basics: Snake Game in ASCII Art (Part 1). Instead of just using it just as a location, we're also going to use it as a direction. You'll see what I mean in a minute. Add the following for starters:

            Console.OutputEncoding = System.Text.Encoding.GetEncoding(1252);
            Console.Title = "Bouncing Ball";
           
            Vector ballLocation = new Vector(4012);
            Vector direction = new Vector(-1, -1);

So ballLocation is the location in the console window where we're going to draw our ball. The direction represents where the ball will go next, relative to ballLocation. In this case, the ball starts at (40, 12) and moves in a northwest direction, so the next position will be (39, 11), and then (38, 10), and so on.

[This paragraph is a bit more advanced... feel free to skip it.] The Vector struct is simply a code representation of a mathematical vector, where a vector such as (3, 1) means "three steps to the right, one step down" (depending on what coordinate system you're using). I'm not going to get into the mathematics, but if you're interested, check out my "A Concise Introduction to Vectors" [PDF].

We're now going to add a loop to show the ball and then move it:

            while (true)
            {
                Console.Clear();
                Console.SetCursorPosition(ballLocation.X, ballLocation.Y);
                Console.Write((char4);
               
                ballLocation.X += direction.X;
                ballLocation.Y += direction.Y;
                Thread.Sleep(100);
            }

At the beginning, add the following which is needed by Thread:

using System.Threading;

The code above is an infinite loop; there no condition for which the while loop will end. In this loop, we show an ASCII diamond as our ball, and then simply add the direction to the ballLocation in order to move it. The Thread.Sleep() at the end is simply a delay (in milliseconds) so that you can see the ball move; otherwise it would move quickly. Try changing the value of 100 and use something else (e.g. 1000, which means 1 second) to see what happens.

Press F5 to see the ball move:


You will get an exception once the ball moves off the edge. Add the following to fix this and make the ball change direction when it hits an edge (note || means "OR"):

                if (ballLocation.X == 0 || ballLocation.X == 79)
                    direction.X = -direction.X;
                if (ballLocation.Y == 0 || ballLocation.Y == 24)
                    direction.Y = -direction.Y;

The infinite loop allows the ball to move on its own without user intervention - just as we wanted with Snake. However, there is a problem: we cannot accept any user input like this. In fact, you can only exit by actually closing the window. If you try to add a

Console.ReadKey(true);

at the end of the while loop, we're back to square one: the user must press a key for anything to happen. Clearly, in order to accept input, we need the program to do two things at the same time: let the ball move, and handle user input. Fortunately, such godlike powers are not unique to Chuck Norris and Multiple Man.

A program (or process to be more precise) can do several things at the same time. It can be composed of multiple threads which run at the same time but do different things. This area of programming is called multithreading. Let's see how we can exploit this to allow user input while the ball is moving on its own.

First, move the while loop and the vectors to a new method outside of Main():

        public static void Move()
        {
            Vector ballLocation = new Vector(4012);
            Vector direction = new Vector(-1, -1);
           
            while (true)
            {
                Console.Clear();
                Console.SetCursorPosition(ballLocation.X, ballLocation.Y);
                Console.Write((char4);
               
                ballLocation.X += direction.X;
                ballLocation.Y += direction.Y;
                Thread.Sleep(100);

                if (ballLocation.X == 0 || ballLocation.X == 79)
                    direction.X = -direction.X;
                if (ballLocation.Y == 0 || ballLocation.Y == 24)
                    direction.Y = -direction.Y;
            }
        }

In what remains of the Main() method, add the following code:

            Thread thread = new Thread(Move);
            thread.IsBackground = true;
            thread.Start();
           
            Console.ReadKey(true);

When you press F5 and run the program, you will now end up with two threads:


The new thread is created in the first line of code above. A thread executes the code in a particular method, so we supply the name of the Move() method (without brackets) as a parameter.

In the second line, we set thread.IsBackground = true. A process (running instance of a program) runs as long as there is a foreground thread (such as the main thread) running. Since our new thread is designated as a background thread, the process will terminate once the main thread has exited.

The rest of the Main() method then starts the secondary thread and waits for a keypress. When the keypress is received, Main() ends, and with it the process. If we didn't set the secondary thread as a background thread, the process would keep on running anyway. Try that out. :)

Fantastic. :) In this article, we learned how to use a simple thread in order to allow a program to do two things at the same time. We used this to allow a game to run, while at the same time waiting for user input.

Stay tuned for more! :)

Monday, May 13, 2013

C# Basics: Command Interpreter Using Methods

Hello! :)

Today we're going to write a program similar to the Windows command prompt, Linux shell, or DOS. It's just a program that accepts commands from the user, and if it recognises the commands, it does something particular. We'll use this program to learn how to use methods, but we'll also learn a few other things as we go along. This article is admittedly longer than usual; rather that split it into two parts, I'm simply not going to post anything new tomorrow, so you can read this over two days if you like.

Let's start with this code:


            while (true)
            {
                String command = Console.ReadLine();

                if (command == "exit")
                    break;
            }

Here, we're accepting a line of text from the user and storing it in the String variable command. Instead of keeping a boolean variable to determine when to quit the loop, as in "C#: ASCII Art Game (Part 1)", we just loop forever (since the while condition is always true). When an "exit" command is received, the break statement allows us to break out of the loop anyway. Try that now.

Next, we add a little spice to our program. First, we set the console title:

            Console.Title = "Command Interpreter";

...and then, we make the user's input show up in white, by replacing the line containing Console.ReadLine() as follows:

                Console.ForegroundColor = ConsoleColor.White;
                String command = Console.ReadLine();
                Console.ResetColor();

Now, let's test what we have so far, by supporting an "echo" command. An "echo" command simply returns whatever you write after it. For example, if you write:

echo I can has cheezburger

...then you'd get:

I can has cheezburger

The only problem here is that we need to separate the command ("echo") from the parameters ("I can has cheezburger"). One way to do this is to break the command string into an array of individual words, as follows:

                String[] words = command.Split();

The command itself is now stored in words[0], while the parameters (if they exist) are in words[1] onwards. Finally, let's change the part where the "exit" command is being handled, and change it into a switch statement. The full code so far should look like this:

            Console.Title = "Command Interpreter";

            while (true)
            {
                Console.ForegroundColor = ConsoleColor.White;
                String command = Console.ReadLine();
                Console.ResetColor();

                String[] words = command.Split();

                switch (words[0])
                {
                    case "exit":
                        return;
                    case "echo":
                        for (int i = 1; i < words.Length; i++)
                        {
                            if (i > 1)
                                Console.Write(' ');
                            Console.Write(words[i]);
                        }
                        Console.WriteLine();
                        break;
                }
            }



For the "echo" command, we used a technique similar to that used in yesterday's article, "C# Basics: Morse Code Converter Using Dictionaries". You'll notice that the break statement used by the exit command has been changed to a return statement. That's because break has a different meaning when used in a switch statement, so we can't really use it there. Instead, return allows us to leave the Main() method completely. We can now test the program:


You'll notice that the code in the Main() method is beginning to grow, and will continue growing as we add more commands. We can organise our code by using methods. Methods are also called functions or subroutines in other languages, or even prodecures if they don't return anything. Take the following code:

                Console.ForegroundColor = ConsoleColor.White;
                String command = Console.ReadLine();
                Console.ResetColor();


...and move it into a new method outside Main(), as follows:

        static String ReceiveInput()
        {
            Console.ForegroundColor = ConsoleColor.White;
            String command = Console.ReadLine();
            Console.ResetColor();
            return command;
        }


This functionality is now defined in this method called ReceiveInput() which returns a String (i.e. it returns the input from the user). In the place where this code originally was, we now need only call this method:

                String command = ReceiveInput();

You'll notice that we now have two command variables declared: one in Main(), and one in ReceiveInput(). That's actually allowed, because they are in different methods. We say they are declared in a different scope.

Now, let's organise the code for the "echo" command in a similar way. Create a new method as follows:

        static void Echo(String[] words)
        {
            for (int i = 1; i < words.Length; i++)
            {
                if (i > 1)
                    Console.Write(' ');
                Console.Write(words[i]);
            }
            Console.WriteLine();
        }

This method has a void return type: that means it doesn't return anything - it just runs the statements within its body. This method is also different from the previous one in that it takes the parameter words. Methods can take any number of parameters in order to receive input data that they will be working with.

The code for the "echo" command can now be simplified as follows:

                    case "echo":
                        Echo(words);
                        break;

If you run the program now, you'll notice it works exactly the same as before.

Now, let's support another command called "total":

        static int Total(String[] words)
        {
            int total = 0;
            try
            {
                for (int i = 1; i < words.Length; i++)
                    total += Convert.ToInt32(words[i]);
            }
            catch (Exception)
            {
                Console.WriteLine("Invalid input");
            }

            return total;
        }

...and...

                    case "total":
                        int total = Total(words);
                        Console.WriteLine(total);
                        break;

The "total" command just calculates the sum of the numbers passed as parameters. Example output:




Finally, let's now support an "average" command:

        static int Average(String[] words)
        {
            int total = Total(words);
            int average = total / (words.Length - 1);
            return average;
        }

...and...

                    case "average":
                        int average = Average(words);
                        Console.WriteLine(average);
                        break;

You'll notice we are using Total() directly to calculate the sum used by the average, instead of repeating the code in Total(). One of the great benefits of methods is that they allow code reuse and eliminate duplicate code - something that plagued my earlier article, "The ASCII Table (C#)". A best practice in programming is the Don't Repeat Yourself (DRY) principle.

Output:


You'll remember from "C# Basics: Arithmetic and Exceptions" that we aren't getting any decimal point in divisions because we are working with integers.

That's it for today! We wrote a little command interpreter, learned how to create our own methods, and learned a lot of new stuff in the process including the break statement, the return statement, and variable scoping. As I wrote earlier, since this was extra long, there will be no article tomorrow!

Here's the full code for today's article:

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

namespace CsCommandInterpreter
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.Title = "Command Interpreter";

            while (true)
            {
                String command = ReceiveInput();

                String[] words = command.Split();

                switch (words[0])
                {
                    case "exit":
                        return;
                    case "echo":
                        Echo(words);
                        break;
                    case "total":
                        int total = Total(words);
                        Console.WriteLine(total);
                        break;
                    case "average":
                        int average = Average(words);
                        Console.WriteLine(average);
                        break;
                }
            }
        }

        static String ReceiveInput()
        {
            Console.ForegroundColor = ConsoleColor.White;
            String command = Console.ReadLine();
            Console.ResetColor();
            return command;
        }

        static void Echo(String[] words)
        {
            for (int i = 1; i < words.Length; i++)
            {
                if (i > 1)
                    Console.Write(' ');
                Console.Write(words[i]);
            }
            Console.WriteLine();
        }

        static int Total(String[] words)
        {
            int total = 0;
            try
            {
                for (int i = 1; i < words.Length; i++)
                    total += Convert.ToInt32(words[i]);
            }
            catch (Exception)
            {
                Console.WriteLine("Invalid input");
            }

            return total;
        }

        static int Average(String[] words)
        {
            int total = Total(words);
            int average = total / (words.Length - 1);
            return average;
        }
    }
}

As an exercise, test the program above and see if you can find any bugs (there are at least two). Solve them.

Come back on Wednesday for the next article! :)