Monday, November 20, 2006

DynamicClassFactory - Motivation

We are all familiar with Activator.CreateInstance. It's a great tool, which provides a simple way of dynamically instantiating an object that was unknown at design-time. An obvious us for is to support plug-ins in an application.
Yet Activator.CreateInstance has one huge drawback - it's sloooooooow! Performance has been significantly improved between .NET 1.1 and .NET 2.0, but still, it's on the order of 60 times slower than a simple call to "new" for a parameter-less constructor and up to 1000 times slower with a highly parameterized constructor. If you're instantiating an object once in a while, this has no meaning. Yet, if you need to instantiate a lot of such dynamically-defined objects, you need a better solution.

The DynamicClassFactory (DCF) comes to solve this exact problem. I have written it about 2 years ago, and intended to publish it on CodeProject ever since. Yet, I never find the time to do it. So I'll publish it here, on my blog, with the hope of one day writing a more elaborated article and publish it somewhere.

It's not perfect, and some parts need to be arranged, but that's what I'm currently using. I'd like to change the configuration part, and cleaning up some of the code (remove the id-based instantiation for example), but still - it's useful as it is.

The basic idea is as follows: every class you want to be supported by the DCF needs to be defined in the configuration file, including the paths where referenced libraries can be found. At run-time, the DCF reads all the constructors of these classes using Reflection and builds a helper class that knows how create the object with each of it constructors. All this is kept in a dynamically generated class, which given the parameters knows which helper class to call. You end up with a reference to this dynamically generated class, and creating an instance of an object becomes a simple (small) set of if-conditions and one "new" instantiation. The result is a performance of only 10 times slower than direct "new", regardless of the number of constructor parameters.

There will now be a set of 4 posts (including this one), which provide the complete code for the DCF. I don't have time to elaborate much - hope the code and comment suffice. Please let me know if you need any help...

Now let's begin.

First, let's look at the interface implemented by the dynamically generated class:


using System;

namespace DynamicClassFactory
{
public interface IClassFactory
{
object CreateInstance(int id, params object[] args);
}
}

Simple, right? This means that creating an object would be exactly the same as with Activator.CreateInstance.


To be continued in next post...

An interesting Neural Network library in C#

I've always been fascinated by Neural Networks - the basic principles are simple and more importantly - intuitive. Yet the final result is complex and rarely explanable. For some time, Neural Networks have been the best learning method for complex, highly non-linear problems. Nowadays it is not so, there are many more learning methods, be it kernel-based Support Vector Machines, Bayesian methods and others, each better at solving different problems. Despite my subjective liking for Neural Networks, I must admit that I never found any problem that was better solved with Neural Networks than with, for example, Support Vector Machines. Yet, there are tons of problems out there and almost as much different types of Neural Networks. So in many cases it's worth considering Neural Networks as one of the various problem solving options.

Andrew Kirrilov has published an interesting Neural Network library on CodeProject, which includes some important network architectures (Back Propagation, Kohonen Self-Organizing Map, Elastic Network, Delta Rule Learning, Perceptron Learning). It seems to me like a good way to better understand how Neural Networks work and maybe integrate them in some applications that require the solving of complex problems. Check it out!

P.S: I have never heard of a similar library for Support Vector Machines. Maybe when I have some time, I will implement something myself and publish it. I don't promise anything - time is currently the resource I lack the most...

Friday, November 17, 2006

The Irreplacable Myth

Too many companies have this Irreplacable Guy, let's call him Guru. He's been in the company for ages, knows all its history better than anyone else (politically as well as technically). Well, he should, for he's written some "core" components a decade ago and it's so damn smart that nobody has ever been able to understand it apart him. Well, nobody dares getting even close to it. Or just look at it. Even from very far away. When a problem occurs, people will do anything to avoid bothering Guru - he's so busy doing important stuff that they try to avoid disturbing him unless absolutely necessary. Even then, they put gloves on. Really thick ones. And Guru makes a lot of money - more than some of the VP's. Well he should - the company would collapse were he to squint at the windows of the company accross the street, even by accident. And Guru knows how important he is, and particularly - how irreplacable he is. The truth is, that deep inside, Guru is in tremendous stress - he knows that he's mostly bluff, and that all his "core knowledge" could be learned (with or without his help) in a few days. He even realizes that his skills have deteriorated over the years, for he never learned anything new in the last decade, nor done any serious work outside of his company. But he has no choice but to remain where he is, making sure the Irreplacable Myth remains as strong as ever and his job remains as secure as the Myth is strong.

