Monday, October 26, 2020

I don't take any pleasure in being a Cassandra

I'm going to deviate from my normal topics for this blog and write about something at work, in the hope that I might better understand what has happened. 

Sometime around the end of March (when we were locked down and working from home), the factory in Karmiel took on a new worker whose job was never clearly defined to me, but turned out to be responsibility for improving work methods in the metal division, primarily with reference to Priority. In other words, this new worker and I interfaced on many levels. He came with a background of working in other companies in similar areas so presumably knew a thing or two.

Almost immediately came the clashes between us. He wanted to change almost everything regarding how the metal division is implemented in Priority (processes, actions, work centres, warehouses) as well as how the reporting itself is done. Whilst some of the changes were necessary and overdue, some of them seemed unnecessary and would lead to the imposition of even more overhead than exists today.

My biases are already becoming apparent in that previous sentence: something with which I agree is fine, but something with which I do not agree is unnecessary. Several times I tried to persuade this employee to write a complete business plan so that it could be scrutinised and criticised but this never happened. During the single day (in June) that I spent in the Tel Aviv offices since March, I had a meeting with both my manager (the CFO) and the managing director, trying to explain why some of the proposed changes were not good. In fact, they were not proposed, they were already on the way to being implemented. The Karmiel factory manager also participated in this meeting - he had been charmed/seduced by this new employee and was prepared to back every single move. Their attitude was that I was complaining due to 'sour grapes', that this new employee would succeed where I had failed and because of this, I was determined to bring him down, so that he would not be more successful than I.

Is this true? I sincerely hope not. Throughout the months that followed, I tried very hard to separate any personal thoughts that I might have had from professional criticism. I was forced to complain a few more times - especially after blitzes of emails - and was told that it is good that there is someone who is trying to move this most stubborn division forward. I cannot disagree with this aim, but there are ways of achieving this.

This person several times told me that he was a "bulldozer" and would succeed in both passing his reforms and getting them implemented. I have kept on the sidelines for the past few weeks, not because that I am trying to show that I am waiting for him to fail, but because I want to let him have a free run, letting others make the criticism. Does this mean that I am waiting for him to fail?

Anyway, yesterday I was very surprised to receive an email from my manager telling me that this employee had decided to quit at the end of the month.

How am I supposed to feel? To gloat over the fact that most of my predictions came true? I don't take any pleasure in being a Cassandra. So much for being a bulldozer who sees projects through to their end. I don't what the reasons were that caused him to quit - they may be entirely personal reasons with nothing to do with his job. It doesn't really matter; what I want to know is who is going to pick up the pieces and continue with all his changes that are in mid-flow, or who is going to revert them to how they were. At the moment, changes in processes, etc, are causing more problems than they are solving.

