Friday, September 25, 2009

Defining my laptop computer's wireless IP settings

My company gave me a laptop computer a few months ago, primarily to help me when I visit the company's various sites, which are spread out across the country. All of these sites have a wireless network, which requires the computer's wireless network card to be defined as DHCP. No problem.

The problems begin when I get home and I want to use the mobile computer; the kibbutz network requires fixed IP addresses. So far, I've been accessing the network card's settings and changing them manually. This is getting to be a drag, and today I learnt how to build two batch files which will set the values automatically. These files don't execute any quicker than setting the values manually, but they're much easier.

First of all, here are the commands necessary to set the wireless card to use DHCP:
netsh interface ip set address name="Wireless Network Connection" source=dhcp
netsh interface ip set dns name="Wireless Network Connection" source=dhcp

I created a batch file called 'dhcp.bat' and added those two lines to the file.

Setting the fixed ip addresses was a bit more complicated, because there are more values to list, and because I need two dns addresses (by experiment, it seems that the secondary dns server would seem to be more important than the primary, but this may change).
netsh interface ip set address name="Wireless Network Connection" static 10.0.90.82 255.0.0.0 10.0.0.1 1
netsh interface ip set dns name="Wireless Network Connection" source=static addr=212.117.128.3 register=primary
netsh interface ip add dns name="Wireless Network Connection" addr=212.117.129.6 index=2

Note that the first line (set address) has three different addresses: the first is the address of the wireless card, the second is the mask and the third is the address of the gateway. Following these addresses is a parameter "1". It seems that the command processor is prepared to read the values without the need to specify what they are. Alternatively, this line could be written in full as
Netsh interface ip set address name=”Local Area Connection” source=static addr=10.0.90.82 mask=255.0.0.0 gateway=10.0.0.1 gwmetric=1

As I never use a network cable to connect the laptop to the kibbutz network, I can leave the settings of the standard network card as dhcp.




Saturday, September 19, 2009

The Girl with the dragon tattoo (two)

I've had more thoughts about this book, no doubt precipitated by the review of the Hebrew translation which appeared in yesterday's newspaper (the translation has curiously lost its definite articles, so it is now "Girl with a dragon tattoo") as well as cogitation about some of the Amazon reviews. Such reviews are torn between the desire to tell what the book is about (so that people will know whether the subject interests them) and the need to review (criticise and praise) the writing. Here I have no such problem: I don't need to tell the story and I can give as many spoilers as I want.

