Wednesday, March 18, 2026

Analysing my lunch

The health app on my phone (from my health fund) records my daily steps; I noticed yesterday that I can also photograph meals and get points for doing so.

So today I photographed my lunch via the app; I could see that the app scanned the photo three or four times, and then to my surprise told me that on the plate there was 125 g quinoa, chicken, broccoli and sauce. I don't recall the weights of the other items except for the quinoa. Now I can't restore that dialog and I also can't see how I can get the photograph itself (maybe next time I'll photograph outside of the app and inside). But I can see how much of each macronutrient there was: 1.1 portions of vegetables (and I thought that there was less broccoli than usual), 0.3 portions of fruit (I wonder where that came from), 106 g carbohydrates, 56 g protein and 20 g fats. The quinoa is responsible for 97 g carbohydrate, 21 g protein and 9 g fat, whereas the chicken contributed 31 g protein and 3 g fat. The broccoli contributed 5 g carbohydrate and 2 g protein, whereas the sauce had 5 g carbohydrate, 2 g protein and 8 g fat. Althogether 845 calories, 36% of my daily requirements (that means 2,347 calories that seems a bit high). I'm impressed that the quinoa was identified properly and not mistaken for cous cous or the Israeli invention p'titim (literally 'flakes' as in snowflakes) which are also cous cous - semolina. They look quite similar from a distance.

Isn't AI wonderful? I'll try and photograph my meagre supper (a piece of 'white' pizza left over from yesterday). It will be interesting to see what the AI makes of my breakfast; I suspect that not all of the ingredients will be visible. 



This day in blog history:

Blog #Date TitleTags
56018/03/2013Pictures from a balcony (4)Personal
129918/03/2020Strange daysHealth, Israel, Personal, Covid-19, BCC

Monday, March 16, 2026

Continuing the migration, supplemental

Today I will write about something that I meant to include in the previous post but forgot: when does one need a TFDMemTable (hereinafter, TMT)? After all, one can define a TFDQuery, include an SQL query to retrieve data from the database, connect the query to a datasource and thence to a grid: the data will be displayed. Also, in a simple 'edit' form, there's no need for a TMT.

I have identified two cases when a TMT is required:

  1. If the grid that displays the data has an OnTitleClick event - this allows the user to sort the data.
  2. If the form allows the addition or deletion of data.
According to CoPilot, a TFDQuery doesn't have indexes whereas a TMT does. So when I migrate units with a grid, I first check to see whether the grid has an OnTitleClick event; if so, I know that I need to a TMT. Incidentally, there is a new flag that has to be set in the grid's options - OnTitleClick. This flag didn't exist in Delphi 7, and I came across it in one of the first units that I migrated. I was clicking on the title bar but the event did not fire ... because this new flag was not set.

If the grid does not have an OnTitleClick event, I check whether the form has a qGetOne query - this means that data has to be added - or a qDelete query. In the case of qGetOne, previously I used to iterate over the fields of the query and add them one by one to the clientdataset. A TMT has a new method, AppendRecord, that allows for the data to be added in one statement (never mind that beneath the hood, the data is still being added field by field). I have used this everywhere, apart from one or two special cases where AppendRecord seemed not to be appropriate.

The TMT comes 'naked' without fields. Here is my methodology for adding them (this may not be optimal). First I check that the query can be opened - it frequently happens that fields are defined automatically as ftString when they should be defined as ftWideString. So I fix all these before I even start with the TMT. When the query is defined properly, I open the 'fielddefs' property of the TMT and begin to add fields. The size of the fields is very important when the field in the query is a ftWideString; the default size is 20 but this should be changed to match the size of the query's field. When all the fields have been defined in the 'fielddefs' property, I then open the TMT's fields editor. This will be empty so I press on 'add all fields' and the fields that I added in the 'fielddefs' property now become persistent fields. I then iterate over the fields in the query, copying their displaynames to the TMT's fields, and finally I delete all the persistent fields of the query. I do this in order to highlight any use in the code of these persistent fields - it has happened that I received bizarre results when debugging and I discovered that these came from usage of the query's persistent fields. As the grid displays data coming from the TMT and not the query, progressing through the TMT gives different data in the persistent fields, whereas the query's persistent fields stay the same.

I wrote about changing column widths in a grid and saving them. I came across a very interesting problem with this: every form has a minimum width that is hard coded. I changed the column widths of one grid so much that the new width was less than the minimum width; as a result, there was a huge space on the left hand side of the grid before data appeared. How could I fix this? I made two additions: I converted the procedure that saves the column widths into a function that returns the total width with an extra 72 pixels for the scroll bar. I then wrote a procedure in the ancestor form that saves this new width. When the form is opened, this new width is compared to the minimum width, and if it is less, then the minimum width becomes this new width. Slightly messy but it works. Part of the problem is that the code for saving and restoring column widths is in a different unit from the ancestor form. Maybe I should move this code to the ancestor form - but not every form descends from this ancestor and maybe I would want to save column widths on such a form (unlikely).



This day in blog history:

Blog #Date TitleTags
11916/03/2008Back to bloggingOffice automation, Meta-blogging
12016/03/2008Chava AlbersteinChava Alberstein
46416/03/2012Rubber duck debuggingProgramming
148016/03/2022My first year as a Londoner, part 1 - being a studentPersonal, 1975, 1974
159316/03/2023I contain multitudesFood science, Non-fiction books