Nebula learning

Great Nebula @iStockphoto / angelhell The traditional method of teaching involves introducing students to a new concept, then exhaustively explain everything about that concept before moving to the next concept. This is linear learning. I think of it as depth-first learning, where a topic is studied in detail, sometimes to the point of redundancy.

There’s a huge flaw in linear learning. It’s boring. Different learners have different learning styles. When applying one singular teaching method with an emphasis on giving out as much detail as possible, students are interested up to a certain point in the lesson and then stop. They stop because either they’ve learned enough or got bored with the subject. In any case, they need to apply that knowledge and then move on to something else.

Searching for a more comprehensive learning method
Another learning method is spiral learning, where students touch on a new concept, learn to apply it, move on to a related concept, apply that one and move on to another related concept. The idea is for students to gain a level of mastery in other subjects and acquire greater understanding about previously taught subjects. A concept may be revisited again for a deeper discussion, thus completing a cycle or in this case, a spiral.

I think of spiral learning as breadth-first learning, where many related subjects are covered as much as possible. Spiral learning solves the boredom problem in a linear learning pattern. It too has a flaw, though it’s not obvious.

In an academic setting, the topic of study is often determined by the degree requirements, subject prerequisites, a friend’s recommendation or even a whim of the moment. “Related” subjects are weakly connected to each other, where “weak” refers to the level of personal interest. And this is a weak point of spiral learning. Few people know what they want to learn next, so they follow predetermined guides.

They work better for computers
So linear learning and spiral learning, the former being a depth-first, the latter a breadth-first. They follow two standard search methods, the depth-first search and the breadth-first search. Both try to find a sought after item in the shortest amount time or with the least effort. This works well… for a computer program. Computers need structure, a predetermined system to do their work.

I believe human learning behaviour is radically different. Children learn an extraordinary amount of knowledge about many seemingly disparate subjects quickly. They learn to differentiate colours, ride a bike, do math, sing and dance, speak and read and write, be a friend to someone. They learn about as many subjects as they are interested in. Then school kicks in and institutionalised a learning behaviour for every single child.

What happened when we grow up? We are faced with problems to be solved and there’s not enough time and energy to learn linearly. We don’t even do spiral learning. We pinpoint the problem and we search for an exact answer for that problem.

I see this happening particularly in programming forums, where someone post a question and sought an exact answer to that question. A kind soul answered the question and gave an incomplete code sample, which just needed a little tweaking to get it right for the questioner’s unique situation. Keyword here is “unique”. It’s always better for the person to determine if a solution is usable. Not good enough for the questioner though.

If the questioner had the habit of connecting many different concepts at once, a little thought would have given him the answer. The incomplete code sample would simply act as a nudge in the right direction. The habit however, needs to be formed when we’re younger, and generally speaking freer in our time.

The nebula learning pattern
Humans follow a nebula learning pattern. We form interests, emotions and knowledge of different topics and are therefore proficient at different levels. Our knowledge can be visualised as a nebula where denser clouds represent deeper interest and proficiency. We learn about things with no relation to each other, yet sometimes with almost equal amount of interest and intensity. We touch on topics till bored, then jump to another topic.

In a way, our questioner above is following the same pattern. The question posed was important to him, probably because his job depended on it. That’s why he’s interested in the answer. He probably doesn’t even care about the concepts that led to that answer. He just wants to copy and paste the answer.

We don’t all have to become polymaths, but if we can consciously learn and form nebulae of knowledge, I believe the world will be a better place. We have too many specialists anyway.

Beginning C# – Formatting output

Real math formulae @iStockphoto / pinobarile Many times when we’re busy churning out code and worrying about the accuracy of our calculations, we can forget that ultimately our users are looking at the results. We have to care about how to present those precious calculations so our users can make sense of it.

And it’s appalling that there are programmers who make up algorithms and write custom functions to get those presentation formats, when the programming language often has a perfectly good in-built function for it. We have to become masters of our chosen programming language! We can start with the following code example.

int numberofapples = 7;
short numberoforanges = 16;
byte red, green, blue;
float distanceinmetres = 42769.307f;
decimal priceofcomputer = 2495.95m;

red = 107;
// the following two lines will fail compilation
// because the values are out of [0, 255] range
//green = -34;
//green = 256;
green = 214;
blue = 0x3f; // this is 63

// this pads the number with zeroes on the left until
// there are 5 digits. If the number is already 5 or
// more digits, then the number is simply printed out.
Console.WriteLine(numberofapples.ToString("d5"));
Console.WriteLine(numberoforanges.ToString("d5"));

