Saturday, December 8, 2007

Colorblindness FAQ

Hello,
as I am colorblind I would like to provide a kind of FAQ about colorblindness and how it "influences" my everyday life. First of all I would like to give you some background knowledge. The correct term for my type of colorblindness is red-green color vision deficiency which basically means that I have the biggest problems in differentiating these two colors. There also exists the yellow-blue color vision deficiency which is the same as the red-green one only with different colors but I think the red-green color vision deficiency is the most frequent one. The “heaviest” kind of colorblindness is the total colorblindness which basically means that you don’t see any colors; everything is black-white and gray.

People should keep one thing in mind:
I am colorblind but not stupid ;-)
This is my answer if someone wants to trick me with some colors...

The first question people ask when they notice that I am colorblind is:
Q1: What do you do at the traffic light??
A1: The traffic light is not a problem for me because the red light is at the top and the green light is at the bottom (at least in Italy) and the red light is sometimes slightly bigger than the green one as you can see in the figure below.


Q2: But what if the traffic lights are horizontal??
A2: unfortunately the position of the lights of a horizontal traffic light differs from country to country as the pictures below show.

So it is not that easy. But the horizontal traffic lights are not a problem for me because the contrast between the green and the red light is quite big and therefore I am able to distinguish them despite I have to be careful.
A difficult situation for me is if I drive at night and I see a traffic light from far. I see if it is green but I am not able to distinguish if it is orange or red; because I don’t see the position of the lights. But also that is no problem because I simply stop at the traffic light if it is orange or red .

Q3: Is it curable or does there exist eyeglasses which removes it?
A3: No, this “disease” or deficiency is inborn and can not be healed; there also not exists an eyeglass which removes it.

Q4: Where does it come from? Who can get it?
A4: Simply told: the color vision deficiency resides on the X chromosome. This means that if man has the defect X chromosome he is colorblind. If a woman has the defect X chromosome then he is not colorblind because the healthy X chromosome is used. If it is the case that both X chromosomes of a woman are defect then also a woman can be colorblind but as far as I know there are only very few cases on the world. The other thing is that women are the carriers for defect chromosome. This means I (as man who is colorblind) have a daughter and she has a son then the probability that the son is colorblind is very high. My direct sons are not affected.
The picture below shows how the defect X chromosome is carried. If you want more details about the backgrounds of colorblindness please refer the Wikipedia entry.


Q5: How do you buy your clothes?
A5: If I go in a store and have to buy new clothes I simply take the colors which I like. It may be the case that I don’t exactly know which color it is but I can say if I like it or not. Sometimes maybe I wear a sweater and trousers which do not fit in terms of color but I think there are worse things. And after all now I have my girlfriend which gives me tips which combinations I can wear.

Q6: How did you realize that you are colorblind?
A6: This is a nice little story. In the elementary school I had to draw a crib and therefore I drew a barn with Josef, Maria and Jesus and then I colored the barn in dark green. As I showed this picture to my teacher she was horrified and asked my why I colored the barn in this color and then we (my mother and I) realized that I and also my brother are colorblind.

Q7: How does it influence your everyday life?
A7: I can say that in my everyday life I am not that restricted as other deficiencies may do and if I don’t tell people that I am colorblind or if there is a situation where I have to identify and tell a color no one would notice it.
Another point is that if the colors are in “clean” form which means that they are not mixed then normally I can differentiate them. The biggest problems I have with the color pairs red and green, dark-green and light-brown, shocking-pink and light-blue and finally violet and blue. This color pairs look very similar to me and in most cases I am not able to distinguish them.
One of the biggest problems that I have is with the sign that a roadman has to regularize the traffic. This sign is on one side red and on the other side green as shown in the figure below.

If I see both of them side by side, as in the figure above, I can say which is green one and which the red one, but if I see only one side (which is the case on the street) I am not able to tell which one the roadman is showing me. For this problem I have two approaches:
The first one is that I simply do what the car before me does 
The other one is if no other car is before me I simply slow down in front of the roadman and if he is showing the green one he will beckon with the sign and I know that I can go.

Another “horror” for me is the color field which is used in different software programs. The figure below shows such a color field.