In Hebrew we say: Graveyards are packed with irreplacable people.

Well it's true, in almost all cases, the Irreplacable Myth is exactly that - a Myth. It has been feeded by Guru himself, as well as the constantly changing staff, bad management and chance. I have personally been in both positions - an Irreplacable Guy and a Myth-Breaker. When I thought I was Irreplacable I used to joke that if I were to get run over by a truck, the company will crash. At some point I decided to leave the company - I hadn't been around enough time to become a real Myth. Yet my feeling of responsibility was so great that I told the company 3 months ahead of time that I was leaving (instead of the 1 month I was obliged by my contract). It took them a lot of time to find someone, so I had only a couple of weeks to pass everything to the new guy. And you know what? Everything went fine, the company didn't loose too much money and is still around today, making much more money than they did back then. On the other hand, I once started working for a company where there were not one, but two Irreplacable Guys. For various reasons (I must admit much of it had to do with me) they were both fired when the company had to cut down jobs, and not only didn't the company loose anything from it - many things went much better and faster, with a much better atmosphere after they left.

Are there real Myths? Well I think there are, but these are usually people not considered Irreplacable, so they become Myths only after they have left. These are usually very talented and creative people, who come up with ideas others would never be able to come up with. A real Myth is not one who knows a lot of stuff, he's one who creates things others wouldn't have thought of. That, ladies and gentlemen, is potentially an Irreplacable Guy!

Monday, November 13, 2006

A Prioritized Queue in C# - Enumerator and Synchronization classes

Continuing my previous post...
        [Serializable]
private class PrioritizedQueueEnumerator : IEnumerator, ICloneable
{
private PrioritizedQueue prioritizedQueue;
private int index;
private int version;
private int currentQueueIndex;
private IEnumerator currentEnumerator;
private int count;

internal PrioritizedQueueEnumerator(PrioritizedQueue prioritizedQueue)
{
this.prioritizedQueue = prioritizedQueue;
this.index = -1;
this.version = prioritizedQueue.version;
this.currentQueueIndex = -1;
this.count = prioritizedQueue.Count;
updateInternalEnumerator();
}

public bool MoveNext()
{
if (version != prioritizedQueue.version)
{
throw new InvalidOperationException("Enumerator was changed!");
}

index++;
if (index > count)
{
return false;
}
else
{
if (!currentEnumerator.MoveNext())
{
updateInternalEnumerator();
if (!currentEnumerator.MoveNext())
{
return false;
}
}
return true;
}
}

public void Reset()
{
index = -1;
}

public object Current
{
get
{
if (version != prioritizedQueue.version)
{
throw new InvalidOperationException("Enumerator was changed!");
}

if ((index < 0) || (index >= count))
{
throw new InvalidOperationException("Enumerator out of bounds");
}

Debug.Assert(currentEnumerator != null);

return currentEnumerator.Current;
}
}

public object Clone()
{
return base.MemberwiseClone();
}

private void updateInternalEnumerator()
{
currentQueueIndex++;
for (; currentQueueIndex < prioritizedQueue.queues.Length; currentQueueIndex++)
{
Queue queue = prioritizedQueue.queues[currentQueueIndex];
if (queue.Count > 0)
{
currentEnumerator = queue.GetEnumerator();
break;
}
}
}
}

