Gigi Labs

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

Wednesday, November 6, 2013

C#: XML Serialization

Hi guys and gals! :)

In this article, we're going to see how to do XML serialization, which is really just a fancy way of saying we want to load and save objects as files in XML format.

So you see, I've been a big fan of Warcraft 2 for a long time... probably about 15 years. In this game, you command different units (e.g. peasants, knights, etc), and each of them has different attributes such as Damage, Speed, etc. For instance, this is the mage:


Don't mess with that guy - he can turn you into a sheep! And here's the knight... not exactly a mild-mannered fellow, either:


If we represent those units and their attributes in XML, we might end up with something like this (I took out some of the extra crap that appears at the beginning when you actually save a file using XML serialization):

<UnitDatabase>
  <units>
    <Unit>
      <Name>Mage</Name>
      <Armor>0</Armor>
      <MinDamage>5</MinDamage>
      <MaxDamage>9</MaxDamage>
      <Range>2</Range>
      <Sight>9</Sight>
      <Speed>8</Speed>
    </Unit>
    <Unit>
      <Name>Knight</Name>
      <Armor>4</Armor>
      <MinDamage>2</MinDamage>
      <MaxDamage>12</MaxDamage>
      <Range>1</Range>
      <Sight>4</Sight>
      <Speed>13</Speed>
    </Unit>
  </units>
</UnitDatabase>

So, let's see how we can actually read and write a file like this in C#. Create a new Console Application in your favourite IDE.

We first need to create a class to represent our units with their attributes. Create a class and call it Unit. For convenience, we can implement the attributes as auto-implemented properties as follows:

        public String Name { get; set; }
        public int Armor { get; set; }
        public int MinDamage { get; set; }
        public int MaxDamage { get; set; }
        public int Range { get; set; }
        public int Sight { get; set; }
        public int Speed { get; set; }

This is just a quick alternative to declaring a member variable and a corresponding read-write property (available from .NET 3.0 onwards). For example, the Name property above is more or less equivalent to the following (just for demonstration - don't actually add it to your code):

        private String name;
       
        public String Name
        {
            get
            {
                return this.name;
            }
            set
            {
                this.name = value;
            }
        }

Next, add a constructor to set the attributes, so we can easily create Unit instances from our main program code:

        public Unit(String name, int armor, int minDamage, int maxDamage, int range, int sight, int speed)
        {
            this.Name = name;
            this.Armor = armor;
            this.MinDamage = minDamage;
            this.MaxDamage = maxDamage;
            this.Range = range;
            this.Sight = sight;
            this.Speed = speed;
        }

Now we need to create another class to hold an array of these units. Create a new class and call it UnitDatabase (admittedly a bit of a poor choice of a name, since it's not actually a database, but anyway). Give it a Units property as follows:

         public Unit[] Units { get; set; }

A constructor to assign this directly can also be pretty convenient. Add the following:

        public UnitDatabase(Unit[] units)
        {
            this.Units = units;
        }

Now we can implement our loading and saving code in UnitDatabase itself. Start by adding the code to save the UnitDatabase to a file:

        public void Save(String filename)
        {
            XmlSerializer ser = new XmlSerializer(typeof(UnitDatabase));
           
            using (StreamWriter sw = File.CreateText(filename))
                ser.Serialize(sw, this);
        }

You can see that we're making use of the XmlSerializer class. The file is saved by using its Serialize() method, which takes a TextWriter and the object to serialize. The StreamWriter returned by File CreateText() quite conveniently is a subclass of TextWriter, so we can pass it as the first parameter to Serialize(). The second parameter is this: the UnitDatabase itself.

To get this code to compile, you'll have to add the following using statements at the top:

using System.Xml.Serialization;
using System.IO;

Loading an XML file as a UnitDatabase is just as easy. In this case we make the method static since it isn't tied to any particular UnitDatabase instance:

        public static UnitDatabase Load(String filename)
        {
            XmlSerializer ser = new XmlSerializer(typeof(UnitDatabase));
           
            using (StreamReader sr = File.OpenText(filename))
                return ser.Deserialize(sr) as UnitDatabase;
        }

You can see that we're still using the XmlSerializer, but this time we use the Deserialize() method to read the file from disk and create a UnitDatabase from it. Deserialize() takes a TextReader, which again is a base class of the StreamReader that we get by calling File.OpenText(), so everything fits like magic. Deserialize() returns an Object, so as a last touch we cast this to a UnitDatabase using the as keyword. It's just the same as writing it like this:

                return (UnitDatabase) ser.Deserialize(sr);

That's all we need! Now, let's add some functionality to make it easy to write our units to the console output. All classes inherit from Object, and Object defines this ToString() method which we can use to return a string representation of our objects. This is very convenient in our case, so we can implement Unit's ToString() method as follows:

         public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendFormat("Name:      {0}", this.Name);
            sb.AppendLine();
            sb.AppendFormat("Armor:     {0}", this.Armor);
            sb.AppendLine();
            sb.AppendFormat("MinDamage: {0}", this.MinDamage);
            sb.AppendLine();
            sb.AppendFormat("MaxDamage: {0}", this.MaxDamage);
            sb.AppendLine();
            sb.AppendFormat("Range:     {0}", this.Range);
            sb.AppendLine();
            sb.AppendFormat("Sight:     {0}", this.Sight);
            sb.AppendLine();
            sb.AppendFormat("Speed:     {0}", this.Speed);
            sb.AppendLine();
           
            return sb.ToString();
        }

Note the override keyword in the method's signature. This means that we are replacing ToString()'s default functionality (which usually just returns the name of the class) with our own, in this case showing the unit's name and attributes.

Let's do the same for UnitDatabase. In this case we return a concatenation of all the units' string representations:

        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            foreach (Unit unit in this.Units)
                sb.AppendLine(unit.ToString());
            return sb.ToString();
        }