For example I am not able to tell if the highlighted color is light green, yellow or light orange. It could be everyone of this three. Fortunately some color fields provide the name of the color which is hovered with the mouse because otherwise I would be completely lost.
The figure below shows how a colorblind person sees the world to give you an idea. If I look at the pictures and compare them I see almost no differences. Sometimes one color is on one side a little bit darker or lighter but otherwise I don’t see any difference.


If you are curious and you would like to know if you have also color vision deficiencies I suggest you to have a look at this online test of the Kings College of London.

If you have additional questions or you would like to tell your own experiences about colorblindness you are welcome to leave a comment.

Monday, November 26, 2007

C# unit testing helper

As I am writing some unit tests for a C# application I found myself filling the attributes of the objects with meaningful values. With objects having 26 attributes this can be a very frustrating task and especially if you have to do it twice because you want to test the "add" and the "update" method. The other problem that I had was that I need to compare the values of all attributes of two "user" objects which again is a long task with many attributes. I decided therefore to take advantage of Reflection and letting the computer to do this nasty work.

Possible Solution:
I created a class called "TestHelper" which contains static methods that do exactly this work for me :-). One method fills the public, non inherited properties with random values; except for properties which name ends in "id" and properties which name is "pk". This behaviour is adjusted to my needs but can easyily be changed. The other method takes two objects as input and compares each value of their properties if the objects are of the same type; it returns true if the two objects are "equal". For the compare operations I took some code from Steve Lautenschlager (his code can be found here) and Jonas John (his code can be found here). I needed to mix this two versions because in Johns "RandomHelper" there was missing a method to generate random DateTime objects. The random fill method fills the properties according to their type as follows:
  • DateTime: it puts a random date between now and 3000-01-01
  • String: it puts the name of the property plus a random string of uppercase letters of lenght 50
  • Int, long, Int32, Int64: if they are not ids or pks a random number between 0 and 999999 is set
  • Bool: a random boolean value is created
This behaviour can be easily changed to match your specific needs!

The compare method has some small disadvantage when working with DateTime objects and databases. My problem was that if in the database there was only Time datatype and it was then stored inside a DateTime object it has differed in the last 5 or 6 numbers of the Ticks number. This forced me to make this additional check but it can easily be removed and adopted to other needs.

Here is the code of the TestHelper and the RandomHelper classes:
public class TestHelper
{
/* This method can be used to fill all public properties of an object with random values depending on their type.
CAUTION: it does not fill attributes that end with 'ID' or attributes which are called 'pk'. They have to be filled manually.*/
public static object FillAttributesWithRandomValues(object obj)
{
Type type = obj.GetType();
PropertyInfo[] infos = type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);

foreach (PropertyInfo info in infos)
{
Type infoType = info.PropertyType;
if (infoType.Equals(typeof(DateTime)))
info.SetValue(obj, RandomHelper.RandomDateTime(DateTime.Now, new DateTime(3000, 01, 01)), null);
else if (infoType.Equals(typeof(String)))
info.SetValue(obj, info.Name + " " + RandomHelper.RandomString(50, false), null);
else if ((infoType.Equals(typeof(long)) || infoType.Equals(typeof(Int32)) || infoType.Equals(typeof(Int64)) || infoType.Equals(typeof(int))) && !info.Name.ToLower().EndsWith("id") && !info.Name.ToLower().Equals("pk"))
info.SetValue(obj, RandomHelper.RandomNumber(0, 999999), null);
else if (infoType.Equals(typeof(bool)))
info.SetValue(obj, RandomHelper.RandomBool(), null);
else if (infoType.Equals(typeof(Color)))
info.SetValue(obj, RandomHelper.RandomColor(), null);
}
return obj;
}