// in this case, the number is converted into a string,
// then it's padded on the left with spaces (default) until
// there are 5 characters.
Console.WriteLine(numberofapples.ToString().PadLeft(5));
 // this time, we pad with the letter v (instead of spaces)
Console.WriteLine(numberoforanges.ToString().PadLeft(5, 'v'));

// the maximum number of placeholders is 3: {0}, {1} and {2}
// To go beyond 3, you'll have to use this syntax
//Console.WriteLine("{0}, {1}, {2}, {3}, {4}", new object[] { red, green, blue, 8, 13 });
Console.WriteLine("\\nRGB triplet is [{0}, {1}, {2}]", red, green, blue);
Console.WriteLine("In hexadecimal, they're [{0,0:x2}] [{1,0:x4}] [{2,3:x2}]\\n", red, green, blue);

Console.WriteLine("Distance is {0}", distanceinmetres.ToString("f2"));
distanceinmetres = 42769.304f;
Console.WriteLine("New distance is {0}", distanceinmetres.ToString("f2"));
Console.WriteLine("Distance in scientific notation is {0:e}", distanceinmetres);
Console.WriteLine("Scientific notation (2 dec places) is {0:e2}", distanceinmetres);

Console.WriteLine();

Console.WriteLine("Computer price:\\t{0:N}", priceofcomputer);
Console.WriteLine("Or this way:\\t{0:C}", priceofcomputer);
Console.WriteLine();

DateTime timenow = DateTime.Now;
Console.WriteLine(timenow.ToString("dd/MM/yyyy HH:mm:ss"));
Console.WriteLine(timenow.ToString("yyyy-MM-ddTHH:mm:sszzz"));
Console.WriteLine(timenow.ToString("dddd, MM/dd/yyyy"));
Console.WriteLine(timenow.ToString("d MMM yyyy"));
 // for more formats, search MSDN for "Custom DateTime Format Strings"

Console.WriteLine("End of program");
Console.ReadLine();

There’s quite a bit of commenting, so you can follow better while reading the code. It saves a lot of explanation in the post too. There are only a few things I want to point out.

Hexadecimal values
Any integer variable type can be assigned a hexadecimal value instead of plain vanilla numbers. Perhaps the value to be assigned is the result of a binary OR. In this case, hexadecimal values give a clearer idea of how the result is obtained, such as 0xf0 | 0x33 becomes 0xf3.

Hexadecimal values are also used in colour representations, as illustrated in our example code.

Special characters
In the example code, two new characters are introduced: \n and \t. The former is a new line character, and the latter is a tab character. They are also known as escape characters. The backslash \ escapes the normal meaning of the following character. So the “n” is not really printed out.

Automatic rounding
When the float value 42769.307f is printed to 2 decimal places, it’s rounded up to 42769.31. When 42769.304f is printed to 2 decimal places, it’s truncated to 42769.30.

Despite the convenience, I strongly suggest you do not let the computer determine your result. If you want it rounded up, ensure the result yourself.

Thousands separator
Sometimes, when the user deals with numbers in the millions, it’s hard to determine the value of a number such as 43526176849. The user has to count the digit positions to know it’s about 43 billion. This is where using “N” in the format string helps. Commas are used to separate every thousandth digit. Commas are the commonly used separator. If you live in Germany, it’s a period “.”. If you live in Sweden, it’s a space.

The “C” format string is for currency.

Date/Time formats
The combinations for formatting dates and times are the most formidable ones I’ve ever encountered. I am inclined (and due to work requirement) to use the date format used in England, where the day is before the month, like so dd/MM/yyyy.

If you’re working in ASP.NET, I suggest you don’t rely on the culture of the globalisation tag in web.config. There are short cuts for date formatting, such as DateTime.Now.ToString("d") which gives the short date version. I personally find this lacking in descriptive detail. I prefer to manually set the format string. This way, I know what’s gonna come out.

Output
Formatting output screenshot

Homework
Go search MSDN for all the possible format strings, particular those for dates and times. Then play around with the source code. Have fun!

Download source code.

CSS colours and hexadecimal

CSS, which stands for Cascading Style Sheets, allows you to work design wonders with your HTML. A web page is split into two parts, the design and look versus the data and functions of the page. And CSS is the main driving force behind the former. Aaron’s article gives an excellent introduction to this separation of form and function of a web page. Then stroll through the breathtaking CSS Zen Garden to gain inspiration for your CSS design project.