To compile this code, you'll need to add the following line at the top of both files (because of the StringBuilder):

using System.Text;

Now all we have left to do is write code in Main() that actually uses these classes. We can start by creating our two units:

            Unit mage = new Unit("Mage", 0, 5, 9, 2, 9, 8);
            Unit knight = new Unit("Knight", 4, 2, 12, 1, 4, 13);

We can then combine these into an array using collection initializer syntax (see "C# Basics: Morse Code Converter Using Dictionaries" if you forgot what that is):

            Unit[] units = new Unit[] { mage, knight };

Then, we create a UnitDatabase out of this array:

            UnitDatabase db = new UnitDatabase(units);

...and finally save it to a file called units.xml:

            db.Save("units.xml");

You can now press F5 to run the program and see that it works. If you're using Visual Studio, you might have run into this error:


That's because XML serialization needs classes to have an empty constructor. SharpDevelop creates one for you when you create a new class, but Visual Studio does not. So if you're missing those, add them in. One for Unit:

        public Unit()
        {
           
        }

...and one for UnitDatabase:

        public UnitDatabase()
        {
           
        }

Good. Now press F5 to run the program, and then go to the project's bin\Debug folder to check that the units.xml file has been created. When you open it, it should look like this:

<?xml version="1.0" encoding="utf-8"?>
<UnitDatabase xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Units>
    <Unit>
      <Name>Mage</Name>
      <Armor>0</Armor>
      <MinDamage>5</MinDamage>
      <MaxDamage>9</MaxDamage>
      <Range>2</Range>
      <Sight>9</Sight>
      <Speed>8</Speed>
    </Unit>
    <Unit>
      <Name>Knight</Name>
      <Armor>4</Armor>
      <MinDamage>2</MinDamage>
      <MaxDamage>12</MaxDamage>
      <Range>1</Range>
      <Sight>4</Sight>
      <Speed>13</Speed>
    </Unit>
  </Units>
</UnitDatabase>

It's got some more stuff in the first two lines that I showed you at the beginning, but that's just added there to make it a valid XML document and you can just ignore it.