/* This method takes as input two objects and compares the properties of them.
It returns true if all the public properties of the objects (not inherited ones) are equal.*/
public static bool CompareObjectAttributes(object firstObject, object secondObject)
{
Type t1 = firstObject.GetType();
Type t2 = secondObject.GetType();
/*the two objects must have the same type*/
if (!t1.Equals(t2)) return false;

PropertyInfo[] infos1 =
t1.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
PropertyInfo[] infos2 =
t2.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
for (int i = 0; i < infos1.Length; i++)
{
/*this if is needed because if it is a datetime it should compare only the date and the time and not the ticks*/
if (infos1[i].PropertyType.Equals(typeof(DateTime)))
{
DateTime firstDate = (DateTime)infos1[i].GetValue(firstObject, null);
DateTime secondDate = (DateTime)infos2[i].GetValue(secondObject, null);
/*if the datatype in the database was date then only compare the date part of the datetime object*/
if (firstDate.ToString().Contains("00:00:00") || secondDate.ToString().Contains("00:00:00"))
{
if (!firstDate.Date.ToString().Equals(secondDate.Date.ToString())) return false;
}
/*otherwise compare the string representation of the two datetime objects because the ticks may differ*/
else
{
if (!firstDate.ToString().Equals(secondDate.ToString()))
return false;
}
}
else
{
/*if one property value differs return false*/
if (!(infos1[i].GetValue(firstObject, null)).Equals(infos2[i].GetValue(secondObject, null)))
return false;
}
}

/*when everything went fine the objects have the same values for their properties*/
return true;
}


/* Helper class for generating random values*/
public static class RandomHelper
{
private static Random randomSeed = new Random();

/* Generates a random string with the given length*/
public static string RandomString(int size, bool lowerCase)
{
/* StringBuilder is faster than using strings (+=)*/
StringBuilder RandStr = new StringBuilder(size);

/* Ascii start position (65 = A / 97 = a)*/
int Start = (lowerCase) ? 97 : 65;

/* Add random chars*/
for (int i = 0; i < size; i++)
RandStr.Append((char)(26 * randomSeed.NextDouble() + Start));

return RandStr.ToString();
}

/* Returns a random number.*/
public static int RandomNumber(int Minimal, int Maximal)
{
return randomSeed.Next(Minimal, Maximal);
}

/* Returns a random boolean value*/
public static bool RandomBool()
{
return (randomSeed.NextDouble() > 0.5);
}

/* Returns a random color*/
public static System.Drawing.Color RandomColor()
{
return System.Drawing.Color.FromArgb(
randomSeed.Next(256),
randomSeed.Next(256),
randomSeed.Next(256)
);
}

/* Returns DateTime in the range [min, max)*/
public static DateTime RandomDateTime(DateTime min, DateTime max)
{
if (max <= min)
{
string message = "Max must be greater than min.";
throw new ArgumentException(message);
}
long minTicks = min.Ticks;
long maxTicks = max.Ticks;
double rn = (Convert.ToDouble(maxTicks)
- Convert.ToDouble(minTicks)) * randomSeed.NextDouble()
+ Convert.ToDouble(minTicks);
return new DateTime(Convert.ToInt64(rn));
}
}
}


UPDATE:
This is some very simple code on how to use the UnitTestHelper. It is a very simple Console application. To use it in your unit tests adapt it to Your needs since the creation of Unit Tests is not the topic of this post.
class Program
{
static void Main(string[] args)
{
Person person = new Person();
TestHelper.FillAttributesWithRandomValues(person);

Console.WriteLine("Object with random values:");
Console.WriteLine(string.Format("name = {0}", person.Name));
Console.WriteLine(string.Format("age = {0}", person.Age));
Console.WriteLine(string.Format("tshirtcolor = {0}", person.TShirtColor));
Console.WriteLine(string.Format("birthdate = {0}", person.BirthDate));

Person p1 = new Person
{
Name = "John",
Age = 30,
BirthDate = new DateTime(2000, 10, 19),
TShirtColor = Color.Blue
};

Person p2 = new Person
{
Name = "John",
Age = 30,
BirthDate = new DateTime(2000, 10, 19),
TShirtColor = Color.Blue
};

Person p3 = new Person
{
Name = "Obama",
Age = 30,
BirthDate = new DateTime(2000, 10, 19),
TShirtColor = Color.Blue
};

Console.WriteLine("\nPerson 1 equals Person 2 = " + TestHelper.CompareObjectAttributes(p1, p2));
Console.WriteLine("\nPerson 2 equals Person 3 = " + TestHelper.CompareObjectAttributes(p2, p3));
Console.ReadLine();
}
}


