Tuesday, September 29, 2020

Birthday (song)

About a month ago, I was considering which song I would choose for the Yom Kippur song evening, should it take place. Originally I was going to use 'I like the sound of falling rain', but at some stage I heard the song 'Birthday' by Chani Livneh, which is a song that I have always liked since I first heard it in about 1986, but had long forgotten.

Finding the words wasn't a problem but working out how to play it was more complicated. Although Livneh wrote the song, it shows the arranging chops of Matti Caspi. Somewhat unusually, it's in 3/4, but there seem to be a few 'hiccups' in the B section of the song. After listening to the song in order to learn it, I noted that it is has an opening section starting on Am and finishing on G; this section is repeated, having two bars merged into one towards the end and then finishing on Gm. The B section starts off with a descending bass line played twice before leading into an ascending bass line - this section is quite weird harmonically as apart from the bass line (Gm - Eb - Gm6 - Gm7), the tune spends most of its time on A, making the opening chord Gm9. The B section is repeated, but like the A section, the second time around is subtlely different from the first time.

Eventually I had the chords and melody sequenced, more for reference purposes than as part of the final arrangement. I worked on various approaches, finally arriving at something suitable; it's not exactly how I had intended, but it's not bad. I ignored the rhythmic hiccup in the B section by extending the sung note as opposed to shortening the bar.

Singing as usual was problematic; unlike my usual recording technique, I sang to a version in which the tune was playing, in order to aid my accuracy. I think that a few takes were required after which parts were taken in order to compile a complete version. I had more difficulty than usual in achieving a good vocal sound; unusually I didn't use any reverb but rather a short analog delay that sounds good for most of the time (there are a few staccato notes where it does not sound so good).

I don't know whether this version will ever see the light of day.

Following is a translation of the lyrics (mainly Google translate with some additions and corrections by me)

The cake is in the oven, the candles are all ready, 
A birthday is not just for children. 
And I was sad when I thought in the morning, 
How I have passed my years? 
My pockets are empty of surprises. 
Smiles are not something that come too easily, 
And outside the sun is shining whereas for me, another groove [on my face] is engraved. 
And for the hundredth time I see how I have lived my life in a tunnel of darkness. 
The candles on the cake quietly light up the time. 

And now is the time. God, give me strength 
To stop the minute race on the clock,
To watch and breathe as the grass grows, 
And to get up and sing in his honor. 
And now I know clearly: The greatest gift that can only be taken, 
It's the same feeling when you're seeing for the first time 
That the sun has never shone like this 
And the rain has never sounded so beautiful, 
The candles on the cake give me light as a gift.

Saturday, September 26, 2020

Priority procedures cross-referencer


I spent a few hours on Thursday evening, more than a few hours yesterday and several hours today working on the Priority procedures cross-referencer and hopefully completing it.

As in the army, everything divides into three. For this program, the first stage is parsing the input file, then displaying the references and finally displaying the analysis. The first stage can also be split into three: the tokeniser, the lexical analysis and the storage. A token is a string extracted from a text file; for example, if the current line is 'select part, partname from part', then there are five tokens: 'select', 'part', 'partname', 'from' and again 'part'. In programming languages with regular syntax, the tokeniser is normally quite straight-forward, but it turns out that the procedural SQL language of Priority does not have regular syntax and cannot be considered to be context free.

Two examples of the ad hoc syntax: I want to note when a variable is initialised and when it is not. Initialisation can occur in one of two forms: either there is an equals sign after the token (e.g. :SEARCHNAME = '12345') or the keyword INTO precedes the token (e.g. SELECT DAY INTO :DAYS). These two opposite options (one prefix and one postfix, to use the technical terms) make it complicated to program. Another syntactic problem is the colon - :. Normally this serves to mark variables, e.g. :DAYS, but it can also be used to separate between two clauses in a ternary comparison (e.g. :DAYS < 7 ? 3 : 5). 

The correct tokenisation of table aliases (e.g. GENERALLOAD F1) took quite a bit of time.

Storage of the identifiers and their references is by means of a binary tree; this part was based on the cross referencer that I found a few days ago which was written in standard Pascal. The references are stored in a queue for each node. I added a few fields to these variable types in order to store further information: the type of identifier (variable, cursor, table) and the operation in progress at the reference (e.g. variable initialisation, opening a cursor, linking a table). This part was simple. Displaying the references was also fairly straight-forward.