[
Serializable]
private class SynchronizedPrioritizedQueue : PrioritizedQueue
{
private PrioritizedQueue prioritizedQueue;
private object syncRoot;

public override object SyncRoot
{
get { return syncRoot; }
}

public override int Count
{
get
{
lock (syncRoot)
{
return prioritizedQueue.Count;
}
}
}

public override bool IsSynchronized
{
get
{
return true;
}
}


internal SynchronizedPrioritizedQueue(PrioritizedQueue prioritizedQueue)
{
syncRoot =
new object();
this.prioritizedQueue = prioritizedQueue;
}

public override object Clone()
{
object obj = null;
lock (syncRoot)
{
obj =
new PrioritizedQueue.SynchronizedPrioritizedQueue((PrioritizedQueue)this.prioritizedQueue.Clone());
}
return obj;
}

public override void Clear()
{
lock (syncRoot)
{
prioritizedQueue.Clear();
}
}

public override bool Contains(object obj)
{
bool contains;
lock (syncRoot)
{
contains = prioritizedQueue.Contains (obj);
}
return contains;
}

public override object Dequeue()
{
object obj;
lock (syncRoot)
{
obj = prioritizedQueue.Dequeue();
}
return obj;
}

public override object Dequeue(QueuePriority priority)
{
object obj;
lock (syncRoot)
{
obj = prioritizedQueue.Dequeue (priority);
}
return obj;
}

public override void Enqueue(object obj)
{
lock (syncRoot)
{
prioritizedQueue.Enqueue (obj);
}
}

public override void Enqueue(object obj, QueuePriority priority)
{
lock (syncRoot)
{
prioritizedQueue.Enqueue (obj, priority);
}
}

public override object Peek()
{
object obj;
lock (syncRoot)
{
obj = prioritizedQueue.Peek ();
}
return obj;
}

public override object Peek(QueuePriority priority)
{
object obj;
lock (syncRoot)
{
obj = prioritizedQueue.Peek (priority);
}
return obj;
}

public override object[] ToArray()
{
object[] array;
lock (syncRoot)
{
array = prioritizedQueue.ToArray ();
}
return array;
}

public override void TrimToSize()
{
lock (syncRoot)
{
prioritizedQueue.TrimToSize ();
}
}

public override void CopyTo(Array array, int index)
{
lock (syncRoot)
{
prioritizedQueue.CopyTo (array, index);
}
}

public override IEnumerator GetEnumerator()
{
IEnumerator enumerator;
lock (syncRoot)
{
enumerator = prioritizedQueue.GetEnumerator ();
}
return enumerator;
}

}
}

A Prioritized Queue in C#

Mark Paint asked me on my CyclicQueue CodeProject article to publish my PrioritizedQueue. I don't have the time to wrap it nicely and write an article, so I'm just putting it here for anyone who might need it.

Basically it's like a priority queue, except that here items with the same priority are guaranteed to be extracted in the order they were entered (FIFO). Important: If you don't need this feature then what you need is a simple priority queue which can be implemented in a more effective way (especially memory-wise) using a heap structure. Also, for my personal needs I've used a fixed number of 5 priorities - which may not be the best solution for all problems.

Goodies:
* You can make it automatically shrink the queues when there is a lot of free space (make sure to change the maxCount member variable).
* Support for thread-safe wrapper (Synchronized), enumeration, etc.

Things to modify:
* More flexible priorities
* Generics support