This prints out the following (note that the values may differ on your machine since it are random values):
Object with random values:
name = Name BLHTVGYVHYZVQUJTIPXAWHKMCQLGGYHZMGEBZCXGBDYJCZBMGR
age = 32895
tshirtcolor = Color [A=255, R=32, G=148, B=35]
birthdate = 17.07.2065 15:52:02

Person 1 equals Person 2 = True

Person 2 equals Person 3 = False

Friday, November 23, 2007

Team Viewer

See also my new post about Team Viewer!
As I am frequently asked by kith and kin for helping them with their computer "problems" I was since a long time looking for a good tool to resolve such small software problems over the internet. First I thought that maybe ThighVNC might be the solution but the problem there was that it is difficult or impossible to establish a connection through firewalls and routers (maybe there is a way but I was not able to do it). A day when I surfed around I found this tool which aims to "give your desktop wings". I read some comments about the programm and almost everywhere people said that this tool is the simplest remote desktop tool available and, the most important thing, it works through firewalls and routers. The best news is that there is a free version available which according to a member of TeamViewer does not lack any feature compared to commercial versions.

About the usage:
Both parties have to install the software. The application provides for this an invitation e-mail which can be sent to the other person with the download link for the tool. After the successful installation both have to start the tool and the person who sits in front of the computer which is going to be remotely controlled tells the other person the ID and the password. The person who is going to access the desktop of the other computer enters the provided data and a secure connection is established. After that you can work with the other computer as if you were sitting in front of it.
Another possibility is to install the tool as a windows service and use a predefined password which basically "eliminates" the need of someone sitting in front of the remote computer. For the ID I noticed during my tests that it is always the same for a computer so this is no problem.
TeamViewer provides additionally a chat which unfortunately has a small bug. Every time when you are typing and the other person sends you a message the cursor of the chat is set to the first position and if you don't see it you write there. This is not very handy and this bug is already known to the TeamViewer crew and will be fixed soon. Additionally it provides a tool to send files and folders but I did not try it out.

Summary:
I can only suggest this tool for people who need frequently to help other persons with computer problems or also for other purposes requiring a remote access to a computer. As the TeamViewer crew told me there are no time limitations for the usage of the tool.

Related links:
TeamViewer Homepage

Thursday, November 22, 2007

Set ComboBox value member

Problem:
The problem was to have assign and later read the value member of a combo box. Because this can be useful to store the primary key or id of the related object in order to get it fast.

UPDATE: see also my latest post which deals with this issue!

Possible Solution1:
To assign these values a data source is needed which can be a list of any type. To make it simpler and useful I created a class which holds the value to display and the value of the value
member.
public class ComboBoxItem
{
private string display;
private long value;

public ComboBoxItem(string display, string value)
{
this.display = display;
this.value = value;
}

public string Display
{
set { display = value; }
get { return display; }
}

public long Value
{
set { value = value; }
get { return value; }
}
}

And here some sample code for the usage of the new class:
ComboBox cb = new ComboBox();
...
List<ComboBoxItem> items = new List<ComboBoxItem>();
items.Add(new ComboBoxItem("item 1", myObject.ID));
items.Add(new ComboBoxItem("item 2", myObject2.ID));
...
cb.ValueMember = "Value";
cb.DisplayMember = "Display";
cb.DataSource = items;


Note: I read on a forum that they "complained" that I am not using a generic List; but I am using a generic list, I only forgot to convert the "<" and ">" to be displayed correctly :-)

This line selects the combo box item of myObject2 and shows the appropriate display member:
cb.SelectedValue = myObject2.ID;

This line gets the ID of the selected item:
long selectedItemID = cb.SelectedValue;

And you can retrieve the whole combo box item to do whatever you want:
ComboBoxItem cbi = (ComboBoxItem) cb.SelectedItem;
string selectedItemText = cbi.Display;
long selectedItemID = cbi.Value;

