Separate Sets of Variables? [Solved]

This looks very good - and not too many steps.

So, I am assuming the approach could be to first gather all the individual bits of Data to Variables and then use those Variables to build the Monster DND_Object_Sets Variable? And then from there call the individual Sets as needed using a version of your Example Macro.

What I am tying to figure out is how to build DND_Object_Sets Variable on the fly for each of the Sets.

I can see how I could incorporate this at the start of a Macro 2 to choose between say 3 Sets of Data. For example, at the head of Macro 2 I choose Set02 and that Set of Data is used for the rest of the Macro.

But how would I tell Macro 1 to overwrite the Data for just Set02 when I run it without also overwriting Set01 and Set03?

And this sounds like it should work too. The Dictionary being a kind of version of DND_Object_Sets - a single file with all the Data in, broken down into Sets of Data?

But I just can't understand the logic of how these Dictionaries work.

Again, I think I am creating confusion for myself by not uploading examples of my actual Macro elements. I didn't do that because the Macros are quite long.

But I have now uploaded the Group of Macros to the Macro Library on the Forum as they are stable and working as they are.

They save Workspaces on the fly that I might need to restore at a later date. In their present form they work well (for me at least) and have have been very useful. But they only Save and Restore a Single Workspace. To have them store and restore Multiple Workspaces I have been copying the Group and bulk changing the Variable names (as I mentioned earlier). This allows me to have my Sets of Workspaces to Save and Restore to - but it does mean if I edit any one of the Macros I have to edit it in all the Groups.

The ideal would be to have just one Macro that does the Saving and tell it at the start which Set to Save to. And just one Restore Macro and tell it at the start which Set to Restore.

Dictionaries work very similarly to Arrays (this is in programming in general) except instead of having a number as the index into the values you have a name. This is called a key-value pair. The dictionary name groups the keys and values together.