(Note: I'm posting this with Windows Live Writer. For some reason, there is a limit on size of the post - so I can't post it completely in one post. I'll post the synchronization class and the enumerator in  few minutes)

using System;
using System.Collections;
using System.Diagnostics;

namespace DataStructures
{
   
/// <summary>
   /// A queue which allows the items to have priorities. Items with the same
   /// priority are returned in FIFO order (that's why it's a prioritiIZED queue and not a prioritY Q)
   /// TODO: Make the priorities (names and number) more flexible
   /// </summary>
    [Serializable]
   
public class PrioritizedQueue :Queue
    {
       
private int count = 0; // Counts the number of items in the PrioritizedQueue
       // Our idea was to trim (i.e. shrink) the internal queues once they got a too large empty portion.
       // The problem is that we don't know the internal size of the queues (only the number of items in them).
       // The best approximation we can have is to constantly keep track of the largest number of items in the
       // queues, since the last call the TrimToSize().
       // When this value becomes significantly larger than Count, there is a good chance that the queues
       // can be shrinked.
       // To avoid shrinking needlessly, we shrink the queues only when maxCount has exceeded a certain threshold.
       // It is important to note that this feature (i.e. automatically shrinking of the queues) provides a very
       // important and significant improvement on the memory usage of this class.
       private int maxCount = 0;
       
private Queue[] queues;
       
private readonly int defaultQueueIndex = 2;
       
private int version = 0;
       
public const QueuePriority DEFAULT_PRIORITY =QueuePriority.Normal;
       
public PrioritizedQueue()
        {
            queues =
new Queue[5];
           
for (int i = 0; i < 5; i++)
            {
                queues[i] =
new Queue();
            }
        }

       
public PrioritizedQueue(ICollection collection) :this()
        {
            queues[defaultQueueIndex] =
new Queue(collection);
        }

       
public override void Clear()
        {
            version++;
           
foreach (Queue queuein queues)
            {
                queue.Clear();
            }
            count = 0;
        }

       
public override bool Contains(object obj)
        {
           
foreach (Queue queuein queues)
            {
               
if (queue.Contains(obj))
                {
                   
return true;
                }
            }
           
return false;
        }

       
public override object Dequeue()
        {
           
if (count == 0)
            {
               
throw new InvalidOperationException("Cannot dequeue empty queue");
            }

           
object obj =null;
           
foreach (Queue queuein queues)
            {
               
if (queue.Count > 0)
                {
                    obj = dequeueImpl(queue);
                   
break;
                }
            }           

           
return obj;
        }

       
public virtual object Dequeue(QueuePriority priority)
        {
           
return dequeueImpl(queues[(int)priority]);
        }

       
public override void Enqueue(object obj)
        {
            version++;
            queues[defaultQueueIndex].Enqueue(obj);           
            count++;
           
if (count > maxCount)
            {
                maxCount = count;
            }
        }

       
public virtual void Enqueue(object obj,QueuePriority priority)
        {
            version++;
            queues[(
int)priority].Enqueue(obj);
            count++;
           
if (count > maxCount)
            {
                maxCount = count;
            }
        }

       
public override object Peek()
        {
           
if (count == 0)
            {
               
throw new InvalidOperationException("Cannot peek empty queue");
            }

           
object obj =null;
           
foreach (Queue queuein queues)
            {
               
if (queue.Count > 0)
                {
                    obj = queue.Peek();
                   
break;
                }
            }
           
return obj;
        }

       
public virtual object Peek(QueuePriority priority)
        {
           
Queue queue = queues[(int)priority];
           
if (queue.Count == 0)
            {
               
throw new InvalidOperationException("Cannot peek empty queue");
            }
           
return queue.Peek();
        }

       
public static PrioritizedQueue Synchronized(PrioritizedQueue prioritizedQueue)
        {
           
if (prioritizedQueue ==null)
            {
               
throw new ArgumentNullException("prioritizedQueue");
            }
           
return new PrioritizedQueue.SynchronizedPrioritizedQueue(prioritizedQueue);
        }

       
public override object[] ToArray()
        {
           
object[] objs =new object[count];
           
if (count > 0)
            {
               
this.CopyTo(objs, 0);
            }
           
return objs;
        }

       
public override void TrimToSize()
        {
            version++;
           
foreach (Queue queuein queues)
            {
                queue.TrimToSize();
            }
            maxCount = count;
        }

        #region ICollection Members

       
public override bool IsSynchronized
        {
           
get
            {
               
return false;
            }
        }

       
public override int Count
        {
           
get {return count; }
        }

       
public override void CopyTo(Array array,int index)
        {
           
if (array ==null)
            {
               
throw new ArgumentNullException("array");
            }
           
if (array.Rank != 1)
            {
               
throw new ArgumentException("Array rank must be 1","array");
            }
           
if (index < 0)
            {
               
throw new ArgumentOutOfRangeException("index","Array index out of range");
            }
           
if ((array.Length - index) < count)
            {
               
throw new ArgumentException("Array is too small","array");
            }

           
foreach (Queue queuein queues)
            {
                queue.CopyTo(array, index);
                index += queue.Count;
            }
        }

       
public override object SyncRoot
        {
           
get
            {
               
return this;
            }
        }

        #endregion

        #region
IEnumerable Members

       
public override IEnumerator GetEnumerator()
        {           
           
return new PrioritizedQueue.PrioritizedQueueEnumerator(this);
        }

        #endregion

        #region
ICloneable Members

       
public override object Clone()
        {
           
PrioritizedQueue newPrioritizedQueue =new PrioritizedQueue();
           
for (int i = 0; i < queues.Length; i++)
            {
                newPrioritizedQueue.queues[i] =
new Queue(queues[i]);
            }
            newPrioritizedQueue.version =
this.version;

           
return newPrioritizedQueue;
        }

        #endregion

       /// <summary>
       /// The actual implementation of Dequeue.
       /// This method removes the next item from the given queue and updates the internal counter.
       /// In addition, it shrinks the queues if there is too much space left in the internal queues.
       /// Finally, it returns the object that was extracted from the queue.
       /// </summary>
       private int trimCounter = 0;
       
private object dequeueImpl(Queue queue)
        {           
            version++;
           
if ((count * 4 < maxCount) && (maxCount > 100))
            {
               
// If the available space is significantly larger than necessary (i.e. larger than
               // 4 times the number of items in the Q and larger than a predefined threshold of 100)
               // then we trim the Q to its actual size.
               this.TrimToSize();
                trimCounter++;
            }
           
object obj = queue.Dequeue();
            count--;
           
return obj;
        }

    }

    public enum QueuePriority
    {
        High = 0,
        AboveNormal = 1,
        Normal = 2,
        BelowNormal = 3,
        Low = 4
    }

}

MethodLogger - Hook into method calls in .NET binaries

Senthil Kumar just posted a gem of a tool on CodeProject. MethodLogger is a simple command line application that changes running IL code to hook into methods and do something when they start/end (essentially for logging purposes obviously). Looks pretty cool to me, as well as useful - he's got my 5 points vote!

Sunday, November 12, 2006

Could the ESP Game replace CAPTCHA ???

A few days ago I talked about the Human Computation and the ESP Game. I haven't stopped thinking about it since...

What I was thinking was - why not leverage the principles of the ESP Game to replace CAPTCHA, and tranforming this "annoying, inproductive, necessary" thing (CAPTACHA) into something that is "annoying, productive, neccessary"?

Let me explain:
Image you are creating an account in GMail. At some point, instead of being given a CAPTCHA, you are showed an image of a little boy dressed-up like a cow-boy with a huge mustache. And instead of having to type these annoying skewed letters, you must type a word that represents what you see in the image (maybe with a "taboo" list that says that the word "BOY" cannot be used). Since "BOY" is already taken, you type "MUSTACHE" and your subscription goes on.
What happened in the background is that the system already had a set of potential tags for this image, that is, tags given by one user and still require acknowledgement by another (independant) user. Since the word MUSTACHE was one of these potential tags, the systems can deduce that there is indeed a person behind the computer and lets you continue.

How do you get this initial list? Why do you need it anyway? What happens if the word entered does not appear in the potential tags?

You need an initial list for two reasons:

  1. Without such a list you would have to play the real ESP Game - in which case you need to compare the words entered by two users. This could lead to too slow response if one of the "players" has entered his word and the second one is still thinking. You could solve this by having multiple players with the same image, but then it's becoming very similar to my idea of an initial list.
  2. You must make sure spammers won't take advantage of your system. With the ESP Game, they could launch thousands of simultaneous request, making them all enter the exact same word - they would stand large chance of being coupled together and provide you with really bad tags (not to mention that the whole idea of avoiding spam would be lost).

To generate this initial list, you need to actually show the user 2 images. One of them is based on an existing initial list (i.e. and image for which you already have a large number of potential tags). The second image has no potential tags at all - it's there to build an initial list for the future. The user will "pass" only based on what he entered for the first image - the second one will be judged in the future, once it's used as an initial list.

With this approach (2 images, one compared to an existing list and the other to build a future list), spammers can't fool you. If you leave enough time between the time you generated an initial list and the time you use the image for actual tagging, you can track words recurring very often for various different images, which could potentially be due to spammers. These tags will be removed and not used as potential tags. Thus, the spammers won't be able to fool you! Also, it avoids any delay and none of the users depends on other users.

Even if you collect hundreds of potential tags for each image, you could still get to a situation that the user entered a word that does not exist in the potential tags list. In this case, you could show him another image. Yet, if you want to avoid annoying the users too much, you can simply show him a CAPTCHA. The result being that each user is given exactly 2 or 3 images (in the latter case the third image is a CAPTCHA) and thus there is a concrete limit to the level of annoyance to the user. Of course, you can be really nice and provide the user a choice between a CAPTCHA and an image to tag.

Finally, this system could provide you a huge amount of image tags very fast. The advantage is that the taggers are very diverse, and the amount of taggers is much more than you would have in the case of a game.

Thursday, November 09, 2006

Human Computation

 

Luis von Ahn is a GENIUS!!!

He developed a way to make people label images, mark regions to locate objects in images and is working on more stuff - by making people doing it for him. And they do it for free. And they enjoy it. And they continue to come for more....

For a detailed description, I urge you to go and see his presentation. Alternatively go directly to the ESP Game or Peekaboom (or check out their search engine - Peekasearch).

ESP Game is a game where two people have to label given images. Once they both give the same label for an image, they get scores. The result is a pretty accurate set of labels for the images.

Peekaboom - gives the first user an image and a label. He then must point to areas of the image that represent the label. The second player is shown only the area around the points marked by the first player, and must guess the label based only on the portion of the image that he can see. The result is that the labels are given pretty accurate locations inside the images!

The basic idea of transforming difficult tasks, such as computer vision problems and the like, into games is what he calls Human Computation, and its potential is huge! Porn sites use it to resolve CAPTCHA in a very straight-forward way. The gaming approach is essentially the same, except that it's more moral, it's fun, and could be adapted to a lot of other very difficult problems.

Brilliant!

Wednesday, November 08, 2006

Waiting for threads

I know I'm stating the obvious, but I've seen this in one too many occasions - I had to act...

Sometimes you have an application that must do some job with multiple threads, and once they all complete, you can proceed with a concluding action. The straight-forward code would be as such:


public class StraightForward
{
private int numberOfThreads;
private Thread[] threads;

public StraightForward(int numberOfThreads)
{
this.numberOfThreads = numberOfThreads;
}

public void DoWork()
{
// Launch the threads to do the work
threads = new Thread[numberOfThreads];
for (int i = 0; i < numberOfThreads; i++)
{
threads[i] =
new Thread(new ThreadStart(doWorkImpl));
threads[i].Start();
}

// Wait for all the threads to complete
for (int i = 0; i < numberOfThreads; i++)
{
threads[i].Join();
}

// Do the concluding work
onWorkCompleted();
}

private void doWorkImpl()
{
// Do something here
}

private void onWorkCompleted()
{
// Do some concluding work here
}
}

Using a threadpool instead of launching the threads yourself is an option, but then I would strongly recommend Ami Bar's SmartThreadPool. Also, to be able to "join" threads from the .NET's threadpool you may want to use Stephen Toub's ThreadPoolWait. Anyway, for our discussion we will assume you have very good reasons for not using a threadpool at all.

The problem with the code above is that it requires an additional thread for "administrative" purposes only. That is, either the calling thread (like the code above) or an additional thread (to run DoWork asynchronously) must block there, waiting for all the others to complete their job and then execute onWorkCompleted.

The solution is very simple - keep track of the number of threads still running using an integer (that is handled only through the Interlocked class). The last thread to complete will know it's the last one and will be responsible to execute the concluding onWorkCompleted method. Here is a sample:


public class NoRedundantThread
{
private int numberOfThreads;
private Thread[] threads;
private int runningThreads;

public NoRedundantThread(int numberOfThreads)
{
this.numberOfThreads = numberOfThreads;
}

public void DoWork()
{
// Launch the threads to do the work
threads = new Thread[numberOfThreads];
runningThreads = numberOfThreads;
for (int i = 0; i < numberOfThreads; i++)
{
threads[i] =
new Thread(new ThreadStart(doWorkImpl));
threads[i].Start();
}
}

private void doWorkImpl()
{
// Do something here
// ...

// If we're the last thread - run the concluding method
if (0 == Interlocked.Decrement(ref runningThreads))
{
onWorkCompleted();
}
}

private void onWorkCompleted()
{
// Do some concluding work here
}
}

Now the code is asynchronous, without the need for a thread that just sits there, waiting for the others to do the work :-)

