Saturday, June 25, 2016

Returning an IEnumerable from a database

This is probably rather obvious, but... when returning an `IEnumerable` from a database, like the records from a table, don't do this:

using (var db = GetDatabase())
  return db.GetTable("Table1");

because it will throw an exception when trying to enumerate those records, since the database connection has already been disposed.

Don't do this either:

using (var db = GetDatabase())
  return db.GetTable("Table1").ToList();

because it will retrieve all records from the table, even if you only need a small subset.

A slightly better way is to do this:

using (var db = GetDatabase())
  foreach (var item in db.GetTable("Table1"))
    yield return item;

This way, the `Dispose` method doesn't get called until the enumeration is over and if you only `Take()` a limited number of records from the result, it won't load the whole table. On the other hand, if you only add `Where()` clauses to the result, it will still enumerate everything (the "where" doesn't get passed on to the database engine).

This is not perfect - it would be best if I could return an IQueryable so that additional filters get passed on to the database engine, but I haven't yet figured out how to do that.

Sunday, June 05, 2016

Aligning text

I needed to write some code in a console app to align what a user was saying, in case it was longer than a line (80 characters):

marcel: blah blah blah a lot of text that doesn't fit in 80 characters more blah
         blah blah
long_username: Contrary to popular belief, Lorem Ipsum is not simply random text
               . It has roots in a piece of classical Latin literature from 45 B
               C, making it over 2000 years old. Richard McClintock, a Latin pro
               fessor at Hampden-Sydney College in Virginia, looked up one of th

I wrote the code in two ways: an imperative, mutating style and a functional (recursive) style. I find the second one to be more elegant but since the entire project is something done as a hobby I don't much care about speed; your mileage might vary. I'm also quite certain the first method can be improved but… again, I don't need to do that so it doesn't get done.

As usual, use at your own risk, I don't care about copyrights, blah, blah. Oh, and the result will look bad if the text contains non-printable characters.

        private static string Align(string prefix, string text, int length = 80)
            Debug.Assert(prefix != null);
            Debug.Assert(text != null);
            Debug.Assert(length > prefix.Length);

            var prefixLength = prefix.Length;

            var sb = new StringBuilder();

                var limit = Math.Min(text.Length, length - prefixLength);

                var current = text.Substring(0, limit);
                sb.Append(prefix + current);

                prefix = new string(' ', prefixLength);
                text = text.Substring(limit);
            } while (text != "");

            return sb.ToString();

        private static string Align2(string prefix, string text, int length = 80)
            Debug.Assert(prefix != null);
            Debug.Assert(text != null);
            Debug.Assert(length > prefix.Length);

            var all = prefix + text;

            return all.Length <= length
                ? all
                : all.Substring(0, length) +
                  Align2(new string(' ', prefix.Length), all.Substring(length), length);

Hmm... I think this would be an interesting exercise if I wanted to hire programmers.

Math is a game

Math is a game, an arbitrary set of symbols and rules. The weird part, the part that always surprises me, is that it's relevant to the real world.

Here's an example: we'll start with just two symbols, Yin and Yang. (Replace those with black and white, circle and square, X and Y… whichever two symbols you prefer.) What can we do with them?

Well, the simplest thing we can do is transform one into the other:

Yin → Yang; Yang → Yin

We'll call this transformation "mirroring" and denote it with the letter "M".

What about combining two symbols? We have a number of possibilities:

A) Yin, Yang → Yin; Yang, Yin → Yin; Yin, Yin → Yin; Yang, Yang → Yin

This is rather boring… no matter what we start with, we obtain an Yin symbol. Nevertheless, let's continue.

B) The opposite of A: Yin, Yang → Yang; Yang, Yin → Yang; Yin, Yin → Yang; Yang, Yang → Yang. Still boring.

C) Yin, Yang → Yin; Yang, Yin → Yin; Yin, Yin → Yin; Yang, Yang → Yang

Ok, so this is a bit more interesting: this combination still overwhelmingly favors the Yin symbol, but at least once in a while we get back an Yang. For completion, we'll also write down its opposite:

D) Yin, Yang → Yang; Yang, Yin → Yang; Yin, Yin → Yang; Yang, Yang → Yin

The last two combinations give us an equal distribution of the results:

E) Yin, Yang → Yin; Yang, Yin → Yin; Yin, Yin → Yang; Yang, Yang → Yang

F) Yin, Yang → Yang; Yang, Yin → Yang; Yin, Yin → Yin; Yang, Yang → Yin

I'll summarize the A..F combinations in a table:

1st 2nd A B C D E F
Yin Yang Yin Yang Yin Yang Yin Yang
Yang Yin Yin Yang Yin Yang Yin Yang
Yin Yin Yin Yang Yin Yang Yang Yin
Yang Yang Yin Yang Yang Yin Yang Yin

So, what was the point of all this? In itself, nothing much. We can imagine that two kids might alternate playing this game, where one of them writes symbols and the other one combines them to obtain the result, and the one with the most correct results wins. It doesn't really matter: the interesting part is that we just re-invented Boolean logic. The Yin and Yang symbols are 0 and 1 (or true and false) and the transformations are the well-known Boolean operators: and, or, xor, equ and finally not for what we called "mirroring" (I've ignored the "boring" A and B). Given that Boolean logic is used by all computers, this is quite amazing - what looked like rather pointless playing with two symbols picked at random proved to be hugely important.

Thursday, June 02, 2016

Parsing INI files

I am trying to allow the end user to modify the application behavior in some limited ways; as such, I have a need of parsing .INI files of the form

[Type 1]

[Type 2]

I looked around for a class / library that would allow me to read these files but I haven't found anything useful (most of the classes I found couldn't handle duplicate keys within the same section). As such, I went ahead and implemented this myself. This algorithm is extremely specific to my usage, you might have to modify it for your needs.

The IniTuple represents each line as a (section, key, value) tuple:

    public class IniTuple
        public string Section { get; private set; }
        public string Key { get; private set; }
        public string Value { get; private set; }

        public IniTuple(string section, string key, string value)
            Section = section;
            Key = key;
            Value = value;

The IniParser class implements the algorithm that transforms a string to a list of IniTuples:

    public class IniParser
        public IEnumerable<IniTuple> Read(string text)
            var lines = text
                .Split('\r', '\n')
                .Where(line => !string.IsNullOrWhiteSpace(line))

            var section = "";
            foreach (var line in lines)
                if (IsNewSection(line))
                    section = line.Substring(1, line.Length - 2);
                    yield return GetTuple(section, line);


        private static string RemoveComment(string line)
            var index = line.IndexOf(';');
            return index < 0 ? line : line.Substring(0, index);

        private static bool IsNewSection(string line)
            return Regex.IsMatch(line, @"^\s*\[[^]]+\]\s*$");

        private static IniTuple GetTuple(string section, string line)
            var index = line.IndexOf('=');
            return index < 0
                ? new IniTuple(section, "", line)
                : new IniTuple(section, line.Substring(0, index), line.Substring(index + 1));

Please let me know if this was useful. As usual, I don't believe in copyrights so feel free to do whatever you want with the code.