So in a traditional array you have multiple values like so:
array_name = (value1,value2,value3)
and can access individual values with
new_var1 = array_name(1)
new_var2 = array_name(2)
new_var3 = array_name(3)
(note, arrays in most languages are zero indexed (first value is at index 0, not 1) so this example isn't exact for them)

In a dictionary instead you name each entry and assign it's value to that name.
dict_name[key1]=value1
dict_name[key2]=value2
dict_name[key3]=value3

then you use the same dictionary/key name to recover the value
new_var1 = dict_name[key1]

In KM accessing dictionaries as a token via:
%Dictionary[dict_name,key1]%

One of KM's super powers is the ability to expand tokens in a variable name then use the result as new variable name, the % can make it hard to read, but it is absolutely a fabulous feature.

varDictName = "Set1"
%Dictionary[%Variable%varDictName%,key1]%

Now your token can refer to multiple dictionaries just by changing the varDictName to be the name of the dictionary you want to use. Or if you just want to embed a number:

varDictNum = 2
%Dictionary[Set%Variable%varDictNum%,key1]%

You can do the same with key names and use variable substitution to change which key you're looking at (I rarely use this).

If in KM you ever need a "true" array, just make your key names into numbers:
secretArray[1] = array_value_1
secretArray[2] = array_value_2
secretArray[3] = array_value_3

This is closer to a true array but can have differences like the numbers don't have to be consecutive and deleting an item leaves a hole, the indexes aren't renumbered.

1 Like

So, I think I am beginning to get this. When I thought of a "Dictionary" I was thinking all the Variables in my Macro would end up stored in one big Dictionary.

But it looks like I can make a "Dictionary" for each Variable I want to store and "Key" number for what actual Data Sets I want them to store or reference?

So, for my Macros I might set up:

"Dictionary Left" to store the left coordinate of a Windowas a number.
"Dictionary Top" to store the top coordinate of a Windowas a number.
"Dictionary Width" to store the width of a Windowas a number.
"Dictionary Height" to store the height of a Window as a number.

And then use the "key" number to allow me to store different values to each Dictionary.

So "Dictionary Left" would have a choice via the "key" number.

Something like "Dictionary Left" "Key 1" (or "Key 2" etc)

I know the syntax is not right for Keyboard Maestro but is this the concept?

Yes, that would work. It's more like the traditional array you were looking at to begin with.

Another option is to group all the related coordinates together in a single dictionary and have multiple dictionaries for each window.

Let's suppose you want to save the coordinates for 2 window both the methods work.

Method 1 dictionary per coordinate, key name is window name:
dict_left[Win1] = window_1_left_coordinate
dict_left[Win2] = window_2_left coordinate

Now your dict_left can store the left coordinate for as many windows as you want. Just add a new Key name for the new window. Expand by creating a dictionary for each of the other coordinates and use the same key name:

dict_top[Win1]=Window_1_top_coordinate

Method 2: Dictionary per window, all coordinates in that dictionary:
dict_Win1[Left]=Window_1_left_coordinate
dict_Win1[Top]=Window_1_top_coordinate
dict_Win1[Width]=Window_1_width_value
dict_Win1[Height]=Window_1_height_value

Now to store a new window just create a new dictionary name:
dict_Win2[Left]=Window_2_left_coordinate

Which ever method makes the most sense to you should work.

1 Like

Yes. If you will give us an example of how you get your source data for each object maybe we could make some suggestions.

Add Set

You can use the Set Variable to Text action with the "Append" option (set in the Gear menu).

Assuming that you have set the "Local__..." variables from your source object:
image
NOTE: The variables are separated by TAB character. Everything is on one line. The KM Editor shows a soft word wrap that will NOT be in the data.

Update Set

You would use a KM Search and Replace action

Assuming that Local__SetID_ is "Set02"
image

I have several Macros that use this design and they work very well.

Questions?

Thank you @kvanh and @JMichaelTX
I can see two solutions here both equally promising. Is there any way to mark both as "the solution" in this thread?

Eureka! I have it now.

For my use this approach works (in this example to Save and Recall the name of the Front Application).

(VAR__ and DCT__ at the start of the Variable and Dictionary names are purely for my own annotation so that I can clearly see what is a Variable and what is a Dictionary.)

To Set a Value

To Recall a Value

The moment it became clear, was linking the method of creating a Dictionary Value to the method of Recalling a Value from it. And the fact that the Key could be a Variable is the solution to my problem.

So, the Dictionary becomes a fancy Variable that allows different values to be saved and recalled governed by a Key - which is what my question at the start of this thread was asking.

The Wiki page confused me because the example it uses for Storing is different to the example it uses for Recalling:

I'm trying to work out Shop Prices and Drink types and Costs that are saved in a Dictionary and then given First Names and Persons as the Recall Example :thinking:

Anyway thank you so much to @kvanh, @tiffle and @JMichaelTX I think I am there now.

3 Likes

Yes, that isn’t very helpful. It should end with the same example it started with. Maybe the wiki can be tidied up?

Anyway - good job getting your head around it :smiley:

1 Like

Congrats to finding a solution that works for you.
:+1:

1 Like

At present the Wiki says this:

I think I would have been a lot less confused if the Wiki had said something more like this:

3 Likes

I agree, that would be clearer.

@peternlewis @JMichaelTX - can the wiki be updated along these lines please?

That will have to be a job for @peternlewis, since I barely understand KM Dictionaries, and almost never use them.

Keyboard Maestro's dictionaries are an extreme PITA to create and maintain.

I'd much rather use a plain text table or a JSON object.

-Chris

2 Likes

I would be more than happy to make the small suggested edit changes to the Wiki myself (but I don't think I have the privileges needed to do that?) as I have found the Dictionaries to be genuinely useful in the last week - having never tried them before. I am sure others would find uses for Dictionaries too and that many have probably given up at the first hurdle.

1 Like

If you would like to post a Topic in the Wiki Category (sub-forum) with your proposed changes, I would be happy to apply them to the actual KM Wiki.

1 Like

Thanks @JMichaelTX - I was just about to do that but see that @ccstone has gone ahead and made the changes to the Wiki.

The most confusing part in the Wiki before was the use of the word "name" in different parts of the explanation rather than "key". This is what gave me a headache the first time when I tried to read the explanation.

It was also confusing having the recall example straight away use a variable (which hadn't been referred to before). Not to mention the recall example being about people (who by coincidence also had "names")... rather than coffee prices...

Once the % symbols and [ and , are understood the final syntax is actually not that hard.

Also good to show that each Value has its own "Set Dictionary" Action - very similar to Setting a Variable.

And as a footnote I see that the AppleScript for setting Dictionaries has now been corrected:

So is the Wiki clear now?

Yes.

If the Wiki had been as it is now, I might not have had to ask the question which started this thread :grinning:

I have finally put all this to use for my Macro - which is now in the Macro Library for anyone else to make use of. It has been fun to do but taken quite a time. It would have been fairly easy to make something just to work for me.. The challenge was to make it robust and simple enough that others could use it too. Thanks for your help guys.

1 Like

So, I joined this forum yesterday and came across this post, and had an issue with what someone posted about not having access to input and output data in array - I went right to work... without reading on. Now that I finished building my "point" I decided to read through. Well, it's a little late, and although you have your solution, I built it, so here's what I have for you.

ARRAY EXAMPLE AND DISPLAY.kmmacros (31.4 KB)

Just run it for demo

Lesson learned - I will read through a post before responding

1 Like