At the end of Main(), let us now add code to load the file and display the unit data:

            UnitDatabase loadedDb = UnitDatabase.Load("units.xml");
            Console.WriteLine(loadedDb.ToString());
            Console.ReadLine();

Press F5 to see the result:


If you omit the ToString() as follows:

             Console.WriteLine(loadedDb);

...then the program works all the same, because Console.WriteLine() uses the ToString() method of the objects it is meant to write.

Great! :) In this article, we have seen how we can very easily save (serialize) objects as XML files, and load (deserialize) them back from XML files. To do this we need classes that match the XML structure, as well as the handy XmlSerializer class. Classes to be serialized must have a parameterless constructor. It is possible to do a lot more with XML serialization - there are several attributes that allow you to control the actual XML nodes and attributes that are written to the file.

We have also seen other aspects of C#, such as the ToString() method available in every object; how to override inherited methods; the as keyword which is an elegant alias for type casting; and auto-implemented properties.

Thanks for reading, and come visit Programmer's Ranch again in future! :)

Sunday, October 6, 2013

C#: Extracting Zipped Files with SharpZipLib

Hello there! :)

In this article, we're going to learn how to extract files from a .zip file using a library called SharpZipLib.
Additionally, we will also learn how to work with third-party libraries with functionality we might not get by default. This is because SharpZipLib is not part of the .NET Framework, and is developed by an independent team.

