[Solved] Perform a Calculation Directly on a Dictionary Value?

This might be a question for @peternlewis. I have searched the Manual and Wiki and the Forum and have not found the answer (apologies if I have missed it).

I can perform a Calculation directly on a Variable and save the result back to the same Variable:

But trying the same thing with a Dictionary Value doesn't work.

I have got around this by first Copying the Dictionary Value to a Variable. Performing the Calculation on the Variable and then Saving the Result back to the Dictionary. But I was wondering if there is a way of doing this with one Action rather then three:

I have tried different syntax, like:

Dictionary[Test,%Variable%SomeKeyWord%]% + 3

CALCULATE(Dictionary[Test,%Variable%SomeKeyWord%]% + 3)

%CALCULATE%(Dictionary[Test,%Variable%SomeKeyWord%]% + 3)

But so far nothing works.

Just a guess, but the proper format for the Calculate token is

%Calculate%<formula>%

(taken from the KM wiki).

I notice you tried

but you seem to have missed off the final %.

Also - this use of Calculate is as a token not a function, so it shouldn't be in all caps (another stab in the dark).

Maybe worth a try?

Thanks @tiffle That make me feel there must be an answer!

I have now tried:

%Calculate%%Dictionary[Test,%Variable%SomeKeyWord%]% + 3%

%Calculate%(%Dictionary[Test,%Variable%SomeKeyWord%]% + 3)%

%Calculate%[%Dictionary[Test,%Variable%SomeKeyWord%]% + 3]%

But by looking at the page about the Calculate Token I found this (which was new to me - so, I have learnt something!)

Token for Window Frame, %WindowFrame[3]%1%, will be the third comma-separated value, which is the Window width in this case.

  • %WindowFrame%1% returns “3606,23,1514,1417”

  • %WindowFrame[3]%1% returns “1514”

I hadn't realised that %WindowFrame%1% could return each of the 4 coordinates separately - I have been using a convoluted method of splitting %WindowFrame%1% into 4 Variables...

1 Like

First, please always upload your Macro so that it is easy for others to test.

Second, I hate to be bearer of bad news, but this is just one more reason that I do NOT use KM Dictionaries. I love JavaScript Objects and Arrays -- they are much, much easier and more powerful to use than KM Dictionaries.

The answer to your question "Perform a Calculation Directly on a Dictionary Value?": No, you can not.

image

@peternlewis, this fails but does NOT throw an error.
It follows the proper syntax for Variables.
It results in the Dictionary Value being set to empty string.
I think it should throw an error.
Even better, allow Dictionary objects in a Calculation field.

Please consider a change.

Here's my test macro that illustrates the issue.
The KM Wiki Calculate token makes it clear:

Use any Variable which may be evaluated as a number
It does NOT say that Dictionary objects are allowed.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Example Output

@Zabobon:

Below is just an example written in response to your request. You will need to use as an example and/or change to meet your workflow automation needs.

Please let us know if it meets your needs.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

MACRO:   Perform Calculation With Dictionary Items [Example]

-~~~ VER: 1.0    2021-06-04 ~~~
Requires: KM 8.2.4+   macOS 10.11 (El Capitan)+
(Macro was written & tested using KM 9.0+ on macOS 10.14.5 (Mojave))

DOWNLOAD Macro File:

Perform Calculation With Dictionary Items [Example].kmmacros
Note: This Macro was uploaded in a DISABLED state. You must enable before it can be triggered.


3 Likes

Thanks @JMichaelTX

Your test Macro confirms what I have found. (Apologies for not uploading my test Macro - as that would have saved you having to build a similar one…)

Yes. And I see you came to the same Workaround Solution to the problem:

  1. Recall the Dictionary Value to a Local Variable.
  2. Perform the Calculation on that Local Variable.
  3. Save the Result back from the Local Variable to the Dictionary.

Three Actions instead of one. But it works and now I know I wasn’t missing something.

As always, thanks for helping.

UPDATE: I have now saved these three Actions as an easy to recall Template Set using the truly amazing [KMFAM] Favorite Actions and Macros by @DanThomas.

The field is a token field, so to calculate it you need to use the Calculate token. So that starts with:

%Calculate%5+3%

Ok, and now you want to use your text token %Dictionary[TestDict,TestKey]% in the calculation.

However, within the calculation, you can only use numeric values, you cannot use a text token. So to use a text token within a calculation, you use the CALCULATE function.

%Calculate%CALCULATE(%Dictionary[TestDict,TestKey]%)+3%

Which works fine in your original action.