CAUTION:
When using the data source property it is not possible to add new items to the combo box with the following code:
cb.Items.Add(new ComboBoxItem("new item", 3);


Possible Solution2:
If you do not want to create a class only for the combobox items you can also use the class "DictionaryEntry" in the namespace System.Collections. This gives you the ability to specify different datatypes for the display and value members as shown in the code below:
this.comboBox1.Items.Add(new DictionaryEntry("integer", 5));
this.comboBox1.Items.Add(new DictionaryEntry("string", "i am a string"));
this.comboBox1.Items.Add(new DictionaryEntry("float", 5.6f));
this.comboBox1.Items.Add(new DictionaryEntry("bool", true));
this.comboBox1.Items.Add(new DictionaryEntry("null", null));
this.comboBox1.Items.Add(new DictionaryEntry(1, 1));

this.comboBox1.DisplayMember = "Key";
this.comboBox1.ValueMember = "Value";

this.comboBox1.DataSource = this.comboBox1.Items;

This code populates a combobox with different DictionaryEntry objects. The key can be any object and the value can also be any object. This adds the flexibility of using different display and value members in the same combobox. The last line is needed in order to get the selected value member through the according property of the combobox; because this is only "enabled" if a datasource is set. To retrieve the selected values you can use code like this:
MessageBox.Show(string.Format("key: {0} - value: {1}", ((DictionaryEntry)this.comboBox1.SelectedItem).Key, this.comboBox1.SelectedValue));

If you have only display - value pairs which have all the same datatypes you could use the generic class KeyValuePair which is in the namespace System.Collections.Generic. With this you could populate your combobox like so:
this.comboBox1.Items.Add(new KeyValuePair("customer 1", 1));
this.comboBox1.Items.Add(new KeyValuePair<string, int>("customer 2", 2));
this.comboBox1.Items.Add(new KeyValuePair<string, int>("customer 3", 3));
this.comboBox1.Items.Add(new KeyValuePair<string, int>("customer 4", 4));

this.comboBox1.DisplayMember = "Key";
this.comboBox1.ValueMember = "Value";

this.comboBox1.DataSource = this.comboBox1.Items;

and obtain the selected item like:
MessageBox.Show(string.Format("key: {0} - value: {1}", ((KeyValuePair<string, int>)this.comboBox1.SelectedItem).Key, this.comboBox1.SelectedValue));

The advantage of this is for sure the type safety; because you do not have to cast the key or the value to the correct datatype. The disadvantage of this is that they have all to be of the same key and value type because otherwise the cast when obtaining the selecteditem would throw an exception.
Hope this may help someone :-)

Monday, November 12, 2007

Error during installation of service

The problem:
I tried to create an installer to install a windows service. The two needed installers are the ProcessInstaller and the ServiceInstaller. A requirement was to have a custom Event Log in the system for the service because there are no other ways (as far as I know) to log errors and events of a Windows service. I created therefore a new source and a new log for my application. When I tried then to install the service with "installUtil.exe" I received always an error that the source already exists on the machine and the installation was aborted and rolled back.

The solution:
After some trying I found out, that the ProcessInstaller creates automatically a source in the application log of the computer. As name for the source it uses the name of the project and as I had to realize I used the same name which clearly will produce the error. To solve the issue I created an EventLogInstaller and added it to the list of installers with a different name for the source and another name for the log. This solved all my problems because this installer creates now automatically the log, the source and when deinstalling, everything is removed automatically.
To use the created log the following code can be used:
EventLog.WriteEntry("sourceName", "message");

Saturday, November 3, 2007

MonoRail

In the last post I wrote about Active Record for C#. I would like to mention that from the same supplier there exist also other projects. Among them there is a framework which is called "MonoRail". As far as I understood it makes it possible to develop web applications in a Ruby on Rails like way by having MVC pattern and Action Pack. I think that this could be a big help for the development because it separates the model, the view and the controller which makes the code more readable and change tolerant. Unfortunately I did not have time to try it out, but as soon as I have some I definitely want to try it.

I also found another framework which aims to "help a website to build itself". It is called SubSonic and tries to port the "best" things of Rails to C#. The description sounds very interesting and I definitely would like to give it a try. But the time, the time... :-)

Related Links:
Castle Project Home
MonoRail Home
SubSonic Home

Active Record for C#

