Request the Google PageRank the Delphi way

In this post I am implementing the Delphi way to request the Google Toolbar’s PageRank (PR). As an example, if I want to look up the PR of my blog (http://www.yanniel.info/), I will have to query the following URL:

http://toolbarqueries.google.com/tbr?client=navclient-auto&features=Rank&ch=64012521073&q=info:http://www.yanniel.info/

So, if you try

Writeln(Curl('http://toolbarqueries.google.com/tbr?client=navclient-auto&features=Rank&ch=64012521073&q=info:http://www.yanniel.info/'));

You will get the following output:

Rank_1:1:0

Oops, at this moment my PageRank is pathetic (PR = 0). Hopefully it will get better someday ;-)

You can find the implementation of the Curl function in my previous post: Fetching a web page with Delphi.

Now that you get the idea, it’s time to generalize our implementation in order to get the PR of any web page.

In the URL above there are two dynamic parameters that we need to understand:

Parameter q: This is the concatenation of “info:” plus the encoded URL for which we want to get the PR. It is mandatory to lead the encoded URL with “http://”. Don’t forget to put a “/” after the top domain, ei, “.info/”, not “.info”.

Parameter ch: Obtaining this parameter is the tricky part. We have to hash the concatenation of “info:” plus our target URL (ei. http://www.yanniel.info/) using the minimal perfect hashing algorithm invented by Bob Jenkins. The outcome will be a number, which corresponds to the value of our ch parameter. We are hashing something like “info:http://www.yanniel.info/”.

I didn’t have the time (or the desire) to understand and implement the minimal perfect hashing algorithm from scratch. So, I ported this C# implementation into Delphi code.

There’s one detail worth mentioning about the implementation. In the original C# code there’s a switch statement that falls all the way through the different cases. I needed to combine a case statement and some goto statements in order to accomplish the same in Delphi. Really, I tried to avoid the goto, I always do, but I couldn’t find a better and cleaner way of implementation. I was telling myself how bad programmer I was, and then, I read one entry in Delphi Feeds talking about the minimal perfect hashing algorithm, and more than that, highlighting the goto issue. Nick Hodges wrote the post: thank you Nick... now I can sleep again.

It seems that I am not the only one considering this goto usage as an exception to the good practice of “don’t use goto statements”. The funny thing is that I read Nick’s post without the intention of finding anything about the minimal perfect hashing algorithm or about the goto stuff. It’s really a big coincidence that we were considering to write about the minimal perfect hashing algorithm (and the goto gotcha) at the same time.

I wrote the strikeout text above initially; but Brian (first comment below) found a clean way to avoid the goto in this situation. I really thank Brian for his contribution, and next time, I won't quit that easily in removing the goto ;-)

I am putting everything together in the Delphi console application below. I bet you can reuse the BobJenkinsHash function in the Generics.Default.pas unit to make the PR implementation more compact. I didn’t know about the BobJenkinsHash function shipped with Delphi before reading Nick’s post; which is why I am keeping my original implementation.      

Finally, this is how you request the Google PageRank in Delphi:

Pascal Server Pages – Pascal Script

Without getting too technical, I would define a Pascal Server Page (PSP) as a dynamic web page containing embedded Pascal Script (PS) code.  When a web request is made, the PS code needs to be executed (interpreted) in the server side and outputted into the proper format (HTML, XML, JSON, text, etc). A PSP is commonly stored as a text file in the Web Server and it could be a mixture of PS code plus any other static content.

This is an example of PSP:

<html>
  <head>
    <title>This is a Pascal Server Page</title>
  </head>
  <body>
    <% begin
         Write('Hello World');
       end.
    %>
    <p>I am going to use Pascal Script to write a few numbers...</p>
    <% var
         i: Integer;
       begin
         for i:=1 to 10 do
           Writeln(i); 
       end.
    %>
  </body>
</html>

The code above is an HTML armature containing some PS code. The PS code has been isolated within the “<%” and “%>” tokens. The PS code is executed in the server and the output (if any) is embedded into the HTML template.

So, if a browser asks for the page above, it will actually get plain HTML code as the one below:

<html>
  <head>
    <title>This is a Pascal Server Page</title>
  </head> 
  <body>   
    Hello World
    <p>I am going to use Pascal Script to write a few numbers...</p>
    1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>
  </body>
</html>

This is all good. The only problem is that the PS code is not going to be magically executed. We need a server side component to do the PS interpretation.

I have seen a couple of intents to build such server side component in the Internet. Anyhow, I bring you my own proposal: create a Web Broker application with Pascal Scripting capabilities. To provide the Web Broker application with the scripting capabilities, I will use Pascal Script from RemObjects. You need to download and install Pascal Script if you want to try my code. 

The workflow goes as follows:
  1. The Web Broker application receives a Web Request.
  2. The Web Broker application finds the corresponding Pascal Server Page and loads its content to a buffer variable.
  3. The content of the buffer variable is parsed in order to find the PS tokens (I will use RegEx to do the parsing).
  4. Each PS block is compiled to Bytecode and then executed in the server. (I will use the Pascal Script library from RemObjects for this purpose). 
  5. The output generated from the execution of each PS block replaces its corresponding “<%......%>” block.
  6. The Web Broker app serves the response.
I developed a VCL standalone Web Broker application as a proof of concept (it could be an ISAPI dll as well). See it in action in the following video:



That application is just a prototype. I really believe that we could build a robust server side component to leverage enterprise Pascal Server Pages. I used Web Broker in this example, but we could also build Apache Modules with Free Pascal.

I am posting below the code of the TWebModule1 class, which is the core of the Web Broker app. The full source code and executable can be downloaded here. (the code was compiled with Delphi XE2). Note that the code is somewhat messy; this was taken directly from my sandbox. Ah, I copy-pasted (and adjusted) the Pascal Script routines from this example: Introduction to Pascal Script.

Salary Guide for Delphi developers: Let’s make it

If you work as an IT professional in North America, you should probably find very useful the 2012 Technology Salary Guide published by Robert Half Technology.

This guide exposes the compensation trends (salary trends) for pretty much every position in Information Technology. It covers the United States of America and Canada, and you could even obtain salary ranges for particular cities.

This guide is useful for both managers and non-managers individuals. In my particular case, I am always curious to know if I am getting paid decently.

The tables below are an excerpt taken from the guide:

 2012 Average Starting Salaries – United States

Job Title
2011
2012
% Change
Software Developer
$ 65,750 - $ 104,250
$ 70,000 - $ 111,000
6.5%

2012 Average Starting Salaries – Canada

Job Title
2011
2012
% Change
Software Developer
$ 56,250 - $ 94,000
$ 59,750 - $ 99,750
6.2%

There are further statistics in the guide about Java, .NET, C++, PHP and other programming languages. You can use that info in order to tune the indicators above even more. There are no details about Delphi in this guide.

I think that we (the Delphi community) could gather some statistics about the salary rates for Delphi Developers. I propose running poll surveys to gather such information. Once the polls are closed, we will publish the outcomes and we can draft our conclusions.

The polls are finally closed. Go to the end of this post and take a look at the outcomes. Thanks a lot to all the participants: 45 in the United States and 30 in Canada. It’s funny how the number of voters was a multiple of 5 in both countries :-)