Tuesday, November 07, 2006

PRNGs for .NET

I'm still looking for a good commerical numerical library in .NET. In the mean time, here's what looks like an excellent PRNG and Distributions library!

Remember - for cryptographic purposes, pseudo-random number generators are NOT good enough and you should always use entropy-based RNGs such as can be found under System.Security!!!

Monday, November 06, 2006

Leave me out of your MLM scams!!!

MLM (Multi-Level-Marketing) has been really flooding the country for the past couple of years. Every few weeks another friend or relative tries to convince me to get with him into this stupid thing (internet phone, vitamins, water filters, games, whatever... - even a magic potion that supposedly solves any physical problem you may have!!!). They are being filled their heads with a vision of mountains of gold and loose their common sense on the way! I know tens of people who got into things like that, but NONE has EVER made enough money to cover for the time and initial investment demanded from them.

IMO, there are 3 ways to make money:

  1. Work, hard, preferably at a job with high demand.
  2. Have a lot of initial money and let it do the job for you.
  3. Steal.

(In case you were wandering - only the first way is an option for me :-)

Also, when I buy a product, I want to pay the money, get the product, and get on with my life. I don't want to have to do some additional work to make it worthwile having bought the product in the first place. I also don't want my decision of whether or not to buy a product to be dictated by the money it may or not give me at the end of the road.

