Thursday, September 27, 2007

A simple GreatestCommonDivisor service in C# - Part2

What if we wanted to consume our previously built GCD Service by a web browser, such as Internet Explorer? ... Nothing easier than that. In fact, with minimal effort we can implement this functionality.
Firstly, we have to (1) declare that our service supports the HTTPQuery operation, secondly we have to (2) implement a handler for this HTTPQuery request, and thirdly we may (3) test the service with a browser.

1.
Just add the HTTPQuery port to the GCD service's port set, which is defined in GCDTypes.cs (assuming that your service is named GCD).

[ServicePort()]
public class GCDOperations : PortSet<..., HttpQuery, ...>
{}

So now that we have declared that our service is capable of understanding a HttpQuery action, we need to implement a routine, which handles such HttpQuery requests - a HTTPQueryGCDHandler.

2. Add the following lines to the GCD.cs

[ServiceHandler(ServiceHandlerBehavior.Concurrent)]
public virtual IEnumerator HTTPQueryGCDHandler(HttpQuery httpQuery) {
if (!string.IsNullOrEmpty(httpQuery.Body.Query["Action"]) &&
httpQuery.Body.Query["Action"] == "GCD")
{
string _M = httpQuery.Body.Query["M"];
string _N = httpQuery.Body.Query["N"];

int _intM = 1;
int _intN = 1;

if (!Int32.TryParse(_M, out _intM))
{
this.LogError("Failed to parse M");
httpQuery.ResponsePort.Post(

new HttpResponseType(new GcdtestState(-1)));
yield break;
}

if (!Int32.TryParse(_N, out _intN))
{
this.LogError("Failed to parse N");
httpQuery.ResponsePort.Post(

new HttpResponseType(new GcdtestState(-1)));
yield break;
}

int _GDC = this.ComputeGCD(_intM, _intN);
this.LogError("GDC = " + _GDC);

httpQuery.ResponsePort.Post(

new HttpResponseType(new GcdtestState(_GCD)));
}
else
{
this.LogError("Action is not GDC");
httpQuery.ResponsePort.Post(

new HttpResponseType(new GcdtestState(-1)));
}

yield break;
}

Besides computing the greatest common divisor and returning it as a http response, this handler does not do too much. It analyses whether the passed Action equals GCD and if so it tries to take the (hopefully) supplied parameters M and N. The service uses M and N to compute their GCD and if successful, passes the result back. If an error occurs, this service returns -1. The handler does not update the service's internal GCD state because of the following recommendation from the MRS help :

"As both GET and QUERY requests are defined by DSSP as not having any
side-effects, GET and QUERY handlers should be marked as
ServiceHandlerBehavior.Concurrent using the ServiceHandler attribute so that the
infrastructure knows that these handlers can run concurrently. "


3.With the handler in place, we may test our service. So we execute it by opening a browser and typing in the following URL

http://localhost:50000/GCD?Action=GCD&M=15&N=3

and this will return the correct result of 3. Note, that depending on you configuration the port and service name might be different. In fact, in the previous tutorial the service's name was GCDService, so you might want to take this into consideratio.

Although this was only a minor sample, I am trying to do something more meaningful with DSS and I hope to provide another small tutorial soon. So read you soon.

Christian

Saturday, September 15, 2007

A simple GreatestCommonDivisor service in C# - Part 1

I was finally able to get the GCD service up and running. Essentially it does nothing different than my previously posted GCD service, which is implemented in VPL. So to recall, this service computes the greatest common divisor of two positive integer numbers (inputx, inputy) and outputs the result as greatestcommondivisor.

Based on this description of what the service does, the remainder of this post will guide you through the process of how I built such a rather simple DSS service using the MRS object model and C# as implementation language (as mentioned you could also choose VB.NET, C++).