Take a look at the right column of this page: I have published two polls to collect the information about the salary rates in the United States and Canada. I am only putting together the data for these two countries, because I already have some reference data to compare with. (I am referring to the data in the tables above). It would be really nice if someone else could take ownership of similar polls for other countries.


Important:
  • I will kindly ask to vote, IF and ONLY IF, you are (were) working as a Delphi Developer in the United States or Canada during the current year 2011.
  • We could make this better if you enroll your coworkers or any other Delphi developers in your area.
  • The poll is by nature anonymous: we are just gathering collective information.
Please, in order for this to work we need your vote!

What’s the salary for a Delphi Developer in the United States?

< $ 50,000                               5  (11%)
$ 50,000 - $ 60,000                 2  (4%)
> $ 60,000 - $ 65,000              1  (2%)
> $ 65,000 - $ 75,000              7  (15%)
> $ 75,000 - $ 85,000            12  (26%)
> $ 85,000 - $ 95,000              4  (8%)
> $ 95,000 - $ 105,000            5  (11%)
> $ 105,000 - $ 115,000          4  (8%)
> $ 115,000                             5  (11%)
                                                   
What’s the salary for a Delphi Developer in Canada?
                                                 
< $ 50,000                               6  (20%)
$ 50,000 - $ 60,000                 5  (16%)
> $ 60,000 - $ 65,000              2  (6%)
> $ 65,000 - $ 75,000              3  (10%)
> $ 75,000 - $ 85,000              2  (6%)
> $ 85,000 - $ 95,000              1  (3%)
> $ 95,000 - $ 105,000            5  (16%)
> $ 105,000 - $ 115,000          1  (3%)
> $ 115,000                             5  (16%)

Generating Fibonacci numbers in Delphi: Recursive and iterative algorithms

In this post, I want to implement a function that returns the Nth Fibonacci number. Initially, I will provide a recursive implementation that derives directly from the Fibonacci sequence definition. Afterwards, I will recode the same function using an iterative approach.

Why do I want to do (share) such a thing? Well, firstly for fun :-) and secondly, because I was asked to do something similar in one phone screen interview. Really? Yep, I was asked to code a function to return the factorial of a number and then, I had to read it over the phone. I implemented the recursive algorithm. At this point, I was asked why I decided to use recursion as opposed to iteration. My answer was that I find the recursive implementation easier (and cleaner) to write. The interviewer finally inquired me about the iterative implementation…

This motivated me to resolve similar programming tasks (recursively and iteratively) just as a training exercise. 