To get started, we need to create a new Console Application in SharpDevelop (or Visual Studio, if you prefer), and also download SharpZipLib from its website. When you extract the contents of the .zip file you downloaded, you'll find different versions of ICSharpCode.SharpZipLib.dll for different .NET versions. That's the library that will allow us to work with .zip files, and we need the one in the net-20 folder (the SharpZipLib download page says that's the one for .NET 4.0, which this article is based on).

Now, to use ICSharpCode.SharpZipLib.dll, we need to add a reference to it from our project. We've done this before in my article "C#: Unit Testing with SharpDevelop and NUnit". You need to right click on the project and select "Add Reference":


In the window that comes up, select the tab called ".NET Assembly Browser", since we want to reference a third party .dll file. Open the ICSharpCode.SharpZipLib.dll file, click the "OK" button in the "Add Reference" dialog, and you're ready to use SharpZipLib.


In fact, you will now see it listed among the project's references in the Projects window (on the right in the screenshot below):


Great, now how do we use it?

This is where our old friend, Intellisense, comes in. You might recall how we used it to discover things you can do with strings in one of my earliest articles here, "C# Basics: Working with Strings". This applies equally well here: as you begin to type your using statement to import the functionality you need from the library, Intellisense suggests the namespace for you:


Now SharpZipLib has a lot of functionality that allows us to work with .zip files, .tar.gz files and more. In our case we just want to experiment with .zip files, so we're fine with the following:

using ICSharpCode.SharpZipLib.Zip;

That thing is called a namespace: it contains a set of classes. If you type it into your Main() method and type in a dot (.) after it, you'll get a list of classes in it:


A namespace is used to categorise a set of related classes so that they can't be confused with other classes with the same name. Java's Vector class (a kind of resizable array) is a typical example. If you create your own Vector class to represent a mathematical vector, then you might run into a naming conflict. However, since the Java Vector is actually in the java.util namespace, then its full name is actually java.util.Vector.

This works the same way in C#. The List class you've been using all along is called is actually called System.Collections.Generic.List. We usually don't want to have to write all that, which is why we put in a using statement at the top with the namespace.

When we're working with a new namespace, however, typing the full name and using Intellisense allows us to discover what that namespace contains, without the need to look at documentation. In the screenshot above, we can already guess that ZipFile is probably the class we need to work with .zip files.

Intellisense also helps us when working with methods, constructors and properties:


I suppose you get the idea by now. Let's finally actually get something working. To try this out, I'm going to create a zip file with the following structure:

+ test1.txt
+ folder
    + test2.txt
    + test3.txt

I've used WinRAR to create the zip file, but you can use anything you like. I named it "zipfile.zip" and put it in C:\ (you might need administrator privileges to put it there... otherwise put it wherever you like). Now, we can easily obtain a list of files and folders in the .zip file with the following code:

        public static void Main(string[] args)
        {
            using (ZipFile zipFile = new ZipFile(@"C:\\zipfile.zip"))
            {
                foreach (ZipEntry entry in zipFile)
                {
                    Console.WriteLine(entry.Name);
                }
            }
         
            Console.ReadLine();
        }

This gives us:


We use the using keyword to close the .zip file once we're done - something we've been doing since my article "C#: Working with Streams". You realise you need this whenever you see either a Dispose() or a Close() method in Intellisense. We are also using looping over the zipFile itself - you realise you can do a foreach when you see a GetEnumerator() method in Intellisense. Each iteration over the zipFile gives us a ZipEntry instance, which contains information about each item in the .zip file. As you can see in the output above, entries comprise not just files, but also folders.

Since we want to extract files, folders are of no interest for us. We can use the IsFile property to deal only with files:

                    if (entry.IsFile)
                        Console.WriteLine(entry.Name);

In order to extract the files, I'm going to change the code as follows:

        public static void Main(string[] args)
        {
            using (ZipFile zipFile = new ZipFile(@"C:\\zipfile.zip"))
            {
                foreach (ZipEntry entry in zipFile)
                {
                    if (entry.IsFile)
                    {
                        Console.WriteLine("Extracting {0}", entry.Name);
                 
                        Stream stream = zipFile.GetInputStream(entry);
                        using (StreamReader reader = new StreamReader(stream))
                        {
                            String filename = entry.Name;
                            if (filename.Contains("/"))
                                filename = Path.GetFileName(filename);
                             
                            using (StreamWriter writer = File.CreateText(filename))
                            {
                                writer.Write(reader.ReadToEnd());
                            }
                        }
                    }
                }
            }
         
            Console.ReadLine();
        }

Note that I also added the following to work with File and Path:

using System.IO;

Extracting files involves a bit of work with streams. The zipFile's GetInputStream() method gives you a stream for a particular entry (file in the .zip file), which you can then read with a StreamReader as if you're reading a normal file.

I added a bit of code to handle cases when files are in folders in the .zip file - I am finding them by looking for the "/" directory separator in the entry name, and then extracting only the filename using Path.GetFileName(). [In practice you might have files with the same name in different folders, so you'd need to actually recreate the folders and put the files in the right folders, but I'm trying to keep things simple here.]

Finally, we read the contents of the entry using reader.ReadToEnd(), and write it to an appropriately named text file. If you run this program and go to your project's bin\Debug folder in Windows Explorer, you should see the test1.txt, test2.txt and test3.txt files with their proper contents. [Again, the proper way to deal with streams is to read chunks into a buffer and then write the file from it, but I'm using reader.ReadToEnd() for the sake of simplicity.]

Excellent! In this article, we have learned to list and extract files from a .zip file. We also learned why namespaces are important. But most importantly, we have looked at how to reference third party .dlls and discover how to use them based only on hints from Intellisense and our own experience. In fact, the above code was written without consulting any documentation whatsoever, solely by observing the intellisense for SharpZipLib. While it is usually easier to just find an example on the internet (possibly in some documentation), you'll find that this is a great skill to have when documentation is not readily available.

If you found this interesting, be sure to check back for future articles in which I will be covering other useful topics! Also, if you happen to like computer games, be sure to check out GOG's catalogue of cheap, DRM-free games. If you buy games through this link, you will be supporting Programmer's Ranch at the same time.

Friday, September 27, 2013

C#: Understanding Recursion with Directory Traversal

Greetings, and welcome to this brand new article at Programmer's Ranch! :)

In this article, we're going to talk about recursion. This technique is often considered an alternative to iteration (i.e. loops), and is useful for a wide variety of situations ranging from computing factorials to clearing empty areas in Minesweeper:


