Tuesday 4 August 2020

Don't be a miser with brackets

In reports, there are three very useful 'group functions': T, S and B, that can be used on columns containing numerical data. T causes the total of the column to be presented at the end of the report, S causes sub-totals to be presented and B causes both sub-totals and totals to be presented. Unless one is displaying oranges and apples in the same column, B is normally the preferred option.

One can also use these functions on calculated columns; for example, I have been working on a report which displays in one column expected costs, in another column the actual costs and in the third column the ratio of actual to expected costs. 

Let's say that the report looks like this

Expense expected actual % ratio
Gas 160 170 106.25
Electricity 188 13571.81
Water 207 197 95.17
Totals 555 502 90.45

In order to achieve this, the definition of '% ratio' is (in words) 100.0 times the actual cost divided by the expected cost. Assuming that 'expected' has a column number #100 and 'actual' has a column number #110, the definition of column 120 will be 100.0 * #110 / #100. The first two columns should have the group function B (or T) in order to display their total at the end, and the ratio should have the group function b (or t). 

Sometimes this works, sometimes it doesn't.

This simple version might well have worked, but I had to change it in order to prevent division by zero; let's say that there are actual costs that were not budgeted. In such cases, Priority displays 100 * #110, which is completely wrong! There should be a condition that if expected = 0, then the result is zero, else it's what the formula calculated. On in Priority-speak, #100 = 0 ? 0 : 100.0 * #110 / #100.

This formula certainly handles division by zero properly and also displays the correct ratio in each row, but now the total percentage ratio is no longer 90.45 but 273.23 - the sum of the percentages in each row, and not the percentage of the total!

I know that group function b works because I have a report that displays the total percentage correctly. So why doesn't it work here? After a great deal of unsuccessful magic incantations, I was forced to call in someone else. She too did not know the reason off-hand, but she compared the formula here to the successful formula in another report, and noticed that here I was using the ternary comparison expression (taken from C; read it as 'if #100 is zero then return 0 else return 100.0 * #110 / #100). 

It turns out that the parser in Priority is very temperamental when it comes to the order of evaluation of expressions and especially the ternary expression; the parser requires a great deal of help which one supplies by means of brackets. When these are applied liberally, the 'b' group function is finally honoured in the totals line: (#100 = 0 ? 0 : (100.0 * ( #110 / #100)).

The use of brackets is somewhat inconsistent in Priority and reminds me of the UNLINK command: one can often get away without using it, but sometimes it is essential and so one should always use it. Apparently the same as with brackets: don't be a miser with them!

Also it seems that one has to use the row numbers (#100, etc) instead of actual row fields (e.g. STACK4.REALDATA).

No comments:

Post a Comment