One person wrote about how the characters don't develop (surely, one of the tenets of fiction is that at least one character has an epiphany which changes how she feels about life and coincidentally helps her provide the story with a resolution). Another reviewer noted in response that in real life, people don't really change. Whilst that is mainly true, I know that I am trying to change, or at least deepen my understanding of what is happening around me in the hope that I will be able to impress myself more on the environment, or have the environment impress itself less on me (current book "Predictably Irrational" by Dan Arieli, which I was given as a New Year's gift yesterday). Going back to the matter at hand, Lisbeth Salander, the eponymous girl with the dragon tattoo, does change, although that doesn't seem to affect the story's resolution.

The real problem with the book is that it's really two stories in one. Now, I know that a good book has a plot and a sub-plot, but this one has two plots, neither of which is dominant to the other, and this is what caused the feeling of anti-climax at the end of one of those plots. The book could either have been about the search for Harriet Vanger, or it could have been about the shady financier Wennerstrom. The background material (whilst overly done) fits into both stories equally well. The only links between the two stories (apart from the characters) is Henrik Vanger's desire to bring Wennerstrom down, and his feeble promise about the material necessary to do so.

True, protagonist Mikael Blomkvist was lured into the Vanger plot by being promised the hot material on Wennerstrom, and his actions in the Vanger plot lead to him linking up with Salander, but otherwise the two plots have nothing to do with each other.

Ian Rankin, in his Rebus novels, usually has three or even four plots runnning in the book, but they run in parallel and are solved simultaneously by the end of the book. This has often given me a deux ex machina feeling about some of the stories; whilst I know that life - and especially police work - is not so simple, in that plots run into each other with no apparent beginning or end, and can run side by side (but not necessarily in tandem) for years, I am aware of literary constraints which demand that most (if not all) loose ends are tied by the end of the book. I often wondered what would happen if Rankin (or Peter Robinson, or any other detective novelist) would introduce a thread which does not get solved by the end of the book.

Steig Larsson has written a book with two concurrent but non-parallel plots; whilst both plots have conclusions, they are not simultaneous. So this book answers in part my query about how such a book would feel. And having read this book, I now know the answer: due to literary conventions and the escapist need to have a complete ending, I prefer Rankin with his multiple and parallel plots which finish simultaneously.

Thursday, September 17, 2009

The Girl with the Dragon Tattoo

I, too, have read this book. Amazon has been pushing it at me for some time, so eventually I decided to order it.

I am in two minds as to how to rate the book. The first two hundred or so pages were quite heavy going, with too much exposition and a frequently irrelevant depth of detail: for example, the description of Salander's employer, or the passage describing the destruction of her first laptop and her subsequent purchase. Characters were introduced who had no connection with the story and could easily have been edited out. Whilst I understand the necessity to describe what happened between Salander and her second guardian, in order to improve her characterisation, this section was too vivid, too long and too brutal (mirroring to a certain extent something which takes place towards the end of the book).

But after the two protagonists meet, sparks begin to fly and the pace hots up considerably. Once the major problem has been solved, the last hundred pages or so seem like an anti-climax, although actually this part is much more rewarding and could have been made into a novel by itself.

Reviewers on Amazon have mentioned unlikely coincidences, but almost all fiction depends on such devices. The skill of the author is measured in how believable he can make those coincidences, and I think that the late Steig Larsson managed quite well in that respect.

Sunday, September 13, 2009

Using dbExpress - conclusions

I've just discovered that if one googles "Porting BDE", the first few entries reference this blog! It transpires that someone has been following my jottings and posting them on the Firebird site. At the moment, I've converted about 20 forms, and the conclusions resulting from these conversions are becoming clear. I don't expect to post any more on the subject, unless I run into a staggering 'gotcha'.

When porting the contents of the database itself, the TSqlQuery should be used with the following statement: insert into values (:p1, :p2, :p3, etc). In the delphi code, one writes as follows:
with SqlQuery1 do
 begin
  close;
  parambyname ('p1').asinteger:= ...
  parambyname ('p2').asstring:= ...
  parambyname ('p3').asdate:= ...
  execsql;
 end;
A date parameter has to be passed AsDate, not AsDateTime. Apparently this is a bug in dbExpress.

In applications, I have discerned three different cases in which previously I would have used a BDE tquery component. These are:
  1. For statements which update or delete from a table and for statements which return one or more values which will not be displayed via a data-aware component, a TSqlQuery component can be used which simply replaces the TQuery on almost a one-for-one basis.
  2. For DBLookupComboBoxes, one can use the SimpleDataSet component, not forgetting to set the 'connection' property to the global connection. This component is considered to be deprecated and not to be used, although I have found that for this simple use (and also for a dbgrid from which values are chosen), it's easier to use this than the 'holy trinity'.
  3. Whenever data-aware components are used, the 'trinity' must serve them. The trinity consists of: a SQLDataSet (which is linked to the global sql connection), a DataSetProvider and a ClientDataSet.
I have also developed a new template for data editing forms. Once I would write as follows:
function TEditDiag.Execute (n: longint): boolean;
begin
 with qEditDiag do
  begin
   close;
   if n = -1 then
    begin
     open;
     append;
     caption:= 'Adding'
    end
  else
    begin
     params[0].asinteger:= n;
     open;
     caption:= 'Editing';
    end;
   edit;
   if showmodal = mrOK then
    begin
     result:= true;
     post
    end
   else
    begin
     cancel;
     result:= false
    end;
   end
 end;
The above code takes advantage of the fact that the BDE has autoincrement fields, and so one doesn't have to explicitly create a new key. FB does not have such fields, and so the use of a generator is required. The above code is now replaced with the following:
function TEditDiag.Execute (n: longint): boolean;
var
 gen: longint;

begin
 sdsEditDiag.commandtext:= 'select * from minidiag where id = ' + inttostr (n);
 with qEditDiag do // clientdataset
  begin
   open;
   if n = -1 then
    begin
     caption:= 'Adding';
     insert
    end
   else caption:= 'Editing';

   edit;
   if showmodal = mrOK then
    begin
     result:= true;
     if n = -1 then
      begin
       with qGetID do // get new id number from generator
        begin
         open;
         gen:= fieldbyname ('gen').asinteger;
         close
        end;

       FieldByName ('id').asinteger:= gen
      end;
     post;
     applyupdates (0)
    end
   else
    begin
     cancel;
     result:= false
    end;
   end
 end;

Friday, September 11, 2009

Sandy Denny in "Ma'ariv"

I wrote two weeks ago about an article in the Israeli newspaper "Ma'ariv" about Nick Drake. In today's arts supplement, it was the turn of Sandy Denny. Whilst it's true that there's no such thing as bad publicity, this article was so inaccurate that I became very annoyed. Instead of writing about the classic Denny songs, her participation in Fairport's groundbreaking "Liege and Lief" and her twice winning the "Melody Maker female singer of the year award" (1970/1), we got to read about her drinking and smoking (twice), her husband who ran off with her infant baby and a little about her "fall down the stairs". Naturally "The battle of Evermore", the first (and only?) Led Zeppelin track to be recorded with someone outside of LZ was mentioned.

The final nail in the coffin? The "fact" that Sandy's best song was "Listen to the song of the sea". Excuse me? I've never heard of such a song. To be fair, it might be a problem with copyediting and punctuation marks, in which the sentence becomes "Listen to the song 'The Sea'". Whilst I have no problem in considering this Fotheringay song as one of her best, I wouldn't consider it to be the best.

I fired off an angry and frustrated letter, but I don't expect to receive any reply. I certainly didn't get one after the Nick Drake article. I even offered to copy edit any future articles about Witchseason artists, figuring I probably know more about them than anyone else in Israel.

Tuesday, September 08, 2009

Richard Thompson - You?Me?Us?

I had a long (for me) car journey yesterday, two and a quarter hours in the morning and two and a quarter hours back in the afternoon. For accompaniment, I brought with me the above Richard Thompson disc as well as an mp3 disc. Unfortunately, the car cd player wouldn't play the mp3 disc, so I listened to RT all the way.

Although this is nominally a double cd, both sides are quite short (about 37 minutes) and theoretically could have been put together on one disc. RT didn't do that, because the two discs are in different styles: the first, subtitled "voltage enhanced", features the electric guitar, whereas the second, "nude", features the acoustic. The contrast wouldn't provide for a good sequencing flow, although the closing track on the first disc, the lovely "The ghost of you walks", serves as a good bridge between the two styles.

I remember writing in 1996, which is when the disc was released, that the 'nude' disc was the album I had been waiting 15 years for, as it features several on top form RT songs. I wasn't so enamoured though with the electric disc and have played it infrequently over the years. Yesterday was a good chance to listen to it again.

What impressed me the most was that it's almost as if Richard was trying out different styles of songwriting. The 'nude' songs are conventional in their structure (although again, there are a few songs which sound like songwriting exercises, especially "Train don't leave"), but most of the 'voltage enhanced" songs have no counterpart in the RT canon. After thinking about it, I was able to narrow the differences down to a few stylistic changes in the music:
  1. Many of the songs have repeated lines: for example, the chorus of "Dark hand" has the line "There's a dark hand" repeated six times before the closing "over my heart" completes the sentence. "Business on you" again has several triplet repetitions of "I'm going to do the business on you" before the payoff line of "I've got all the magic I need". The repeated lyrics are set to the same melodic lines, so it's as if the song's progress gets stuck in a loop. Whilst "other" music features this quite often (think of the 12 bar blues as an early example, or the "three times and you're out" petite reprise on many Beatles songs), it's a rarity in RT's songs.
  2. The first few songs don't have conventional harmony, especially "She steers by lightning". Following this is "Dark hand", which too begins with a dynamic bass line over the same chord.
  3. There are songs which hold the I chord for a very long time - the verse of "Business on you" is a good example of this, as is "Am I wasting my love on you?".
  4. There is one explicit example of a slow burner 12/8 - "Bank vault in heaven".
The musical side of Richard Thompson's songs have always been off the beaten track. Whilst some may not have sophisticated harmonic progressions (I'm thinking of the lovely "Withered and died"), they have always featured chord progressions, and normally display a harmonic rate of change at about one chord per bar. There has always been a mix of 4/4 and 3/4 songs, but extremely few in 12/8.