I don't want to say to anybody "I told you so" but maybe I don't have any option. There is nothing to be gained from doing so, but this is going to be very hard to escape from if I am the person who will be required to assess the damage (I don't see that any progress has been made).

There is supposed to be a meeting held today, one of a series, whose topic is improving the output of the factory. Most of the time the discussions are about the arrival and installation of new equipment and the changes that these new machines will cause to our work methods, but I have no doubt that time will be devoted to this change in personnel. Due to a pressing personal reason, I cannot participate in today's meeting. It has happened before that meetings have been rescheduled because I couldn't participate at the given date or time, so it might be that this meeting will be rescheduled for the afternoon.

As always, wait and see.

[Update from a few hours later] The meeting has indeed been rescheduled for Wednesday.

I thought it appropriate to give an example where my well- meaning advice was totally ignored. The person wanted stations on the shop floor to report production as they finish each job (good). To this end, he requisitioned a computer for each station, each armed with a bar code reader, and connected to the wired network. At one stage it appeared that each station would require a separate Priority license as well as a network license. A few months earlier, I had implemented a similar system for on-station reporting using wireless bar code readers that would broadcast their barcodes to one central computer; each message that the readers would send would include a prefix identifying the reader (in other words, the worker). This solution would be cheaper and easier to implement (in my humble opinion); this suggestion was totally ignored. It rose again in a meeting a week or so ago when one manager had visited another factory and saw how they were reporting, using wireless bar code readers. Why should 'the person' ignore this suggestion? Because someone else suggested it? Because I suggested it? Maybe this suggestion can be used now that he is going.

Friday, October 23, 2020

Overcoming the 'leading zero' problem in Excel

I see that I haven't written on the topic of Excel and automation for two years - I must be doing something right. In the management program that I wrote (and always extending) for the OP, there is frequently a need to output data to Excel. In order to facilitate this, I wrote a few standard routines that extract data from some form of query (this could be a clientdataset, an SQL query or a 'simple' query, hence the need for a few routines): these extract the data and output a CSV file along with column headings. Another routine is then called that inputs the CSV file into an Excel spreadsheet and displays it.

There is a well known problem with Excel - fields that appear to be numeric but are actually alphanumeric have leading zeroes truncated, as Excel 'thinks' that the field is numeric. In the OP's world, this problem applies to identity card numbers: many (including mine) begin with a zero (mine begins 0176), and when a csv file with this number is inserted into a worksheet, the field displays 176. Until now this hasn't been a problem, but a new (and somewhat nasty and patronising psychologist/analyst) has been working on data output from the management program and it annoys him that the leading zeros from identity numbers are being dropped.

My first solution was something similar to what Priority does: surround the field with quotation marks. I innocently thought that Excel would not display these marks but that's not the case. My 'solution' probably annoyed this psychologist even more as now he had to contend with strings like "0176". I had to find another solution.

Theoretically the problem could be solved easily by formatting the column that would hold the identity numbers, but this is a chicken and egg problem: formatting the data after it has been read in doesn't help as the leading zero has already been stripped, and formatting the column before reading in the file doesn't help because a new sheet is always created with the data. I thought that I might be able to hack the problem by including a non-displayable character before the string but this didn't work either.

Excel does have a method for inserting data into an existing spreadsheet - I used to see this frequently when trying to input text files - via a wizard that helps the user to insert the file correctly, handling character sets and delimiters with ablomb. I recorded the process as a macro but there were too many problematic statements for me to translate into the required Delphi format so I discarded this approach.

Then I remembered that I already have implemented a solution - the varArray approach. This allows one to create a sheet, format its columns then input the data in an 'underhand' manner. I adapted the code that I already have in one module to the module where I need it, and lo and behold, the leading zero problem had been solved.

I then removed the new code from the module and inserted it into the same general utility module that contains the other Excel routines. This required a few minimal changes and now there is an alternative method for exporting to Excel that both solves the leading zero problem and doesn't require an intermediate file.

After I reported on this improvement, the annoying psychologist condescendingly wrote to me to make sure that nothing else has been affected by this change. Obviously he's never heard of modular code.

Thursday, October 22, 2020

New bass guitar

Slightly over three years ago, I wrote about the semi-acoustic bass guitar pictured on the left. Some time after this picture was taken, I noticed that the side of the guitar was beginning to separate from the top. When eventually I got around to looking for a luthier to repair the damage, the whole body was falling apart. Thirty years the guitar lay dormant under my bed with no damage but a year hanging on the wall ruined it. I quickly removed the guitar and put it back under the bed but I doubt that it can be repaired now.

So the space on the wall became vacant. At various stages the 2019 bozouki and one of my mandolins have occupied this slot. Over the last few months I've bought a few new (to me) instruments and something told me that maybe now is the time to buy a 'proper' bass guitar. 

There are two main sources for buying instruments in Israel: one is a company with maybe ten or more shops throughout the country (I bought the Fender 12 string from one of the branches). I had a look at their web site, but the basses displayed there were far too expensive for my modest needs. Maybe they have cheaper items in the shops but I'm not about to visit one (because of the Covid lockdown that has now be relaxed somewhat). There is a music shop in Bet Shemesh but I don't know whether they are open let alone whether they have a suitable instrument. The other main source is a company whose main shop is in Jaffa - I bought the Washburn semi-acoustic here. Their web site was much more promising, with a variety of basses suitable for any pocket. They also offer a 40% discount and no delivery charge, making their goods very attractive.

After some deliberation, I plumped for the bass pictured on the left. It's branded Encore and is made in China but seems eminently suitable. It cost only 500 NIS, which is less than $150. We can spend more money that that in the butcher's. Although the web site said that delivery can take up to 14 days, it arrived three days after being ordered. Presumably they have the guitars in stock and are willing to sell at slightly above cost price in order to have some form of cash flow in these problematic days. They also sell 7/8 scale basses that are even cheaper and might be even more suitable; had I been in their shop, I would have tried both sizes, but I thought it more prudent to buy a full scale bass.

After tuning the guitar (it was slightly flat compared to the piano), I played a bit on Tuesday and a bit more yesterday. It's very easy to play the bass, but I have one small problem (or as my CEO would say, one challenge): because the scale of the bass is longer than a guitar, the distance between frets is greater. I am unconsciously fingering the neck as if it were a guitar, and as a result my fingers often land too far behind each fret, causing the string to buzz. Of course, I'm playing without looking at my fingers: if I paid more attention to the scale then I'm sure that my fingers would press the strings just behind each fret. I imagine that this would be less of a challenge had I bought the short scale bass.

As for the wall on which the new bass is hung: at first I hung the bass where its predecessor had been, but because the headstock (where the tuning pegs are) is longer, it was almost touching a shelf that had been added above the guitar. After thinking for a few minutes, I swapped the bass for the Gibson SG copy bought in 1976 that has a shorter headstock.


Tuesday, October 20, 2020

DBA update

Finally some news! The DBA coordinator informed me a few days ago that a tentative date for my viva exam has been set - 26 November. Apparently the external examiner had been unwell for some time (I don't know whether this was due to Covid-19 or something else, and it doesn't really matter).

Coincidentally, someone approached me via LinkedIn: it transpires that this person completed his doctorate at EBS earlier in the year, with his viva taking place via Zoom (or similar). When I informed him that I now have a tentative date and that I was going to start rereading the thesis, he pointed out that the examiners will probably ask about things that aren't in the thesis.

As it happens, I spent a few weeks at the end writing about topics that might have been expected to appear in the interviews but didn't (section 7.6, data lacunae) as well as hindsights obtained after completing the research and thesis (this section refers to section 7.6), so these sections should be good preparation.

Incidentally, the person from LinkedIn has chosen an unorthodox abbreviation for his doctorate: DrBA instead of DBA. This is a good idea as it differentiates between a DoctoR of Business Administration and a DataBase Administrator. In my line of work, I'm more likely to encounter the second type of person.

Saturday, October 17, 2020

Completing the story of porting an application to Windows 10/Delphi 10.2

The previous installment of this story had the application displaying people's names in unicode and allowing them to be edited. This means that the remaining parts are to read in the INI file that contains the answers from the user and then display them, via HTML and thence to Word.

Initially I tried saving Russian text into the database table via the database manager program, outside of Delphi. This was spectacularly unsuccessful so eventually I created a new database with the same structure but with the default charset UTF8. I then copied (by means of a simple program that I wrote) all the data from the old database to the new database, using the 'cast' trick (cast (surname as varchar (16) character set unicode_fss)) wherever necessary. I then renamed the original database to 'OldWhoAmI' and renamed the new database to 'WhoAmI'. Then I unregistered both databases from the database manager then registered the new one. This version allowed the saving of unicode text, especially Russian.

Once the database issue had been settled, it was much easier to continue porting the application. I restored the 'edit person' screen discussed in the second episode of this series to use data aware components; there was no need for tricks using 'cast' as the text was now unicode. Reading the data file, including Russian, required no changes that I can recall. 

Creating an HTML file that could be sent to Word required a few changes. Until now, I have been using the 'AnsiToUTF8' procedure whenever I wanted to output Hebrew; this is now superfluous so I had to remove all these calls. I also had to update all the Hebrew that was embedded in the program code. Once I had an HTML file that displayed correctly, I tried to export to Word; I received a mysterious error message, informing me that my file could not be found. Initially I thought that this meant my HTML file, but then I realised that it meant that the template could not be found. Once I updated the template, I could export the data to Word.

Conclusions for next time:

  1. Create a new database with the same table structure but with the UTF8 charset. Copy all data, using casts wherever there is Hebrew text.
  2. Register the new version of the database in the database manager (this isn't essential but it helps).
  3. Save the database in a specific directory.
  4. Porting is fairly simple. AnsiToUtf8 calls should be removed when HTML code is developed.


Friday, October 16, 2020

PrioXRef 3 - insert without parameters

Every day I've been checking the Priority cross referencer and fault analyser (XPrioRef) against a variety of my own procedures and every day I've come across new constructs that have to be handled. Yesterday I came across a real doozy (as Ned from 'Groundhog day' would say):

INSERT INTO PART SELECT * FROM PART ORIG WHERE PART = :PART;
For those who aren't au faire with SQL, this means 'insert into the (linked) table PART all the fields from the real table PART for all tuples where the part number is equal to the variable PART. As the variable can only have one value, it means that only one tuple gets copied into the linked table. Statements like these occur when the linked table is about to be sent to an external procedure.

Until now, XPrioRef has handled two kinds of insert statements: INSERT INTO <table> (<fields>) and INSERT INTO <table> <alias> (<fields>). The above statement has no alias and no list of fields; as the character after the table name on the first line is not an opening bracket, XPrioRef thought that the next token (it's a 'top hat', ^, that signals the end of the line) was an alias, so there was a reference to PART ^.  There is also a problem with the line count at this stage. Then the asterisk in the second line (which in this context means 'bring all the fields') was parsed as punctuation, causing the parser to be even more bewildered.

Handling the asterisk was easy (the character after 'SELECT' is checked, and if it's an asterisk then it's swallowed) but handling the first line was not easy. The next token after ^ had to be read, and if it's SELECT, then the 'insert into' part has been finished and then 'SELECT' is handled. 

This is all very ad hoc, something that I had tried to avoid, but it seems that the confusing syntax demands this. Of course, within the SQL engine there is a parser that has to execute the statement; I'm only trying to list references and determine what is happening at the time of the reference.

After adding a fix for this kind of statement, running PrioXRef on the same procedure produced the expected output. Now I wait for the next misreference to appear.

Monday, October 12, 2020

Cardiologist

In July, I wroteDuring the lockdown, I noticed that my feet - especially the right foot - were swelling up, and it was painful to move them. Although that extreme swelling has not returned, I still see every evening that my right foot is somewhat inflexible. It often happens that by the time I return home from work, my feet and legs are like two blocks of wood. Fortunately, exercise - walking the dog - helps, as do my sport shoes, so I don't suffer so much in the evenings.

The final stage in the diagnostic sequence was a visit to a cardiologist. He asked me all kinds of questions, looked at the list of medications that I take and examined the various test results. His opinion is that the swelling is a side effect of one of the medications for lowering blood pressure, and so his recommendation is to stop taking the medication. The daily swelling should cease in a day or two. Of course, I also have to monitor my blood pressure: if it starts rising then I will have to see my GP who will recommend new medication. It will be very easy to see whether his opinion is correct.

Sunday, October 11, 2020

Continuing the story of porting an application to Windows 10/Delphi 10.2

I spent quite a few hours on Saturday working on the application that I discussed here. I started off by working on the database again: I wrote a program that would export the forename, surname and primary key of all the records to an INI file (this is with Window 7/Firebird 1.5, so there are no problems with unicode). Once I had this data outside of the database, I dropped those two fields then redefined them, this time with WIN1255. I then wrote a simple program to repopulate these fields from the INI file. So far so good.

On to the mobile computer with Windows 10, Delphi 10.2 and Firebird 2.5. As I seemed to be unable to use the clientdataset component, I was forced to use a simple query to access the data then display it by means of a listview component. The 'cast' trick worked well and now I could display all the records. I worked on the code to filter these records, and when that was done, I worked on a screen in which the user can edit personal data. As I couldn't use the clientdataset component, I had to create a screen with non-data aware components; this means extracting the data from the database with a query component then loading the data into the appropriate edit boxes. Should the user decide to accept the changes, the data from the edit boxes would be written back to the database with another query. 

This update query was actually a piece of serendipity: when I edited a person's name then wrote the data back to the database (into a field defined as WIN1255), the field in the database became gibberish. Of course! The solution was to add two new fields to the database table defined with character set UNICODE_FSS; the update query then wrote the data to these two fields correctly. But that's not much use if I want to use the WIN1255 fields in the main screen, so I wrote a simple query that updates the WIN1255 fields with the data from the UNICODE_FSS fields cast as WIN1255 (i.e. the reverse of what I had done previously). This actually worked first time!

Then I faced the problem of updating the tree view with the new data: I used the same approach as I use with a grid, namely delete the current record, extract the data for the new record from the database then add it to the list view. This worked on the second time - because I forgot to delete the current node first time around and so caused a key violation.

Whilst walking the dog, I wondered about the clientdataset component: I'm sure that it worked at some stage before I got bogged down with unicode issues. I decided to remove the Delphi installation completely then reinstall; this took a fair bit of time, but once it was finished, the clientdataset component resumed working. So I saved the list view version of the program in a different directory for backup purposes then set about restoring the grid and db controls - this went very quickly. Due to the unicode issues, I decided to continue using the new version of the 'edit person' screen with its non-data aware controls; my approach wouldn't work well with data aware controls as the data is read from one field but written back to another field.

The next stage will be to see what happens when the unicode INI file containing the Russian text is read. I may have to defined duplicate fields with character set UNICODE_FSS for this data. Supposedly the database knows in what language the user completed the exam as there is a language field in the 'people' table, but this field is always empty. I shall ensure that this field receives a value when there is Russian text so that the correct field in the 'results' table will receive the text and eventually be displayed.

With regard to the clientdataset, I wonder whether fields defined in the program (i.e. using the component in 'standalone' mode, not connected to a database) are automatically unicode. This isn't an issue for this program but it will be for the next program that will undergo porting.

And here is the answer to my question about unicode (someone had asked before me): 

You cannot store unicode characters in a field with the ftString field type, you should use the ftWideString field type. Data disappears in a field with ftWideString field type because the size of this field is zero by default. To solve this problem, you should set the Size property of this field to the value more than zero.

Saturday, October 10, 2020

Simple baked salmon


I've been at home for the past week, not because of the lockdown in Israel but because it's the "Festival of Booths" during which traditionally (in our company) office workers use their holiday days and stay at home. This isn't to say that I've been idle - the work on the Priority cross referencer and Delphi unicode programs is evidence of that.

As a result of being at home, I decided to change my cooking/eating habits: instead of making a pot full of chicken breast or meat balls with vegetables for the entire week, I bought a 'plank' of salmon, cut it into portions and every day I would bake a portion in the oven, served along with steamed vegetables.

The recipe is extremely simple: spread a sheet of baking paper on an oven pan, drip a few drops of olive oil on the paper, rub a salmon portion in the oil and leave it with the skin upwards. Bake in the oven at 180°C for 15 minutes. Serve along with steamed vegetables. Simple, nutritious and above all, tasty.

Next week it's back to the office so I'll get out the trusty slow cooker and cook up a batch of meat balls and vegetables.

Friday, October 09, 2020

Converting a Delphi 7 semi-unicode program to Delphi 10

Possibly the simplest exam in the Occupational Psychologist's armoury is a program that requires the user to list 20 phrases that describe herself ('I am ... ') and 20 phrases that do not describe herself ('I am not ...'). The program displays itself in four languages - Hebrew, English, French and Russian - but until recently, the output that the user entered appeared as either Hebrew or English. We bought a 'Russian' keyboard and added Russian to one computer, in the naive hope that words that the user types in Russian would appear as such in the output file (an INI file).

Extremely naive: the output file consists of question marks where there should be Russian. After researching the topic, it turns out that the output file should be opened as follows 

Old style: datafile:= TIniFile.create (ffn); New style: datafile:= TMemIniFile.create (ffn, TEncoding.UTF8);
The 'TEncoding.UTF8' is the magic invocation required to create an INI file with Russian (or other unicode) characters; this also requires using TMemIniFile and a modern version of Delphi. Painstakingly I created a version of the exam in Dephi 10 (Seattle), replacing all the Hebrew characters that had been inserted directly into the program with either 'updated' Hebrew or appropriate resource strings. I eventually managed to test this program on the 'Russian computer', and indeed the INI file contains Russian characters.

At the same time I have been trying to create a program that will successfully read a database file. I have come to the reluctant conclusion that there is a bug with the ClientDataSet component that prevents me from using it. But the TSQLQuery component works correctly: I remembered that I wrote one or two programs using a TListView instead of a TDBGrid, where the list view is populated by a TSQLQuery, so I can use this alternative approach. But that wasn't the real problem....

It turns out that the 'surname' and 'forename' fields in the database table containing the examinee details were defined with the wrong character set - WIN1251, Russian - instead of WIN1255, Hebrew. I tried several times to convert from one to the other but with no success. Eventually I decided to delete these fields from the database, redefine them as WIN1255 then read in all the original data files in order to populate the name fields. This worked well, although there are about 15 entries in the database with identity numbers but no names. I can copy these from a working version of the database.

Going back to Delphi 10, every attempt to read this new database file failed. I'm not sure what the real reason is, but I discovered that I could access the database via my program only after I moved it to a directory that does not descend from 'users'. In the program that is to read this database, I replaced the dbGrid with a list view, and after dealing with the required method of inserting data into the list view, I could finally see data - but the Hebrew was not displaying correctly (each character appeared as a black diamond). I had researched this topic earlier this morning and had found the solution: the Hebrew fields should be accessed in queries in the following method cast (surname as varchar (16) character set unicode_fss). This method did indeed give me readable Hebrew text. Below is a screen shot of the program.


What's to come? I had removed all the functionality of the results program so that I could concentrate on displaying the data. Now I will restore all the functionality, which hopefully will not require many changes. After that, I can concentrate on reading an INI file with Russian characters, inserting the data into the database and then displaying it. Fortunately, the data (i.e. the phrases that each examinee wrote) appear to be coded as WIN1255 so I won't have to reinsert the data. As the data is sent directly to Word for output, the 'cast' trick may not be required. 

Of course, I will have to see what happens with Russian characters: I may have to add a new field to the table in UTF-8 coding to store the Russian properly.

Wednesday, October 07, 2020

Completing the second version of PrioXRef

I spent several hours yesterday and today working on the Priority Procedure Cross Referencer and Fault Analyser (PrioXRef). I finished off the deceptive assignment statement (:C = (:B = 1 ? 2 : 3) initialises :C but it does not initialise :B) then continued working on other kinds of statements. I noticed that at one stage, some variables were being marked as unused after their definition, which I know is wrong. It turned out that the code that reads comments was not working correctly and caused the program to skip over a large chunk of the program. I wrote a routine that sort of works but I wasn't happy with this and tried to find a better solution. 

The problem is that two characters have to be detected in order to end a comment (*/) and my routine had great difficulty in doing so. It doesn't help that I often used long comment lines (like /****************/ to mark sections in my code: these were causing the problem. After thinking about the problem for several hours, I decided eventually to 'cheat': I used the Delphi function pos that looks for a substring in a string, making the detection of */ very easy. Thinking about it now, this is hardly 'cheating' as I am using several other Delphi constructs, but the idea was to write the lexical analyser using standard Pascal as much as possible.

Once I got past the comments, other things became clearer. I added references to ERRMSG and WRNMSG that weren't in my original plan; this was very easy to do and adds value. When I thought that I had developed the program as much as possible, it then occurred to me to display the references in a tree view instead of as multiple lines of text. This is definitely easier to read. I'm still keeping the original 'block of text' so that the references can be exported as a file. Adding the references to the tree view was fairly simple, but now looking at the screen shot, I see that an extraneous colon has been added.

For all the help that  PrioXRef can bring to the table, there are still areas that can give a programmer grief. I have just spent a frustrating hour trying to figure out why an interface procedure that I wrote several months ago had suddenly stopped working. The interface is for the SUPPLIERS screen and naturally uses fields from the eponymous table. I eventually discovered that the problem was that I was accessing the default purchase order type, a pointer to which is held in the table SUPPLIERSA. There was no record in this table for the supplier that I was testing and so my query result was empty. The rationale behind extension tables (such as SUPPLIERSA) is that one can define for this table fields that are used by only a subset of the suppliers and so save space in the database. 

I should add a heuristic to PrioXRef that tables whose name ends in A should appear in queries with a question mark (e.g. SUPPLIERSA ?), which is Priority's way of saying 'this is a left join'. This would take a fair amount of work as PrioXRef tends to ignore table names that appear in FROM clauses (which is where the question mark would appear): it's only interested in tables that have LINK statements.

PrioXRef can be downloaded here.



Monday, October 05, 2020

Continuing the development of the Priority Cross Referencer (PrioXRef)

I've been working on this program for several days, adding more and more definitions. I thought that I had reached a saturation point this morning, and so decided to write a new tokeniser that would be more streamlined rather than the ad hoc structure that exists at the moment. But in doing so, I discovered that I also have to rewrite a fair amount of the lexical analyser that too was very ad hoc

One advantage that the program has is that it is intended to work on procedures that have already passed the internal syntax checker and so there is no need to check all kinds of pathological structures.

This is going very slowly as I spent a few hours working solely on handling variables and their initialisation. I am concentrating on the following three statements

:A = 10; :A = :B = 10; :A = (:B = 1 ? 2 : 3);

The first statement should be easy to handle, but it required a change in the new 'GetChar' routine. The first version of this along with the new tokeniser would return four tokens for the first line, namely :A, =, 10 and ;. This makes parsing the line unnecessarily difficult: there should be a 'one token lookahead' but the routine needed to look at the following two tokens. So I changed the routine so that there are now two tokens (:A and 10), and the equals sign can be 'seen' when handling :A. The next token still has to be retrieved; if its first character is a digit then the identifier is being initialised and everything is good (this is the first line). But if the first character of the following token is a colon, then apart from handling :A, the following token (:B) should be put back into the input stream. 

Tomorrow I will handle the third statement. I think that the key to handling this properly is the opening bracket before :B; this will indicate that some form of expression is about to appear. :B will be referenced but it won't be marked as an initialisation.

Friday, October 02, 2020

Weight at the beginning of Oct 2020


I have been too embarrassed to write about my weight in the past few months. Despite all my walking and swimming, my weight has slowly been increasing over the past six months or so; maybe only 100g in a week, but always increasing. When it reached 80 kg a few weeks, I realised that I had to take action; I examined my diet to see what I could reduce. At first I thought it was the slice of bread with peanut butter that I would eat at 6:15 am that was intended to reduce pangs of hunger during the morning, so I cut out the peanut butter for a while - no difference. Even cutting out the bread made no difference.

Then the penny dropped: as a source of iron and other minerals, I have been eating a handful of raw almonds every day. As these aren't particularly tasty, I added another handful of cashew nuts: these two supplement each other very well in nutritional terms. Unfortunately they also contain no small amount of (good) oil and so they contribute quite a few calories to the diet.

Two weeks ago I stopped taking the nuts with me to work; my weight dropped by 400g last week and by another 700g this morning. Mission accomplished. Maybe I'll go back to eating raw almonds but I won't return to eating cashew nuts - these have salt or something added that always leaves me wanting to eat more (the same doesn't happen with almonds). Anyway, this morning my weight had dropped below 79 kg and I would very much like it to drop another 2 kg. This is definitely possible.....

I don't remember if I mentioned it here, but about a year ago I bought some 'almond butter' - the same as peanut butter but made from almonds. I don't think that I managed to eat more than one slice of bread with almond butter, it was so unpalatable. I used some whilst cooking, but most of the container found its way to the bin.

This weight loss has made me feel very happy and enthusiastic this morning.