That's it, I had to get this off my chest...

Binding Enum values to a combobox

Being mostly a back-end programmer, every time I find myself working on a Windows Form I have to remind myself of all these tiny tricks. This time I'll post it on my own blog, so it will be easier for me to look it up in the future.
Say you have an enumerator (MyEnum) and you want to bind its values to a combobox (myCombo) - the simplest way is as so:


myCombo.DataSource =
Enum.GetValues(typeof(MyEnum));

Saturday, November 04, 2006

Rich Lentil Soup

It's getting cold again, and Winter is getting close - so I'm making soups again*... 
Today I'd like to introduce you to one of my favorites, especially when it's really cold and wet - meet my Rich Lentil (and Meat) Soup:

Ingredients:

  • 2 Onions in thin slices/stripes
  • 2 cups of green Lentils
  • 1 Potato
  • 1 peeled** frech Tomato in little cubes
  • 3 sliced cloves of Garlic
  • 1 Carrot in slices
  • 1 small piece of Pumpkin in small cubes (could be replaced by a small sweet potato, but then the soup will be sweeter)
  • 2 Celery branches with leaves
  • 1 piece of Bone with marrow
  • 300 gr. meat (cow or mutton). You could replace this by 1 or 2 additional bones instead
  • 5 bay-tree ("dafna") leaves
  • olive oil
  • salt
  • 1-2 tea-spoons of Hawayedge***
  • (optional) hot pepper
  • (optional) Chili pepper

