Examples of CALCULATE() Function

I was discussing with @Airy, @Nige_S and @peternlewis about how some Text Functions work in this thread. Although we shared a few CALCULATE() examples to highlight some of its unique behaviors/quirks, I believe there are better use cases that truly showcase its benefits.

To start, I created an "Example Macro" that takes advantage of features in CALCULATE() that aren’t accessible through the Calculate action/token. While the macro could be made more efficient using other methods, @Airy was interested in exploring “possible tricks” we can add to our toolbox for solving new types of problems.

CALCULATE Function example.kmmacros (11.6 KB)

Macro as Image

EXPLANATION

This Keyboard Maestro macro calculates discounts by dynamically constructing and evaluating mathematical expressions using the CALCULATE() function.

The central calculation is performed in this action:
CALCULATE(purchaseAmount * Tier%TierID%Discount)

Here’s how it works:

The macro dynamically creates a variable name inside the CALCULATE function by concatenating three parts:

  1. The static text "Tier"

  2. The value of the TierID variable (which is set to "1", "2", "3", or "Employee" earlier in the loop)

  3. The static text "Discount"

For instance:

  • If a purchase qualifies for the third tier, the TierID variable becomes 3. The expression resolves to purchaseAmount * Tier3Discount

  • For an employee, TierID is set to Employee, and the expression resolves to purchaseAmount * TierEmployeeDiscount

The CALCULATE() function evaluates this dynamically generated string, retrieves the correct discount percentage from the corresponding variable (e.g., Tier3Discount or TierEmployeeDiscount), and completes the multiplication. This method allows a single, adaptable action to handle dynamic discount rules.

It would be nice if you could share other examples of the CALCULATE() Function =)

2 Likes

Can I first make a plea for the use of Local variables in any examples? Yes, I know this macro nukes the variables at the end -- but what if one of your variable names matches one of mine, a variable that I wanted to persist?

Secondly -- isn't this just a special case of indirection? You can easily -- and much more explicitly -- do what you want with

image

Yes, it's an extra action (Oh noes, a whole extra millisecond per loop! :wink: ) but I'd argue it is much more readable and -- importantly -- it works with the Debugger. You can step through and see how Local_discountLevel is constructed and applied, whereas the CALCULATE() function is a black box.

The only advantage I can see is that CALCULATE() etc will instantly dereference through multiple (unknown at build time) levels -- while that could come in handy in very special cases, it's more likely a sign that the macro needs refactoring.

While I'm all for neat tricks -- especially when, as here and in the original thread, they provoke useful discussion about the inner workings of KM, if they don't offer anything over "standard" actions then they are just tricks...

2 Likes

Yeah, I thought about that myself. Especially when there are better methods that are more flexible and maintainable (Keyboard Maestro Dictionaries or just JSON objects).

Done.

1 Like