This and That

Dear Future Jamie:

DI with a private constructor

When you are doing DI with a private constructor, this syntax will not work:

            String animalTypeName = ConfigurationManager.AppSettings["animalTypeName"].ToString();
            Type animalType = Type.GetType(animalTypeName);
            IAnimal animal = (IAnimal)Activator.CreateInstance(animalType);

Instead use this syntax:

            String animalTypeName = ConfigurationManager.AppSettings["animalTypeName"].ToString();
            Type animalType = Type.GetType(animalTypeName);
            IAnimal animal = (IAnimal)FormatterServices.GetUninitializedObject(animalType);

Params Keyword

When you have a series of overloaded methods that are taking on an ever-growing number of parameters, consider using the params keyword.  For example, instead of this:

        public void NameMe(String FirstName)
        {

        }

        public void NameMe(String FirstName, String LastName)
        {

        }

        public void NameMe(String FirstName, String MiddleName, String LastName)
        {

        }

Do this:

        public void NameMe(params String[] parameters)
        {

        }

Love Current Jamie

RDU Code Camp

TriNug put on an awesome codecamp over the weekend.  I presented programming the Kinect.  There was about 20 people in my session (more than I expected) and we had a great time going through some of the basic (and way cool) features of the Kinect API.  I hope to see some really neat projects at future TriNug events using the Kinect.

My side deck and code samples are on TriNug’s wiki found here.

Proper Casing Of Proper Names

I was consuming an external API that was returning people’s first names.  The problem was that the names were coming back all caps (eg: “GILLIGAN”).  I wanted to convert that into the proper case (eg: “Gillian”).  In the past, I would call ToLower() of the string and then take the first character of a substring and make it Upper().  To protect myself in case there was several words in the name(eg: MARY ANN), I would also need to split on any spaces and loop through the array doing my Upper/Lower functions.  The code would look something like this:

static void WrongWay(String name)
{
    String tempWord = String.Empty;
    String firstLetter = String.Empty;
    String restOfWord = String.Empty;
    StringBuilder stringBuilder = new StringBuilder();

    String[] splitName = name.Split(' ');
    foreach (String word in splitName)
    {
        tempWord = word.ToLower();
        firstLetter = tempWord.Substring(0, 1);
        firstLetter = firstLetter.ToUpper();
        restOfWord = tempWord.Substring(1, tempWord.Length-1);
        stringBuilder.Append(firstLetter);
        stringBuilder.Append(restOfWord);
    }
    Console.WriteLine(String.Format("Was = {0} Now = {1}", name, stringBuilder.ToString()));
}

And the output looks like this:

image

I hate this solution for a couple of reasons:

  • It smells like Kludgy code
  • It is Kludgy code
  • It does not account for people with single letter names
  • It does not account for internationalism and different languages that use different glyphs

I thought to myself – there must be a better way and since Microsoft has lots of smart people, they might have done something like this already.

My first stop was the String.ToLower() overload.  I pumped in the different cultures (Current and CurrentUI):

static void WriteNames(String name)
{
    CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture;
    CultureInfo currentUICulture = Thread.CurrentThread.CurrentUICulture;

    Console.WriteLine(String.Format("ToLower = {0}",name.ToLower()));
    Console.WriteLine(String.Format("ToUpperWithCurrentCulture = {0}", name.ToLower(currentCulture)));
    Console.WriteLine(String.Format("ToUpperWithCurrentUICulture = {0}", name.ToLower(currentUICulture)));
}

Alas, it did not work:

image

ToUpper() had the same (non) effect.

I then thought “Hey, maybe I should check MSDN or Stackoverflow”.  Sure enough, I ran into this page.  Without reading the entire page (who does that?)  I jammed in this line of code,

Console.WriteLine(String.Format("currentCulture.TextInfo.ToTitleCase using Upper = {0}", 
    currentCulture.TextInfo.ToTitleCase(name)));

but I got the same result:

image

 

I then went back and read the entire MSDN page.  I changed my code to this (note the ToLower())

Console.WriteLine(String.Format("currentCulture.TextInfo.ToTitleCase using Lower = {0}",
    currentCulture.TextInfo.ToTitleCase(name.ToLower())));

Sure enough:

image

Not only that, it works for multiple words:

image

Not only that, it handles middle initials!

image

Alas, it does not handle suffixes:

image

Still, that function gives you plenty out of the box.  I am very excited (OK, mildly excited) about this new find….

Signature Capture

I was chatting with another member of TriNug last night and we talked about the best way to capture a user’s signature.  There are some pretty good articles out there, including this one.  I dove right in with a WinForm application and a Panel control and built something like this:

image

 