The result of these experiments is that the songs are much more commercial (for want of a better word), more familiar to the ear of the common listener (who isn't aware of the 'guitar as bagpipes' sound of RT). The electric guitar and mandolin duet in "Business on you" probably sounds fresh, exciting and exotic to those ears, whereas to the cognoscenti it sounds like a rehash (albeit a brilliant one) of "When I get to the border".

Interestingly, the two songs which feature on both discs, "Razor dance" and "Hide it away", feature none of the characteristics which I have noted. "Razor dance" is quintessential RT; the acoustic version sounds like a demo for the electric version. "Hide it away" is slightly off the beaten RT track, although its roots can be found in a few songs on the preceding "Mirror Blue" album. Again, I think that the electric version is better than the acoustic, although this time they are arranged differently: the electric version sounds like a Burt Bacharach smoocher (is that electric piano or electric guitar providing the chordal accompaniment?), whereas the acoustic version is rougher and features a double bass solo.

The lyrics are interesting and inventive throughout both discs and have no relation to the musical experiments to which they are set. As a result, the lyrics of "Business on you" or "Am I wasting my love?" are far better than their music, a rare occurrence in an RT song, where music and lyrics are normally at a high and equal level.

Saturday, September 05, 2009

More porting issues

Saturday morning, 7:30 am. I'm sitting on the small balcony outside our house writing this on a mobile computer. It's very quiet; the only sounds I hear are the birds twittering in the tree and the occasional child. The dog and I have already been out for our walk. I'm using the mobile because my main computer is "in hospital": it's been conking out after about 30 minutes of use. Obviously the fan in the power supply is causing problems. Actually, according to the repairman, the fan is fine; the insides of the computer are full of dog hairs....

I am in the process of porting my flagship program from using the Borland Development Engine (BDE) to Firebird; I want to write about some of the "gotchas" which I've come across in the past few days, things which one doesn't read about in the various texts. Actually, the issues have nothing to do with Firebird and everything to do with the dbExpress components which I am using to connect to the Firebird server.

As any Delphi programming book which covers the topic will tell you, the dbExpress components are uni-directional; this makes them simpler and less demanding of system resources, but it also makes them problematic for someone used to the BDE query component. Here are two problems which I've come across.

1. Recordcount
The 'recordcount' function of a query gives the number of records which have been returned by the query, as its name might suggest. I use this function in two different ways: most times, I set a progress bar's length to the number of records returned so that the user can have feedback via the progress bar how the computation is progressing. Very important when there are 3000 records to be processed.... Less frequently, I use the function to see whether the query even returned a record set, in order to do some more computation.

The dbExpress TSqlComponent has a 'recordcount' function, but unfortunately most of the time it doesn't work. The documentation states that there is no function when the query is called with parameters or when it is a multi-table query (there is also a third case but I don't remember what it is). This means that the recordcount function is fairly useless, as it is extremely rare that I will program a function which uses only one table and has no parameters (it turns out that I do have one such query in my program, 'select key from table'). So how does one solve the problem?