The analysis part is dependent on the type of identifier: there are certain checks for variables, certain checks for cursors and certain checks for tables. I found a method to make these checks as stream-lined as possible.

I tested the program by running it alternately on a short test file into which at times included deliberate errors (so that I could check that the errors were being picked up) and on the file for the procedure that I wrote a few days ago. Every time I would look at the references, noting mistakes that had to be fixed. Now I'm 99% confident that I've correctly parsed the files and have correctly denoted variable initisalisation (this was very complicated). Running the finished program on my procedure finds three variables that were initialised and never used. These can be safely deleted from the procedure.

My next step is to publicise the program within a small community, inviting examples of procedures whose analysis appears to be wrong. Maybe there are other checks that need to be added.

Friday, September 25, 2020

Accordion

After losing out on the dulcimer a few weeks ago, I came to realise that one of my hobbies is collecting musical instruments. I ran a search on Ebay later and came up with this gem, a Stephanelli miniature accordion. The price with postage was about £45, which was the winning price for the dulcimer. 

The accordion arrived a week ago, securely packed, and has now taken its place of honour in the music room, next to the concertina. In a few years, I'll try and teach one of my grandchildren how to play it.



Thursday, September 24, 2020

Return to lockdown - keeping myself occupied with new programming projects

Due to the high number of people being found positive for Covid-19 in Israel and the exponential rate of increase, it has been decided that some form of lock down will be enacted over the next few weeks. In a sense, this isn't much of a problem, as Monday is Yom Kippur, which means that Sunday wouldn't be a work day for most people. Then the week after that is 'the festival of booths', during which many people don't work anyway. At the time of writing, I don't know whether my company is to be closed or to work in some reduced form, so I don't know what will happen to me next week.

One way or another, I'm going to have plenty of spare time on my hands. Just as well, as I have two programming projects that I want to execute during this time. The first is an update of one of the OP's multilingual exams - there are problems running this with Windows 10. I started examining the problem last week in a modern version of Delphi; I think that I know what the problem is but I haven't had the time to do anything apart from thinking about the problem. I'm fairly certain that there is interference between the use of a string table resource file and the clientdataset component. If I can't find a simple resolution, I may have to abandon the clientdataset, instead outputting 'rich text' files that will somehow have to be combined to create a final output file.

The other project is quite grandiose: over the months, I've collected various mistakes that I have made whilst programming procedures in Priority and that were not noted by the in-built syntax checker. The idea is to check things that are not caught by the internal program, to supplement it and not replace it. Simply put, I want to write an external syntax checker that will check things like matched LINK/UNLINK pairs, uninitialised variables and a few other problems. I've been devoting a fair amount of thought as to how to store the data of such a program; traditional cross reference programs in Pascal used linked lists, and indeed I found such a program yesterday evening. But I would like to have a much more modern interface and use types such as stringlists and similar. A stringlist is ideal for storing what would have been an array of identifiers but isn't so useful when additional data regarding those identifiers is required.

I will no doubt continue to debate the subject in my mind until I commence coding; at the moment, my inclination is to take the old school cross referencer and adapt it to the Priority SQL syntax. This will be a complex task that would have to be done one way or another, so it's probably better to start with something that works so that I can concentrate on the syntax and not on how everything is stored. A cross referencer is a good idea anyway: it makes finding references to a variable much easier. I started writing a long program in Priority yesterday afternoon and finished writing and debugging this morning: this is 270 lines long which is fairly long but not too complicated. During the writing process, I moved pieces from place to place within the program (primarily moving non-variant operations out of loops, to be technical) and sometimes these edits slightly mangled the text. I discovered a new bug: a variable will always start with a colon (e.g. :DAYS); in the course of one of these edits and pastes, I had a variable named ::DAYS which is not the same as :DAYS. 

A cross referencer helps in finding variables that appear only once; this can mean that either the variable is superfluous as it is never used, or more problematic, it is a variable without value (as in the above case of ::DAYS). I wasted an hour yesterday on another procedure, trying to figure out why a value being saved in a variable was not being written later on. Eventually I saw the problem: the value was saved in :PARTCOST but was later accessed as :PARCOST. A cross referencer would find this immediately.