This issue has nothing to do with dictionaries, it is simply a matter of using tokens and functions in their appropriate place. There are no dictionary functions, so you cannot use them within a calculation field without going via the CALCULATE function, and if you want to use a calculation in a text field, you need to use the Calculate token.

Because that is attempting to use calculate the numeric value of the calculation:

Dictionary[TestCalc,Amount1] + 10

which is an error - it is attempting to array index a variable named Dictionary, but with two parameters so it is invalid.

And tokens cannot throw an error - tokens never have an error condition. So it returns nothing.

But again, this has nothing to do with dictionaries, it is not making any reference to a dictionary (except for the words you happened to use. You could just as easily write it as:

%Calculate%Variable[TestCalc,Amount1] + 10%
1 Like

Wow! Like magic. Thank you @peternlewis, just needed to know the secret formula!

So, modifying a version of @JMichaelTX's test Macro, this now works to Perform a Calculation on a Dictionary Entry and save the result back into the same Dictionary Entry. And all in one Action.

Perform Calculation With Dictionary Items [Example] v2.kmmacros (2.9 KB)

I wonder if someone with the authority to do so, could add this bit of information into the Wiki page on Dictionaries? @ccstone or @JMichaelTX ?

I have actually really enjoyed using Dictionaries and found that in almost all cases they can be used where a Variable can be used - apart from (until you provided the answer) Calculation Fields which is why I asked the question that started this thread.

They are particular powerful as every one of the three elements that forms them: Name,Key,Data can be replaced with Variables or even partly replaced with Variables.

So, the same Dictionary called "Name1" can also be accessed by "Name%Variable%Number%" where %Variable%Number% is 1.

But @peternlewis already said:

I would vote for an amendment to the wiki that spells this out in plain detail - much like Peter has.

Where in the wiki? Is it about the use of text tokens? Is it about the CALCULATE function or the %Calculate% token?

I don’t know but this was as clear as mud before Peter replied.

1 Like

Having started to implement this I think for all practical purposes (although it is good to know it is possible to do it in one Action) it is actually much simpler to Convert the Dictionary Value to a Variable, perform the Calculation on the Variable and then Copy back to the Dictionary (as in the 3 Steps above).

The Syntax needed to do it in one Action is so complex it would be very easy to make an error when typing in the formula.

This:

As against this:

So, I'll stick to the three step approach for simplicity.

2 Likes

I’m with you on that - much less likely to make a mistake!

1 Like

Typinator to the rescue!
%Calculate%CALCULATE(%Dictionary[{{?Dictionary NAME}},{{?Dictionary KEY}}]%) {^} %

Demo-Typinator-KM-Dict-Calculate-AN

One cool thing about Typinator is that it remembers your previous entry for an input field.

3 Likes

Peter, I think the very reasonable expectation is that a Dictionary name would be treated exactly like a Variable Name.

So, if this works:
%Calculate%SomeVariableName + 3 %

then this should also work:
%Calculate%Dictionary[DictName, KeyName] + 3 %

Clearly you are able to detect a KM Variable name in a Calculation Field.
So it should be no problem to also detect a Dictionary name in a Calculation Field, especially since it will always start with Dictionary[.

Very simple, very obvious.

Please CHANGE all Calculation fields to accept Dictionary names.

Thanks.

2 Likes

I think my main points are:

  1. There are better ways to store data
  2. There are still many areas of KM where using Dictionaries can be a problem.
  3. Using KM Dictionaries are very verbose.
  4. You can't easily share KM Dictionaries with other sources.

Yes, there are workarounds to all of these. But there are just that -- workarounds -- that require more time and effort.

I find it much easier to build, maintain, edit, and share data that are stored in:

  1. Tab-delimited Variables, or Files
  2. Spreadsheets, like Excel
  3. SQLite databases

There are a few exceptions where I have found KM Dictionaries to be useful and the most effective solutions.

Having said all that, each of us has to choose the solution that works best for us.

1 Like

Hi @peternlewis
I know I am pushing my luck here... :grinning: but is there a formula to put Dictionary Values directly into these Fields?

Thanks! I will check it out.

Yes, they are numeric fields, so exactly the same, except you only need the CALCULATE function.

CALCULATE(%Dictionary[DictName,DictKey]%)
1 Like

Thanks! I am finally beginning to understand the difference between Numeric and Text/Token Fields.

And good to know that both can be used with the right syntax to accept all data.

image

So, both of these work - Brown Action is the Text/Token Field and Green Action is the Numeric Field:

To give the same answer:

1 Like

But should it not be written like this?

CALCULATE(%Dictionary[DictName,DictKey]%)

Yes, I missed a bit in the copy.

1 Like