As I am a fan of Active Record and in the company in which I work C# is used to develop applications I looked for an Active Record implementation for C#. After some searching I found one which is called Castle Active Record. It does exactly what I want namely it provides a framework which makes it possible to use the Active Record pattern with C#.
As I am curious I tried it out imediatly. I did the tutorial provided on the homepage.
I had no problems with the tutorial and initially I tried it with a PostgreSQL database and I was not able to get it work. I always got an error message when I tried to let Active Record create the database schema. After some researches on the internet and some trying out I found out that I had to add a reference for the two files "Npgsql.dll" and "Mono.Security.dll" which are located at "C:\program files\PostgreSQL\8.2\Npgsql\", to my Visual Studio project. After that everything worked fine.
To make it work with MySQL you simply have to download and install the MySQL Connector from here. After you installed it you simply add it to your references and everything should work.

The project showed me how Active Record can be used with C# and I think that it can be very useful also for commercial projects. Give it a try...

I realized that the demo project is only available as VS2003 version. I will make it available as VS2005 version as soon as possible for people who have not time to write the project from scratch ;-) In my version I additionally added a search functionality which automatically iterates over all attributes of an object by using reflection and allows therfore searching in all attributes/columns.

Enjoy

Useful links:
Castle Active Record Home
MySQL Home
PostgreSQL Home

ReadOnly controls

I had the problem, that I needed controls which can be set to ReadOnly in Visual Studio. Since I have not found a solution in the internet that fits my needs I decided to create my own controls and I would like to make them available to other persons who may need them. The controls where created with Visual Studio 2005 Express and the .NET Framework 2.0.


To make the controls even more customizable they provide in additon to the "ReadOnly" property two other properties:
  • ReadOnlyBackColor - specifies the back color of the control when it is in ReadOnly state.
  • ReadOnlyForeColor - specifies the fore color of the control when it is in ReadOnly state.
In the screenshots below you can see the impact of this properties. Only for the Checkbox the ReadOnlyBackColor is not available, because this color can be changed with the BackColor property.

Usage

To use the controls in your project simply drag and drop the dll file of the controls into your Visual Studio Toolbox.

Here some screenshots:

To download the source code of the demo form and the dll file see the following link:
http://manfred-ramoser.jimdo.com/c.php

Ruby on Rails

As internship project for my thesis of applied computer science I developed a web application with Ruby on Rails. Since that point I am a big fan of Ruby on Rails and the used concepts such as Active Record, MVC, database migrations, scaffolds, unit- and function testing and many more. If you find some time I would stronlgy suggest to give it a try because it makes web development fast, easy and agile. "Simple" web pages can be created in a very small amount of time; but Rails provides also features for complex pages. This requires some time of vocational adjustment but then it is almost fun to create dynamic web pages.

Active Record
The most impressing thing of Rails was the built in support for the Active Record pattern. This is the short definition of what it is:
An object that wraps a row in a database table or view, encapsulates the database access, and adds domain logic on that data.
Martin Fowler
The idea behind is very very interesting. It mainly states that you take care of building the model with its objects and the relations between them and Active Record maps then automatically to an underlying database management system. The big advantages of this are that you can change the database when you like because you are not bounded to a specific DBMS; another big advantage is that you do not have to write any SQL which reduces errors and safes you a lot of code and maybe also a class which is called DBManager ;-).
To start you simply "tell" Active Record which is the database that you use, the name of the catalog and the user with which to connect to the DBMS. After that you create so called migration scripts which are written in Ruby and are used to create the needed tables in the database; you can also create the database tables manually or with SQL but I found that this was the easiest way. After the successful creation of the tables you can start coding. It is very simple to do that as you can see by this example:

This code creates a new user and stores it in the database:
user = User.new()
user.name = "uname"
user.passwor = "mypassword"
user.create


This code updates an existing user and stores the changes in the database:
user = User.find(3)
user.name = "newName"
user.update


This code destroys a user:
user = User.find(3)
user.destroy


It is as simple as this and you do not have to write any SQL statements.

Finally some usefull links to get started with Ruby on Rails:
Ruby on Rails Home
One click Ruby installer
Tutorial (not tried by myself)

Hello world!

Hello out there. I decided to start a Blog where I post my opinions and ideas.

Since I work in a small software company in south tirol I think that I will face with problems during development and I would like to post here possible solutions that I/we found which may be useful also for other people...