Sunday, September 06, 2020

What a weekend!

In true British style, I suppose that I should start with the weather: this allowed me to use such adjectives as 'torrid' and 'oppressive'. Friday morning started hot, and by about 3 pm, the temperature outside was 40°C. The air conditioner in the lounge was barely coping to keep inside to around 30°C, a condition that was severely challenged when I began cooking. Steam from the tomato sauce that I was making caused the temperature to rise in the kitchen. At one stage I turned on another air conditioner in the house in the hope that this would help, but it didn't; not only that, when I turned on the electric cooker, the main fuse blew! So I turned the second a/c off then restored power. Somehow we got through the evening although it was very hot. Saturday was very slightly better but still hardly bareable. Now it's Sunday morning and I'm at work with an air conditioner at my back so at least now I'm comfortable.

I had hoped to write that I was expanding my collection of musical instruments. I saw on Ebay that someone was offering for auction a dulcimer, along with case: there was one other bid at around £20 which would be a ridiculously low price. I entered a maximum bid of £30, and until one minute before the auction closed, it seemed that I would win the dulcimer for £27. To my surprise, dismay and disappointment, new bidders swooped in at the final minute of the auction and someone bought it for £45. Still a steal. I was disappointed for a few minutes but not for longer.

I installed a copy of Delphi 10.2 on my mobile computer which has been behaving better since I replaced its battery a week ago. The main advantage for me of using a modern version of Delphi is seamless unicode; so far, everything that I have seen is worse than Delphi 7. When compiling, there is a whirlwind of windows opening, resizing and closing which is annoying but has no affect on the final result.

I ported one of the exams that I had programmed for the OP: this one has a fairly simple interface but can display in four different languages, namely Hebrew, English, French and Russian. I 'shot myself in the foot' somewhat by choosing to port the version that displays unicode by virtue of the TNT components; these don't exist in Delphi 10, so my forms became devoid of controls. I eased the pain by using an earlier version of the exam. I found myself adding a certain amount of code controlling the position of the controls - Hebrew is read and written right to left, so labels have to be on the right, etc. Different fonts are required as well. The end result is a program that works like the original, only that it's 10 times larger. I didn't really gain anything from this.

Then I thought I would try to port the program that maintains the database for this exam. I wasn't expecting any of the earlier interface problems: the main problem would be the database driver. I was pleased to see that Delphi 10 has the dbExpress components so I didn't need to change these - that would be an arduous task - but I haven't succeeded yet in connecting the program to its database when it is running. At design time I did manage to connect one query: the output is unreadable. I'm going to continue working and reading about this: I need the correct 'database driver' for Firebird 2. Ironically my low level database manager works fine, but it's written with Delphi 7.

I wrote about some of these topics two years ago; last time I didn't have the database components so I couldn't do anything in that area. Now I have them but I still can't do anything with them.

Wednesday, September 02, 2020

Wedding stairs

It has become normal for couples a few hours prior to their wedding to have a 'photo shoot' in some scenic location. We've discovered that an enterprising photographer has been using the steps at the back of our house as a location for these wedding photos.

I don't think that there's anything remarkable about these stairs and the accompanying foliage (which can't be seen too well in the photo), but maybe it's sufficiently exotic for the photographer. 

I should mention that neither the photographer nor the couples come from the kibbutz which might explain why they've chosen our stairs: when one enters the kibbutz and travels around the 'outside road', the view isn't particularly pretty. If one considers the road to traverse a rectangle, then the entrance is at the bottom right hand corner and we are in the top left hand corner: we're the second house from the corner. It might well be that the photographer entered the kibbutz, turned right at the entrance (I think that these days there isn't much of an option to turn left as this leads to a building site), started driving around the road and stopped at the first location which took his fancy. 

Whilst I don't think that we should charge the photographer for the use of the stairs, it might have been prudent from his point of view to ask permission. The thought that people have their wedding photos taken on our steps amuses us somewhat.

It's hard to believe but we're already in September - time seems to fly. I'm more aware of this than most, as my early morning walk (at 5:30 am) now starts in almost darkness, and the evening walk is also partially in darkness. We're fast approaching the vernal equinox, so this isn't too surprising. Saturday swimming - for the few Saturdays left before the season closes - will start now at 9 am.