Well, enough with that blah, blah, blah.

Taken from Wikipedia:  

The Fibonacci numbers form a sequence of integers, mathematically defined by


    F(0)=0; F(1)=1; F(n) = F(n - 1) + F(n - 2) for n > 1.


This results in the following sequence of numbers:


    0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, ...

This simply means that by definition the first Fibonacci number is 0, the second number is 1 and the rest of the Fibonacci numbers are calculated by adding the two previous numbers in the sequence. 

Translating that into Delphi code:

function Fibonacci(aNumber: Integer): Integer;
begin
  if aNumber < 0 then
    raise Exception.Create('The Fibonacci sequence is not defined for negative integers.');

  case aNumber of
  0: Result:= 0;
  1: Result:= 1;
  else
    Result:= Fibonacci(aNumber - 1) + Fibonacci(aNumber - 2);
  end;
end;

The function above is the recursive implementation, which in my opinion fits naturally. Now, the iterative implementation might not be as cleaner as that:

function Fibonacci(aNumber: Integer): Integer;
var
  I,
  N_1,
  N_2,
  N: Integer;
begin
  if aNumber < 0 then
    raise Exception.Create('The Fibonacci sequence is not defined for negative integers.');

  case aNumber of
    0: Result:= 0;
    1: Result:= 1;
  else
    begin
      N_1:= 0;
      N_2:= 1;
      for I:=2 to aNumber do
      begin
        N:= N_1 + N_2;
        N_1:= N_2;
        N_2:= N;
      end;
      Result:= N;
    end;
  end;
end;

Finally, if you want to produce the first 21 Fibonacci numbers try this out:

program Project2;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

var
  I: Integer;

function Fibonacci(aNumber: Integer): Integer;
begin
  {Your implementation goes here}
end;

begin
  for I:=0 to 20 do
    Writeln(Fibonacci(I));
  Readln;
end.

Hopefully you are not bored to death :-)

Internationalizing your Delphi application: An ABC example

If you want to make your Delphi application general enough to address multiple locales, then you need to internationalize it. There are three common aspects that I want to emphasize (no necessarily in that order):
  • Resourcing
  • Unit conversions
  • Dynamic messages
We’ll cover the three of them with a very simple example. Consider the following code snipped intended for the en-US locale (English-United States of America):

procedure TForm1.DefineFever;
begin
  ShowMessage('If the body temperature rises above 99°F the person is considered to have a fever.');
end;

Resourcing is the process of removing hard-coded strings from the code by making them resourcestrings instead.

The code above is not localizable because the ShowMessage procedure is taking a hard-coded string. What do you do? Take a look:

procedure TForm1.DefineFever;
resourcestring
  strFeverDefinition = 'If the body temperature rises above 99°F the person is considered to have a fever.';
begin
  ShowMessage(strFeverDefinition);
end;

We defined strFeverDefinition as a resourcestring and used it as a parameter for the ShowMessage procedure. The functionality remains the same, but the function is now localizable.

Unit conversions: In some countries (like the United States and Belize) the temperature is given in the Fahrenheit scale, but in the rest is given in the Celsius scale. In order to internationalize this we can do the following:

function GetFeverTemperature: string;

var
 
LangID: LangID;
begin
  //By default
  Result:= '37.2°C';

  {read current system locale}
 
LangID := GetSystemDefaultLangID;

  //Assuming that only the United States and Belize use the Fahrenheit scale
  if (
LangID = {English - United States} 1033) or        
     (LangID = {English - Belize} 10249) then
  Result:= '99°F';
end;

procedure TForm1.DefineFever;
begin
  ShowMessage('If the body temperature rises above ' + GetFeverTemperature + ' the person is considered to have a fever');
end;

Wait a minute, we managed the unit conversion by introducing a dynamic message, but we reintroduced the hard-coded strings. That’s not good!

Dynamic messages: We consider the ShowMessage above to be a dynamic message, because the parameter depends on the GetFeverTemperature function, which of course can vary. 

To solve the pitfall above we can refactor the DefineFever function as follows:  

procedure TForm1.DefineFever;
resourcestring
  strFeverDefinition = 'If the body temperature rises above %0:s the person is considered to have a fever.';
begin
  ShowMessage(Format(strFeverDefinition, [GetFeverTemperature]));
end;

We are just using a format string (resourcestring) that we can format by using the Format routine. This allows resourcing and handling the dynamic message all at once.

The thing about dynamic messages goes beyond. In Spanish, for instance, the dynamic message would have been coded as follows:

ShowMessage('Se considera que la persona tiene fiebre si la temperatura corporal es superior a ' + GetFeverTemperature);

Note that the GetFeverTemperature is at the end of the ShowMesssage parameter, as opposed to the English implementation that has it in the middle. There’s no way you can localize something like this if you don’t internationalize it first.

So the ABC for Delphi localization is Resourcing, Unit Conversions and Dynamic Messages.