Visual Studio 2010 and WinForms made this a pretty straightforward task.  First, I built up my domain model starting with the points that are captured from the Panel.MouseMove event handler (MouseEventArgs) with the e.Location of type Point.

I created a Line class that has 2 points that make up the line:

[Serializable]
public class Line
{
    public Line()
    {

    }

    public Line(Point startPoint, Point endPoint)
    {
        this.StartPoint = startPoint;
        this.EndPoint = endPoint;
    }

    public Point StartPoint { get; set; }
    public Point EndPoint { get; set; }
}

I then created a Glyph class that is a collection of those lines:

[Serializable]
public class Glyph
{
    public Glyph()
    {
        this.Lines = new List<Line>();
    }
    public List<Line> Lines { get; set; }
}

I could have called this class “letter” but each glyph may or may not be a letter – it could be several letters strung together in cursive, a part of a letter (the dot of the i), or may not be any letter (like when R2D2 signs his name.  R2D2 is a boy, right?)

Anyway, I then created a Signature class that is a collection of glyphs:

[Serializable]
public class Signature
{
    public Signature()
    {
        this.Glyphs = new List<Glyph>();
    }

    public List<Glyph> Glyphs { get; set; }
}

If this was used in a real-world application, this class would have a uniqueId so you can relate it back to your people/user class.  It might have some other properties to allow easy comparison and analysis.

I then coded in my WinForm a way to capture the user’s mouse strokes and putting them into this signature graph.  First, I started with some form level variables:

Boolean IsCapturing = false;
private Point startPoint;
private Point endPoint;
Pen pen = new Pen(Color.Black);
Glyph glyph = null;
Signature signature = new Signature();
String fileName = @"signature.xml";

I then handled three events from the panel:

private void SignaturePanel_MouseMove(object sender, MouseEventArgs e)
{
    if (IsCapturing)
    {
        if (startPoint.IsEmpty && endPoint.IsEmpty)
        {
            endPoint = e.Location;
        }
        else
        {
            startPoint = endPoint;
            endPoint = e.Location;
            Line line = new Line(startPoint, endPoint);
            glyph.Lines.Add(line);
            DrawLine(line);
        }

    }
}
private void SignaturePanel_MouseUp(object sender, MouseEventArgs e)
{
    IsCapturing = false;
    signature.Glyphs.Add(glyph);
    startPoint = new Point();
    endPoint = new Point();

}

private void SignaturePanel_MouseDown(object sender, MouseEventArgs e)
{
    IsCapturing = true;
    glyph = new Glyph();
}

Basically, every time a user clicks down it starts capturing the points and turning them into lines.  When the user clicks up, all of those lines go into 1 glyph.  Capture…Rinse….Repeat.

There is 1 supporting function (DrawLine) that looks like this to render it to the screen:

private void DrawLine(Line line)
{
    using (Graphics graphic = this.SignaturePanel.CreateGraphics())
    {
        graphic.DrawLine(pen, line.StartPoint, line.EndPoint);
    }
}

A couple of notes on the code blocks above.

  • The Point struct has a convenience property called IsEmpty.  This resolves to X and Y equaling 0.
  • The Point Equals overload resolved to the X and Y values.   If you have 2 instances of a Point with the same X and Y, they are equal.

Once the signature is captured on the panel, I needed a way to save the signature.  Most people capture the image.  Me, I want the signature transformed into structured data for better down-steam analysis.  Therefore, I decided to put it into XML.  To that end, I marked all of the classes in the Signature graph as Serializable.  I then created two functions to push and pull the signature out of a XML file:

private void SerializeSignature()
{
    XmlSerializer serializer = new XmlSerializer(typeof(Signature));

    if (File.Exists(fileName))
    {
        File.Delete(fileName);
    }

    using (TextWriter textWriter = new StreamWriter(fileName))
    {
        serializer.Serialize(textWriter, signature);
        textWriter.Close();
    }
}

And

private void DeserializeSignature()
{
    XmlSerializer deserializer = new XmlSerializer(typeof(Signature));
    using (TextReader textReader = new StreamReader(fileName))
    {
        signature = (Signature)deserializer.Deserialize(textReader);
        textReader.Close();
    }
}

I then wired up the button clicks to save the signature:

private void ExportButton_Click(object sender, EventArgs e)
{
    SerializeSignature();
}

and to load it:

private void ImportButton_Click(object sender, EventArgs e)
{
    DeserializeSignature();
    ClearSignaturePanel();
    DrawSignature();

}

and these are the two other supporting methods:

private void ClearSignaturePanel()
{
    using (Graphics graphic = this.SignaturePanel.CreateGraphics())
    {
        SolidBrush solidBrush = new SolidBrush(Color.LightBlue);
        graphic.FillRectangle(solidBrush, 0, 0, SignaturePanel.Width, SignaturePanel.Height);
    }
    
}

and

private void DrawSignature()
{
    foreach (Glyph glyph in signature.Glyphs)
    {
        foreach (Line line in glyph.Lines)
        {
            DrawLine(line);
        }
    }

}

Sure enough, here is the XML in the file:

image

The problem is that this file is larger than a image file – but much more analyzable (and yes, that is a real word).  I then wanted to display the signature in a web browser.  To that end, I fired up a classic ASP.NET application and created a web control.  In the code, I rendered the points out of the XML file back into a graphic:

protected void Page_Load(object sender, EventArgs e)
{
    this.Response.ContentType = "image/gif";
    using (Bitmap bitmap = new Bitmap(200, 100))
    {
        using (Graphics graphics = Graphics.FromImage(bitmap))
        {
            SignatureFactory signatureFactory = new SignatureFactory();
            String fileName = @"C:\signature.xml";
            Signature signature = signatureFactory.LoadSignatureFromFileSystem(fileName);
            Pen pen = new Pen(Color.Red);
            foreach (Glyph glyph in signature.Glyphs)
            {
                foreach (Line line in glyph.Lines)
                {
                    graphics.DrawLine(pen, line.StartPoint.X, line.StartPoint.Y,
                        line.EndPoint.X, line.EndPoint.Y);
                }
            }

            bitmap.Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Gif);
        }
    }
}

And the output on a web form:

image

Town Of Cary Information Technology Board

 

Not much sharable code this week.  I did get appointed to the Town Of Cary’s Information Technology Board:

image

RDU Code Camp Material

All of the material that I presented last Saturday at Trinug’s code camp is available here.

Removing something from a collection

Consider the following snippet:

//Remove all hexes that have a unit in them for (int i = 0; i < returnValue.Count; i++ ) { if (returnValue[i].CurrentUnit != null) { returnValue.RemoveAt(i); } } return returnValue;

This does not work.  For example, here is a screen shot:

image

The reason why is that the indexer is evaluated once,, but the list changes after each iteration.  In graphical terms:

0

1

2

3

4

5

X

X

0

1

2

3

4

X

 

 

Index 1 becomes Index 0, and since the loop is already on 1, it gets skipped for evaluation. What we need it to remove a hex and then keep looping – so the while construct needs to be used:

bool keepLooping = true; while (keepLooping == true) { int totalHexes = returnValue.Count; for (int i = 0; i < returnValue.Count; i++) { if (returnValue[i].CurrentUnit != null) returnValue.RemoveAt(i); if (totalHexes == returnValue.Count) keepLooping = false; } }

 

And the results work as expected:

image

On Line Source Control

I have received some requests for the source code/project of the examples that I have been showing on this blog. Here to fore, I have been zipping up the solution and email the requestor. I thought I could take it up a level by using some of the services that are available on the internet. I checked out github, codeplex, googlecode, and assembla. I had 3 basic criteria – can I restrict the project to people I want, can I use TFS (I am a Microsoft dev after all) and is it free? Here is what I found:

Site

TFS?

Restrict Users

Free?

github

N

N (for free)

Y

codeplex

Y

N

Y

googlecode

N

Y

Y

assembla

N

Y

N

Rob Seder then suggested that I just upload the zipped up projects that I want into the blog using LiveWriter. <Sound of me slapping my forehead>Doh! </Sound of me slapping my forehead>.  Finally, for basic file sharing, I can always use SkyDrive…

I’ll go back and do that for the posts that people have emailed me about and perhaps in the future…

TSQL ‘IN’ Equivalent in LINQ

I needed to create an ‘in’ query in LINQ.  After searching around a bit, I came across this post.  Very handy:

var q = from l in context.RoadAlert_Location join at in alertTypeIds on l.AlertTypeId equals at select l; foreach (RoadAlert_Location location in q) { locations.Add(MapLocation(location)); }

Old English NLP

I started working through the SharpNLP library as referenced in my last blog post. To recap, the SharpNLP library depends on some source binaries from the SharpEntropy library which depend on sonce data files that have to be placed in a specific location on your file system.

I cracked open the SharpNLP with reflector and took a spin through the more commonly used methods. It looks like you deal with strings and a couple of classes called “chunk” and “word” that have a couple of supporting enumerations.

With the library, you can split paragraphs into sentences, sentences into words, sentences into phrases (what they call chunks), and then identify each word and/or phrase with its part of speech. These functions seem perfect for my Old English translator.

Here is an example of a basic console application with the parser output.