This kind of tutorial is divided into distinct steps beginning at creating a new service project to the final result being the service we want.


  1. Create new DSS Service
    The first thing one has to do in order to set up a basic GreatestCommonDivisor service is to create a new DSS service.We will do so by creating a new Visual Studio 2005 Project. More specifically it is a "Simple DSS Service (1.5)" project (it is assumed that you have MRS 1.5 installed). Select the mentioned project type and name it as you please (e.g., "GCDService") (see here for more detail). This will create a file for the service (e.g., GCDService.cs) a manifest file (e.g., *.manifest.xml) and a file for the types used by the service (e.g., GCDServiceTypes.cs).

  2. Define what is the objective of the service
    The service should do nothing special, just compute the greatest common divisor of two non-negative integer numbers m and n.This can be easily accomplished via euclids algorithm. In a previous post about python, I gave a recoursive implementation for this algorith, which is why I won't do it here again. So let us assume we have built a function, which implements euclids algorithm. The function's signature might look like this

    public static int ComputeGreatestCommonDivisor(int m, int n)
    {/*function's implementation not shown*/}


  3. Define the input message
    A DSS Service accepts input messages of some form coming from some input port, handles these messages and sends some output message as a response to its ouput port. For example, to get information about the state of a DSS service, this service has to handle a Get request, i.e. a "Get" message sent to the input port of this service. The DSS service receives the "Get" message does something and might respond to this message by sending "Hello World" as answer to its output port.
    Similarly, our "GreatestCommonDivisor" service might get a request to compute the greatest common divisor (GCD) of two non-negative integer numbers n and m. Therefore, such a request might incorporate the n, and m sent to our service and the expected response might be the GCD of m and n. Consequently, we have to define such a request or how such a GCD message must look like to be accepted as GCD message by our service and to be handled appropriately. The following lines of code, which we add to the types source code file (e.g., GCDServiceTypes.cs), define such a GCD request

    [DataContract(Name="ComputeGreatestCommonDivisor")]
    public class ComputeGCDRequest
    {
    private int _inputX;

    [DataMember(IsRequired = true, Name = "InputX")]
    public int InputX
    {
    get { return (this._inputX); }
    set { this._inputX = value; }
    }

    private int _inputY;

    [DataMember(IsRequired = true, Name = "InputY")]
    public int InputY
    {
    get { return (this._inputY); }
    set { this._inputY = value; }
    }

    public ComputeGCDRequest()
    {
    this.InputX = 1;
    this.InputY = 1;
    }
    public ComputeGCDRequest(int x, int y)
    {
    this._inputX = x;
    this._inputY = y;
    }
    }

    The ComputeGCDRequest defines how a request to our service has to look like. It defines m and n (InputX, InputY). Each request has to be marked with the DataContractAttribute attribute, so DSS can wire things up for us. Fields we want to incorporate in our request have to be marked with DataMemberAttribute attribute (those fields are part of the message serialization process when the ComputeGCDRequest message is serialized over some channel). These two attributes take some optional arguments such as "Name" and "IsRequired".
  4. Define a message handler for the input message
    The sheer presence of such a GCD request message type won't bring us far. We have to do define a GCD request (I), and add this GCD request to list of requests understood by our service (II). Afterwards we have to set up a mechanism that whenever a GCD request is issued to our service, takes the message, which abstracts this request and acts accordingly (III). So defining a GCD request serive, involves defining what the incoming GCD request message body looks like and defining what the result of processing a GCD request is, may it be success or failure. The following lines of source code, added to the GCDServiceTypes.cs, define a ComputeGCD request type ...

    public class ComputeGCD :
    Query<ComputeGCDRequest, PortSet<GCDState, Fault>>{

    public ComputeGCD(int m, int n) :
    base(new ComputeGCDRequest(m, n))
    {
    this.Body.InputX = m;
    this.Body.InputY = n;
    }

    public ComputeGCD() :
    base()
    { }

    }

    The ComputeGCD request type, subclasses the Query<> type, and defines the incoming message to be our previously declared ComputeGCDRequest message and the result will be a GCDState on success and the pre-defined Fault on failure. A Portset is a collection of ports (a set of ports) and a port is just an abstraction that allows services to communicate with each other. So to signal that our GCDService actually understands the ComputeGCD type, we have to add this type to the GCDService service's operations port set, which is defined in the GCDServiceTypes.cs file.

    [ServicePort()]
    public class GCDServiceOperations :
    PortSet<DsspDefaultLookup, DsspDefaultDrop, Get, ComputeGCD>
    {}

    Now that our GCDService declares being able to understand GCD requests, we have to make him do so. More specifically we have to set up a message handler that jumps in whenever a GCDRequest is sent to our GCDService. The following lines of code, added to the GCDService.cs will be in charge of this.

    [ServiceHandler(ServiceHandlerBehavior.Exclusive)]
    public virtual IEnumerator ComputeGCDHandler(ComputeGCD computeGCD)
    {
    int M = computeGCD.Body.InputX;
    int N = computeGCD.Body.InputY;

    int gcd = ComputeGreatestCommonDivisor(M, N);

    this._state.GCD = gcd;

    LogInfo("=========\r\nGcdTest\r\n=========");
    LogInfo(string.Format("M = {0}\r\nN = {1}\r\nGCD= {2}",
    computeGCD.Body.InputX,
    computeGCD.Body.InputY,
    this._state.GCD));

    computeGCD.ResponsePort.Post(new GCDState(gcd));

    yield break;
    }

    The ComputeGCDHandler handler takes the ComputeGCD request as input and unwraps the necessary InputX and InputY fields from message's body. It then uses these two numbers as input to our ComputeGreatestCommonDivisor method, which computes the greatest common divisor and stores it in the gcd parameter. This gcd parameter is stored into the state of the service, which is of type GCDState. This GCDState encapsulates the state of the service, which is the greatest common divisor computed by the service. Actually the state is not really necessary, because we don't do much with it. At last, the message handler outputs the result of the operation to the output port for success, which was of type GCDState. The LogInfo calls are merely for debugging. Since this service alters its internal state, we have to make sure that this happens in an exclusive fashion, i.e. while updating the state no access to the state is granted. This is what the

    [ServiceHandler(ServiceHandlerBehavior.Exclusive)]

    Attribute declaration is for. It ensures that no race condition can occur by exclusively granting access to the internals our service.
  5. Define the GCDState type
    What is left, is to define what the state of our GCDService looks like. As mentioned, our service doesn't need to have a state but I have to decided to give it one (mainly for learning purposes). The GCDState type is define in the GCDServiceTypes.cd and can be modified like this

    [DataContract()]
    public class GCDState
    {
    private int _GCD;

    [DataMember(IsRequired=true, Name = "GreatestCommonDivisor")]
    public int GCD
    {
    get { return (this._GCD); }
    set { this._GCD = value; }
    }

    public GCDState()
    {
    this._GCD = 1;
    }

    public GCDState(int gcd)
    {
    this._GCD = gcd;
    }

    }

  6. Let's test
    Now that we have set things up. We are ready to build the service and test it. Therefore compile everything. Open the MRS Visual Programming Language to build a new test service using our GCDService. I have done that and the test service can be seen here (my GCDService is named "GreatestCommonDivisor").