Since factorials are boring, and Minesweeper is a bit complex for this easy tutorial, we're going to look at the filesystem in order to learn about recursion. For example, take a look at the folder for the solution I just created in SharpDevelop:


See, the filesystem is actually a tree data structure. Each folder can contain other files and folders, which can in turn contain other files and folders, and so on. It isn't easy to work with things like trees using loops, but with recursion it just comes natural. Let's see how.

After creating a new console application, add the following at the top, which we need to interact with the filesystem:

using System.IO;

The first thing we want to do is get the current directory where the executable will be running. We do this by using Directory.GetCurrentDirectory(). Let's try that out:

            String currentDir = Directory.GetCurrentDirectory();
            Console.WriteLine(currentDir);
            Console.ReadKey(true);

...and here's what we get:


Now, we want to navigate up to the first CsRecursion folder, which is the solution folder. From there we'll be able to list the contents of all the subfolder. To do this, we create an instance of DirectoryInfo:

            DirectoryInfo dir = new DirectoryInfo(currentDir);

This allows us to get to the parent folder:

            dir = dir.Parent.Parent.Parent;

...and this is what we have so far:


Right, now about listing the folder and subfolder contents. Let's add a method to do that:

        public static void ListContents(DirectoryInfo dir)
        {
           
        }

In this method, we first want to list all the files in that folder. We can do this using DirectoryInfo.GetFiles(), or else using the static Directory.GetFiles() method, which is easier and works directly with file paths (Strings):

            foreach (String file in Directory.GetFiles(dir.FullName))
                Console.WriteLine(file);

Okay, now all we need is to do the same thing for all subfolders. It turns out that our ListContents() method can actually call itself, and pass in each subdirectory as a parameter:

            foreach (DirectoryInfo subdir in dir.GetDirectories())
                ListContents(subdir);

When a method calls itself, it's called recursion. In this case we say we are recursing into subdirectories.

Let's just change Main() so that it calls our ListContents() method:

        public static void Main(string[] args)
        {
            String currentDir = Directory.GetCurrentDirectory();
            DirectoryInfo dir = new DirectoryInfo(currentDir);
            dir = dir.Parent.Parent.Parent;
            ListContents(dir);
           
            Console.ReadKey(true);
        }

...and voilà:


As you can see, there's a very small amount of code, and recursion is a perfect fit for this kind of thing, because the same method can work on folders at different levels of the filesystem.

There's an important concept about recursion you need to be aware of, that might not be so evident in this example: the stopping condition. If a method calls itself and has no way to stop calling itself, you get a sort of infinite loop which actually ends in a stack overflow (in short, there's a limit to the number of times a method can call another method). Therefore, a recursive function always needs a way to stop calling itself.

If you're doing factorials, recursion stops when n=1. If you're computing a Fibonacci sequence, n=0 and n=1 are the stopping conditions. In our case, recursion stops when a folder has no further subfolders. In Minesweeper, recursion stops when there are no more adjacent blank squares (you either hit an edge or a number).

Anyhow, as we have seen in this article, recursion is a great technique to use when your data has divergent paths (most notably when dealing with trees). There are a few other interesting applications of recursion that I'll probably be writing about in the future, so stay tuned! :)

Sunday, September 22, 2013

C#: Mocking and Dependency Injection for Unit Testing a File Sorting Program

Hullo folks! :)

In yesterday's article, "C#: Unit Testing with SharpDevelop and NUnit", we learned about unit tests: what they are, why we use them, and how we write and execute them. The article ended with a number of insights about them. One of these insights was that it is not easy to write unit tests for code that relies on databases, the network, or other external resources.

In today's article, we're going to address this problem by learning about mocking and dependency injection. These might sound like big buzz-words, but you'll see in this article that they're really nothing special. To see this in action, we'll write a small program that loads a file from the hard disk and sorts it alphabetically, line by line.