So why do you need to know anything about hexadecimals? Because a major component of CSS values come from declaring colours. And colours are represented in mainly hexadecimal values.

In CSS, colours are commonly represented as RGB triplets, such as #336699. RGB is a short form of Red, Green and Blue. A discussion of colour theory and representation is beyond the scope of this article. Simply know the six characters (not including the hex sign #) is divided into 3 parts. First two characters represent red, middle two for green and last two for blue.

These two-character parts are the hexadecimal values of the colour component (red or green or blue), and range from 0 to 255. The higher the number, the more of that colour component. So #0000ff represents pure blue. If it’s still new to you, rest easy, because most standard image processing software has a hexadecimal colour converter.

There are other ways of declaring colours in style sheets, such as color:Red. To a non-technical person, that is very useful. But we’re programmers. What if we need to dynamically generate the style sheet?

Learn 5 non-programming stuff

Ok, so you’ve been banging on the keyboards for entire day, spewing out tons of flawless code. Now you’re beat. You swear that if you see any line of code, you’re gonna puke. So I’m going to offer you something different. In fact, five something differents.

Beginning C# – Arrays and iterations

Numbered mailboxes @iStockphoto / Eliza Snow So you’ve learnt a bit about variables such as ints and floats. What happens if you need, say a bunch of integer variables with similar purposes? For example, ten decimal variables to store prices. This is where arrays come in.

One and two dimensional arraysArrays offer a simple syntax to declare a series of variables of the same type with minimum work. Think of arrays as boxes in sequential order, where the boxes can only hold a certain type of item.

When someone uses the term “array”, the person usually means a one-dimensional array. What’s the difference? Imagine you have a series of boxes. That’s a one-dimensional array. Then imagine each of those boxes is the start of another series of boxes. That’s a two-dimensional array. You can even go on to three-dimensional arrays, where you stack two-dimensional arrays on top of each other.

Alright then, how do you use them? Here comes the source code.

            const int numberofelements = 10;
            double[] multiplesofpi = new double[numberofelements];
            int i;

            for (i = 0; i < numberofelements; ++i)
            {
                // The result of an operation between two numbers has
                // the precision of the number with the higher precision.
                // Math.PI is a double, which has a higher precision than
                // i, an integer. So the result of i * Math.PI is a
                // double.
                multiplesofpi[i] = i * Math.PI;
            }

            // reverse the for loop
            for (i = numberofelements - 1; i >= 0; ----i)
            {
                Console.WriteLine("Box {0} has {1}", i, multiplesofpi[i]);
            }

            Console.WriteLine("End of program");
            Console.ReadLine();

So we declare an array of doubles named multiplesofpi. Note the square brackets after the double. This line

            double[] multiplesofpi = new double[numberofelements];

just tells the compiler that we want an array of doubles. The new keyword simply tells the compiler to create a new array of doubles, with “numberofelements” number of doubles bunched together. Remember the const keyword we learnt?

            for (i = 0; i < numberofelements; ++i)
            {
                // The result of an operation between two numbers has
                // the precision of the number with the higher precision.
                // Math.PI is a double, which has a higher precision than
                // i, an integer. So the result of i * Math.PI is a
                // double.
                multiplesofpi[i] = i * Math.PI;
            }

In the for loop, we assign each element of the array with a value. Each array element can be accessed using an index, which in our case is the variable i.

There are 10 iterations in this case. An iteration refers to an instance of something being done repetitively, such as in a for loop, or while loop. In each iteration, we multiply the number of the iteration by the value of PI, which is about 3.14159. The Math library provided by .NET already contains the constant value of PI, so we’ll just use that.

It takes some getting used to, but computers really like counting from zero. We humans start counting from 1, and for a long time, cannot grasp the idea of nothingness. Computers however, have no problems with zero. Maybe they’re more advanced than us humans…

Anyway, we then practise reversing the for loop with

            // reverse the for loop
            for (i = numberofelements - 1; i >= 0; ----i)
            {
                Console.WriteLine("Box {0} has {1}", i, multiplesofpi[i]);
            }

This is important, because there will come a time in your programming life where going backwards and forwards in a sequential manner is critical. Besides, it trains your mind to think differently, and that’s great by itself.

Homework
Write the first for loop in reverse manner. Then try writing the second for loop in forward manner. Convince yourself that the array will contain the same values, regardless of whether the for loop is in forward manner or reverse manner.

Download the source code.