public class Program { static void Main(string[] args) { Console.WriteLine("--Start--"); string testSentence = "A quick brown dog jumped over a lazy cat."; Parse parse = ParseSentence(testSentence); PrintParse(parse); Console.WriteLine("---End---"); Console.ReadLine(); } private static Parse ParseSentence(string sentence) { string path = @"C:\ProgramData\OpenNLP\Models\\"; EnglishTreebankParser parser = new EnglishTreebankParser(path, true, false); return parser.DoParse(sentence); } private static void PrintParse(Parse parse) { Parse rootNode = parse.GetChildren()[0]; Parse[] parses = rootNode.GetChildren(); foreach (Parse currentParse in parses) { Console.WriteLine(String.Format("{0} : {1}", currentParse.ToString(), currentParse.Type)); } } }

image

 

I then wanted to change the order from S-V-O to S-O-V or O-S-V. In this example, the output should be “A quick brown dog over a lazy cat jumped.” or even “Over a lazy cat a quick brown dog jumped.”

Looking at the output, the VP needs to be broken down even further. I changed the PrintParse to handle the children (using recursion):

private static void PrintParse(Parse parse) { Parse[] parses = parse.GetChildren(); foreach (Parse currentParse in parses) { Console.WriteLine(String.Format("{0} : {1}", currentParse.ToString(), currentParse.Type)); PrintParse(currentParse); } }

The output is now:

image

Things looks better – except I can’t figure out what the “TK” is – it is duplicating each word and it is not a part of speech (at least according to the WordType enum)…

Removing the TK, I get this (I dropped the Console window and went to the Output window) :

A quick brown dog jumped over a lazy cat . : S

A quick brown dog : NP

A : DT

quick : JJ

brown : JJ

dog : NN

jumped over a lazy cat : VP

jumped : VBD

over a lazy cat : PP

over : IN

a lazy cat : NP

a : DT

lazy : JJ

cat : NN

. : .

So to take a sentence and take it from S-V-O to O-S-V, I need to map the parsing word types to either a S,V,or O. In this example:

  • NP = S
  • VBD = V
  • PP=O

I can then rearrange the words into Old English. The challenge is that the word types are not context-free – the 1st NP that is in the sentence (“A quick brown dog”)is the Subject, but the second NP (“a lazy cat”) is the object – the PP is for the prepositional phrase. So the 1st NP that is encountered is the subject and the second NP is ignored if it is in a PP, but if it is alone (“A quick brown dog jumped a lazy cat”), then it becomes the object. I can build a table with the different patterns – at least the common ones, and leave it at that. Here is an example of the function (yes, I know this is procedural code at its worst, I’ll refactor once I have all of my thoughts down)

private static void AssignOldEnglishOrder(List<Phrase> phrases) { int nounCount = 0; int verbCount = 0; int objectCount = 0; foreach (Phrase phrase in phrases) { switch (phrase.ParseType) { case "NP": if (nounCount == 0) { phrase.SentenceSection = "S"; } else if (nounCount == 1) { phrase.SentenceSection = "O"; } else { phrase.SentenceSection = "Z"; } nounCount++; break; case "VBD": if (verbCount == 0) { phrase.SentenceSection = "V"; } else { phrase.SentenceSection = "Z"; } verbCount++; break; case "PP": if (objectCount == 0) { phrase.SentenceSection = "O"; } else { phrase.SentenceSection = "Z"; } objectCount++; break; default: break; } } }

I then whipped up a function that spits out the phrase in Old-English:

private static void PrintPhrases(List<Phrase> phrases) { StringBuilder stringBuilder = new StringBuilder(); foreach (Phrase phrase in phrases) { switch (phrase.SentenceSection) { case "O": stringBuilder.Insert(0, phrase.Text); break; case "S": if (stringBuilder.Length > 1) stringBuilder.Insert(1, phrase.Text); else stringBuilder.Append(phrase.Text); break; case "V": stringBuilder.Append(phrase.Text); break; case "Z": break; default: stringBuilder.Append(phrase.Text); break; } } Debug.WriteLine(stringBuilder.ToString()); }

And the output looks like this:

over a lazy catA quick brown dogjumped

My next steps are:

  • Spacing between words
  • Sentences formatted correctly (all lower case until final output)
  • Find..Replace key words for Old English
  • More patterns to match O-S-V from a variety of input sentences
  • Handle the apostrophe (Don’t comes down as [Don] ‘[t] from the parser)
  • Refactor using Unit tests to better patterns (strategy seems appropriate here)
  • Stick into a WCF service
  • Probably a bunch more stuff that I haven’t thought of

That’s it. I’ll pick it up more later.