Directions:

  • Fry the onions and the carrot in the olive oil until the onion gets yellowish
  • Add the garlic and keep frying for a couple more minutes
  • Add all the ingredients except for the spices. Cover with water. The lentils will absorb some of the water, so make sure there is enough water.
  • Once boiling temperature is achieved, leave it at boiling temperatures for about 2-3 hours. The water should become completely brown and the lentils should start to decompose. Also, most of the tomato's acidity will be gone by then.
  • Now add the spices (salt, Hawayedge, hot pepper, Chili pepper), stirr well, wait a couple more minutes for the spices to catch.
  • Enjoy!

Notes:

  • Of course, you can play with the ingredients. Today, for instance, I used a sweet potato instead of pumpkin and didn't have celery. I also added one zuccini I had in the fridge. It was a huge success.
  • The tomato is there to add some acidity. Some people like it even more acid, and use lemon - I prefer it with 1 tomato.
  • The thing I like with the pumpkin is that during the cooking it completely desintegrates, making the soup thicker.
  • In many cases I find myself taking one large cup of this soup to replace a whole meal (maybe with some bread on the side).

* If you're interested in more of my soups, check out my:
Chicken Bouillon
French Onion Soup
Orange (color) Soup

** To peel a frech tomato make an X shaped cut at it's bottom, and put it in a container with very hot water for a few minutes. You will then be able to peel it effortlessly.

*** Hawayedge is an oriental coctail of spices (originally from Yemen) made of black pepper, cumin, cardamom ("hel"), turmeric ("curcum") and coriander ("cusbara"). Maybe with other things, I wouldn't know - I buy it already made from my spice-man...

Friday, November 03, 2006

Numerical Library in C#

I'm looking for a good numerical library in C#. So far I've found the following:

  1. Extreme Optimization - Looks nice, documentation a little weak. Seems rather expensive for the amount of functionality it supplies. Also, source code is only available for large licenses (with an extra payment).
  2. Visual Numerics IMSL - From references I found on the internet, it seems to be the most popular, and certainly the longest on the market (the company is 35+ years old). They also propose a very large range of functions. But they seem to only support .NET 1.1 !!! And what's more, their last version was released only last June, so it's not that they are about to release any .NET 2.0 version anytime soon. Besides the fact that I work only with .NET 2.0, I really don't tend to like products from companies that are so slow they can't follow the market on time.
  3. NMath - Looks very promising. They also provide a means of purchasing only packages with what you need, and give you full source code without additional charge. I'm just curious about the company, who'se been around for only 4 years or so (compared to Visual Numerics).

Any suggestions?

Wednesday, November 01, 2006

Skype Gaming Infrastructure - Coooool

Take a look at this: http://www.codeproject.com/csharp/skypegameinfra.asp

Michael Gopshtein shows you how Skype can easily be used to build an online game (or any other multiple users online application for that matters) - no dedicted server attached! And, to make it even nicer, he wraps it all with a nice C# library.

Awesome!

Tuesday, October 31, 2006

"The District" - WTF

I was taking a break, eating a salad in front of the TV, watching half an episode of "The District". There was a whole fuss going on about a kidnapped little girl. The parents got the ransom email, the ultra-smart police-guys analyzing everything on the spot, etc.
Suddenly one of the geeks says: "We've got a partial trace - it's been sent from an anonymous server using a 256-bit key". Then the father's associate jumps saying: "256... Hey, that's the software we've developed!".
And then of course they concluded that the kidnaper must be one of their past employees... (I didn't see whether they were right - it's commercial time now)

Need I say more?

Networked-RNG