When I initially want to see whether the query returned a record set before processing, I now use the 'eof' function; if 'eof' is true after opening the query, then there is no record set. Simple.

As for getting the number of records returned, the only solution which I've found is to define another query, the same as the original but simpler, which returns 'count (*)' instead of actual fields. After opening the query, the value of the aggregate is passed to the progress bar.

2. Sorting a record set displayed in a dbgrid by clicking on column titles
Delphi's dbgrid component exposes a method which is called when a column title is double clicked. I use this method in order to sort and display the record set, according to which column is clicked. The first gotcha which came when porting this was that the column array is now zero based instead of one based; this is strange as it has nothing to do with porting to dbExpress. It only became clear when clicking on one column caused the grid to sort by a different column.

In BDE programs, the query component connects to the database on one side and to a datasource component on the other side. Sorting the data required closing the query, changing the SQL statement to order by a different field and then reopening. Fairly simple. But when using dbExpress components, life is more difficult: the database is connected to a TSqlConnection which is connected to a TSqlDataset which is connected to a TDatasetProvider which is connected to a TClientDataset which is connected to the TDatasource which is connected to the dbgrid. The SQL statement which chooses the data is in the TSqlDataset, which is then buffered by the TClientDataset. It occurred to me that it would more efficient to acquire the data once from the database, and then sort it in memory via the TClientDataset ('cds').

In order to do this, I predefined several indices in the cds, each corresponding to a column to be displayed; some of these indices contain two fields, and some are defined as descending indices.

Now, when a column title is clicked, I simply change the index used in the cds, and hey presto! the grid is displayed, sorted by the new index. This is very fast as there is no need to reaccess the database.

Here is the code for the event (qPeople is the cds):

procedure TMainForm.DBGrid1TitleClick(Column: TColumn);
begin
 try
  dbgrid1.columns[prevcol].title.font.color:= clNavy
  except
 end;
with dbgrid1.datasource.dataset do
 begin
  column.Title.Font.color:= clRed;
  prevcol:= column.Index
 end;

with qPeople do
 try
  disablecontrols;
  close;
  case prevcol of
   0: indexname:= 'idx_date';
   1: indexname:= 'idx_zehut';
   2, 3: indexname:= 'idx_name';
   4: indexname:= 'idx_company';
   5: indexname:= 'idx_matara';
  end;
  open
 finally
  enablecontrols
 end;
end;