This article is a bit on the advanced side, so ideally you should know your OOP and also be familiar with basic unit testing (e.g. from yesterday's article) before reading it.

Start off by creating a new Console Application in SharpDevelop. When this is done, add a new class (right click on project in Projects window, Add -> New Item...) and name it Sorter. At the top, add the following to allow us to read files and use lists:

using System.Collections.Generic;
using System.IO;

Next, add a member variable in which we can store the lines in the file:

private String[] lines;

Add a constructor in Sorter that takes the name of the file to sort, and loads it into the variable we just declared:

        public Sorter(String filename)
        {
            this.lines = File.ReadAllLines(filename);
        }

Now, add a method that actually does the sorting:

        public String[] GetSortedLines()
        {
            List<String> sortedLines = new List<String>(lines);
            sortedLines.Sort();
            return sortedLines.ToArray();
        }

This way of sorting is not the only one and not necessarily the best, but I chose it because it's simple and doesn't change the lines variable, just in case you want to keep it in its original unsorted format for whatever reason.

Let's try and write a test for this code. Add a new class called SorterTest (as I've already mentioned in yesterday's article, people usually put tests into their own project, but I'm trying to teach one concept at a time here). After adding a reference to nunit.framework.dll (check yesterday's article in case you're lost), set up the SorterTest.cs file as follows:

        [Test]
        public void GetSortedLinesTest()
        {
            Sorter sorter = new Sorter("test.txt");
            String[] s = sorter.GetSortedLines();
          
            Assert.AreEqual("Gates, Bill", s[0]);
            Assert.AreEqual("Norris, Chuck", s[1]);
            Assert.AreEqual("Torvalds, Linus", s[2]);
            Assert.AreEqual("Zuckerberg, Mark", s[3]);
        }

Create a file in your bin\Debug folder called test.txt and put the following in it:

Zuckerberg, Mark
Norris, Chuck
Gates, Bill
Torvalds, Linus

Open the Unit Tests window in SharpDevelop (View -> Tools -> Unit Tests) and run it. You can see that the test passes.

Great.

Actually, this is the wrong way of writing unit tests for this kind of thing. We have a dependency on the filesystem. What would happen if that file suddenly disappears? As a matter of fact, we are supposed to be testing the sorting logic, not whether the file is available or not.

In order to do this properly, we're going to have to refactor our code. We need to take our file loading code out of there. Create a new class called FileLoader and add the following at the top:

using System.IO;

...and then set up FileLoader as follows:

    public class FileLoader
    {
        private String[] lines;
      
        public String[] Lines
        {
            get
            {
                return this.lines;
            }
        }
      
        public FileLoader(String filename)
        {
            this.lines = File.ReadAllLines(filename);
        }
    }

In Sorter, remove the constructor as well as the using System.IO; and the lines variable. Instead, we'll pass our FileLoader as a parameter:

        public String[] GetSortedLines(FileLoader loader)
        {
            List<String> sortedLines = new List<String>(loader.Lines);
            sortedLines.Sort();
            return sortedLines.ToArray();
        }

This is called dependency injection: instead of creating the dependency (in our case a file) from within the Sorter class, we pass it as a parameter. This allows us to substitute the dependency for a fake (known as a mock). To do this, we'll need to take advantage of polymorphism (see "C# OOP: Abstract classes, fruit, and polymorphism". Create an interface (when adding a new item, instead of Class, specify Interface) and name it IFileLoader:


An interface is a form of abstract class - it cannot be instantiated, and it declares methods and/or properties that don't have any implementation because they should be implemented by the classes that inherit from (or implement) that interface. In an interface, however, no methods/properties have an implementation. It is used as a contract, saying that any class implementing the interface must implement its methods/properties. In our case, IFileLoader will be this:

    public interface IFileLoader
    {
        String[] Lines
        {
            get;
        }
    }

We then specify that FileLoader implements IFileLoader; this is the same as saying that FileLoader inherits from IFileLoader:

public class FileLoader : IFileLoader

FileLoader already has the necessary Lines property, so we're fine. Next, we replace the FileLoader parameter in Sorter.GetSortedLines() with an instance of the interface:

public String[] GetSortedLines(IFileLoader loader)

This allows us to pass, as a parameter, any class that implements IFileLoader. So we can create a class, MockFileLoader, that provides a hardcoded list of names:

    public class MockFileLoader : IFileLoader
    {
        private String[] lines = { "Zuckerberg, Mark", "Norris, Chuck", "Gates, Bill", "Torvalds, Linus" };
      
        public String[] Lines
        {
            get
            {
                return this.lines;
            }
        }
    }

We can now rewrite our unit test like this:

        [Test]
        public void GetSortedLinesTest()
        {
            IFileLoader loader = new MockFileLoader();
            Sorter sorter = new Sorter();
            String[] s = sorter.GetSortedLines(loader);
          
            Assert.AreEqual("Gates, Bill", s[0]);
            Assert.AreEqual("Norris, Chuck", s[1]);
            Assert.AreEqual("Torvalds, Linus", s[2]);
            Assert.AreEqual("Zuckerberg, Mark", s[3]);
        }

If you run the unit test, you'll find that it works just like before, just that this time our unit test isn't dependent on any file and can run just file without one:


In this article, we have seen how to create mock classes that emulate the functionality of our normal classes, but can replace them in unit tests when dependencies exist. To facilitate this, both the mock class and the normal class implement a common interface, and an instance of this interface is passed as a parameter to the method being tested. This is called dependency injection and allows us to control what is being passed to the method.

It is not always easy to write mocks. First, as this article has shown, code may need to be refactored in order to isolate dependencies and support dependency injection. Secondly, mocking complex classes (e.g. an IMAP server) can take a great deal of effort and might not necessarily be worth it. Use your own judgement to decide whether you need unit tests in such situations.

Thanks for reading, and be sure to visit here often to read more articles that might be useful.

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.
  • A 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.

Wednesday, August 7, 2013

C: Hello World on Linux

Hello people!

Today I'm going to describe how you go about writing, compiling and executing C code using the Linux command line (also known as shell or terminal).

You will first need to make sure you have the tools necessary to compile C code. In particular you need gcc. You can get it by installing the build-essential package. On a Debian-based Linux distribution such as Ubuntu, you'd use the following command in the terminal:

sudo apt-get install build-essential

...and then, after entering the root password (if necessary), you proceed with the installation:


To actually write the C code, you can use the vi editor. Even better, you can make sure that you have the vim (vi improved) by using the following command:

sudo apt-get install vim

Then use the following command to edit a file called hello.c (it doesn't need to exist yet):

vi hello.c

This opens the vi editor. vi is very powerful but takes a little getting used to. You start off in command mode, and just about any letter you type has a particular meaning. If you press the 'I' key, you go into insert mode, and can type code to your heart's content. Do that, and enter the following code:

#include <stdio.h>

int main(int argc, char ** argv)
{
    printf("Hello world!\n");

    return 0;
}

Over here we're first including the stdio.h library, which allows us to do input/output (I/O) such as outputting text to the terminal. The actual code goes into the main() function, which returns an integer. You can ignore the argc and argv bits, and just use this as a template for your code, for the time being. We actually write something to the terminal using the printf() function. The only thing that might seem a little special here is the \n thing - it's an escape sequence that outputs a newline.


Once you're done typing the above, press ESC in vi to go back to command mode. Then type :wq and press enter - this saves the file (w) and quits (q).

Back in the terminal, type the following command to compile the code in hello.c:

gcc hello.c -o hello

The -o part means that the next argument (in this case "hello") is the name of the executable to be produced by gcc. On Linux, executables don't need to have extensions such as .exe, although it's perfectly fine to include them to make it easier to recognise them.


Finally, type ./hello and press ENTER to run the program. You should see "Hello world!" as the output, as above.

Note: just in case you can't run the program because of some permissions, try the following command:

chmod 777 hello

Great! This simple tutorial showed how to write C code using the vi editor, compile it using the gcc program, and execute it from within a Linux shell. Come back for more tutorials!