True Random Number Generators are hard and almost impossible to create. Most computer programs use pseudo-Random Number Generators (PRNG) which are, in fact, not random at all. They simply use a mathematical function (most commonly LCG) with a seed based on the system's clock.
For security applications, these simple PRNGs are bad bad bad - they create a giant hole in the security mechanism through which hackers can fairly easily penetrate. So entropy-based RNGs are usually used for cryptographic purposes (for example Window's CryptGenRandom). These RNGs try to collect randomness (actually it's entropy) from as many resources as possible: keyboard events, mouse events, hard-disk events, network events, etc.
Linux also has such an entropy-based RNG, but it has been shown to be weak in some circumstances.
To my knowledge, Windows' counterpart (CryptGenRandom) hasn't yet experienced such a faith...
BTW - an important problem with the cryptographically strong RNGs on a computer is that sometimes they must wait for enough entropy to occur before being able to returning a new random number, causing the application to stall (and making it difficult to generate a large amount of random numbers at short intervals).
Would it be possible to have a really random RNG?
Well, there are various physical phenomena (such as some nuclear processes) that could be used, but it's complicated to incorporate this into every PC :-)
An idea came to my mind - Imagine we had a web service, generating simple random numbers, based on previous calls to the service (and maybe a few other entropy sources). Then each user would get a random number that is influenced by some other user, completely unknown to her. The main idea behind this is that the randomness is aquired from the various independent requests, making it essentially random.
A simulation of such a generator could be easily created by using Blogspot's "Next Blog" link, where you are randomly forwarded to another blog. Take the link you got (or some information inside the blog), hash it somehow (MD5 hasn't been broken yet), and what you get is really random (I checked - a blog doesn't refer twice to the same blog).
This is all very fuzzy, and I'm sure it's flawed in many ways. Yet I think that the principle could be interesting - using user navigation information to provide an RNG service over the web.
And what about performance - having to execute a web request to get one random number isn't very nice!? Well, I didn't say it's perfect, did I? Yet it may (maybe) be extended to return pools of random numbers, thus requiring much less web calls. Also, if you're already running a web site, you may be able to use your own users' information to generate a local RNG only for yourself.

OK, enough babling, ciao!

Afraid of moving to IE7

I know that using IE is not very "geeky", but I don't care - I'm an IE user. I've tried FireFox several times (including the latest version 2), and even installed the latest Opera browser. Both had real difficulties coping with my banks' sites (Opera remained blank and FireFox often gets completely stuck, up to getting my whole machine stuck!). I want to use one single browser  - without needing to remember which browser works best with which site. I know that the culprits are the web developers and not the browsers (probably), but I don't care -the bottom line is that I can't use either of them for all my browsing tasks.
Conclusion - I have to keep using IE.
Now IE7 is out, and it looks pretty promising - enhanced security, tabs (finally), RSS, etc. Not as rich as FireFox or Opera, but still - much better than IE6. The problem is that I don't know whether the sites I usually visit properly support IE7, and I really don't feel like counting on uninstalling it in case of problems.
Dillema....

Things I'm missing in C#/CLR

Although C# is a great language, I'm still missing some features. I know it's mostly a matter of CLR limitations, but I'm missing it nonetheless.

  1. Signature-free Delegate - imagine you have a system that works intensively with configuration/settings files, loading stuff at runtime. Now you want this system to be able to dynamically receive a delegate from one source and parameters from another source, and run that delegate with those parameters. At compile time, the only thing you know is that you have to run some delegate - you don't know its signature. I'd like a way to define a delegate that accepts any signature, and a technique to dynamically call it with whatever parameters I get. Of course it means that important stuff cannot be checked at compile time, but sometimes it's the best way to provide a generic solution (if you're interested, I could post an example of what I mean in some later post).
  2. Multiple Inheritance - I know, this is almost a theological issue (much like the Good/Bad Agile debate going on lately). I also admit that it doesn't happen a lot that I really need multiple inheritance. Yet, sometimes I do, and at these times, I'm really p'd off for not having the option (and don't give me the brainwashed crap feeded by Microsoft that you never need it and can always use some pattern to work around it!). BTW - Eiffel.NET has full multiple inheritance support.
  3. Method Signatures - as in C++, methods can't differ only by return type. That sucks, plain and simple.
  4. Multiple Return Parameters - who said a method must return only one parameter? If I want to divide two numbers and get both the integer result and the remainder - why do I need to get one in the return value and the other as an "out" argument?
  5. Interactive Scripting - I've written enough about that.