I hope you enjoyed building this service as much as I did and I hope to have something ready for you asap.

Christian

Thursday, September 13, 2007

Online Lectures

Hi folks,

I found this link about online learning in video form on another blog and thought I could repost it here

http://videolectures.net/

so thanks goes out to

http://smart-machines.blogspot.com/

Both links are available in the sidebar.

Other online lectures


  1. http://www.researchchannel.org/prog/displayinst.aspx?fID=880

Christian

Saturday, September 08, 2007

Microsoft Robotics Studio - First Sight

Microsoft Robotics Studio (MRS)

I have recently come accross this great piece of new technology, offered for free by big MS [1]. MRS allows to program robots and other external devices via a visual programming language (VPL) or your prefered .NET programming language, such as VB.NET or C#. MRS main abstraction is a service.
Assuming you use VPL, a service is graphically represented as a box. Services exist in their own space and can be combined via message passing. In fact, services communicate via a SOAP-like protocol. This communication act is graphically represented by wires between services. Where such a wire connects the output of one service to the input of another. It is up to the developer of a service to decide what a service does, i.e. what kind kind of messages a service understands and what output a service produces. Therefore one can develop rather simple services such as a NoOP service, which does nothing, to a more complex service that for example takes a picture from a webcam. The great news is that MS ships MRS with a bunch of pre-built services, such as a Text-to-Speech service. This service takes some input message and renders it as its audio representive.
Since I have been able to play around with MRS, I wanted to share my first project, which calculates the greatest common divisor of two positive integer number m and n. Currently it is assumed that m is greater than n. The main routine that computes the gcd of m and n can be seen below here. As in yesterdays post, we make use of the fact that gcd (m, n) = gcd (n, r) where n = m % n and % is defined as the modulus of m and n. At the moment there is no swapping of m and n, in case n is greater than m (gcd (m,n) = gcd(n,m)). A possible example setting can be seen here. This example simply takes 10 and 5 as input and produces the expected output 5. I hope that this simple service will be one of many to come on my road to do cool stuff with MRS.

[1] Microsoft Robotics Studio: http://msdn2.microsoft.com/de-de/robotics/bb625969.aspx

Friday, September 07, 2007

Working the Snake - Python

I finally found my way to (Iron) Python[1][2] - well I did some Python in the beginning of my studies but lost focus after some time. The experience was quite impressive, since development time is greatly reduced by such a dynamic language. I managed to get some small programs running in less then 1 hour and of course I want to share them with you - precious audience. Since these are my first scripts, I assume that they are not quite correct/stable/... - they are simple and not very error-safe (no checking of arguments ) ...

The first is some simple factorial program, which tries to find the greatest common divisor (gcd)of two numbers by employing the fact that gcd (x, y) = gcd (y, r) where r = x mod y. Since I do not know how a scope for loops can be created (scoping a while/for loop) I did the routine recoursively. The second function builds on the first and is allows to ask whether some number x is a prime number by using the simple strategy of finding a gcd within the range of 1..root(x)


import System
def gcd(x,y):
  if y == 1 : return 1
  elif y == 0: return y
  elif x == y : return y
  elif x return gdc(y,x)
  n = x % y
  if n == 0: return y
  return gcd(y, n)

def IsPrime(x):
  if x == 1 : return 1
  elif x == 2 : return 1
  elif x == 3 : return 1
  tempsqrt = System.Math.Sqrt(x)
  tempsqrt = System.Convert.ToInt32(tempsqrt)
  for i in range(tempsqrt) :
  j = i + 1
  divisor = gcd(x,j)
  if divisor != 1 : return 0
  return 1


The second program is about the all time recursion favorite - the fibonaci numbers ...

the Fibonaci (Fib ) numbers are defined as follows

Fib(0) = 0
Fib(1) = 1
Fib(n) = Fib(n-2) + Fib(n-1)

example

n 0 1 2 3 4 5 6
Fib (n) 0 1 1 2 3 5 8
and here is the program - putting python suggar just around the exemplified formulae

import System
def Fibonaci(n):
  if n <= 0: return 0
  if n == 1: return 1
  return Fibonaci(n-2) + Fibonaci(n-1)

References:

[1] IronPython - www.codeplex.com/IronPython
[2] Python - www.python.org