How to implement "(A and B) or (C and D)" -- when A,B,C,D are complex conditions

KM is amazing, of course, and fulfills most of my programming needs. On occasion I have to find workarounds for certain issues. For example, the IF action has the following four options:

Screenshot 2024-03-27 at 21.07.11

Most people probably use both of the first two choices ("ANY", "ALL".) However at least once a week I need to check several conditions with a mixture of AND and OR, such as "IF (A and B) or (C and D)" which isn't covered by the four KM options above. And when I talk about A, B, C and D, I'm not talking about simple variables, I'm talking about complex conditions like the state of a modifier or the result of finding an image on the screen.

There are two ways that a person is likely to solve this problem.

  1. By creating a variable AB which is assigned the result of the truth of the evaluations of A and B, then doing the same thing for a variable called CD, then creating a new statement checking if AB or CD.
  2. By creating a new macro which I will call Macro1, and then calling Macro1 twice in the original macro with the following two sequential statements:
  • If A AND B then call Macro1
  • If C AND D then call Macro1

Creating an extra couple of variables for every IF statement is somewhat tolerable. Creating an extra macro for every IF statement is not tolerable. And even worse, I sometimes don't create an external Macro and just duplicate the code which is horrible. Having duplicated lines of code in the same macro is very poor programming.

But this week I came up with a third solution that avoids the creation of variables or the creation of a new macro. It works like this: (using four hypothetical tests for A, B, C and D.)

image

Notice how this approach is fully able to test four conditions ("(A and B) or (C and D)") without creating temporary variables or an external macro. I've been using it for a few days now and I think I like it. It's probably not what the TRY/THROW actions were created for, but it works. Let me know if you see a problem with my approach.

At this point you can stop reading, unless you really like a challenge....

I have never needed to test "(A OR B) AND (C OR D)." It's probably not common to need to test that combination. As I write this post, I think I realize how to implement it using TRY/THROW. You have to make three changes to the above action to make it work this way:

  1. Change "all of the following" to "none of the following."
  2. Negate each of the four tests to the opposite of what they are (for example, if your test A is "Finder is at the front" then change it to "Finder is not at the front."
  3. Move the actions that you want to execute from the OTHERWISE clause of the TRY statement up to being the last statement of the TRY clause.

Thankfully it's not a common thing to want to test "(A OR B) AND (C OR D)" so I probably don't have to explain why the above will work.

1 Like

It's an interesting solution. I'm not sure I'd advocate it, because it's a little hard to understand unless you know the idiom.

Generally, I'd just do:

  • If A AND B
    • Set variable "Local Doit" to 1
  • Else
    • If C AND D
      • Set variable "Local Doit" to 1
    • Else
      • Set variable "Local Doit" to 0
  • If “Local Doit” is 1
    • Do stuff
  • If A OR B
    • If C OR D
      • Do stuff
2 Likes