Need a 1-based MOD function for calculations

I use the MOD function quite a bit, but KM's MOD function is based on 0 to n-1, while I normally need it to deal with values from 1 to n instead. This results in a lot of extra coding and debugging.

Is it possible to introduce a new function perhaps called MOD1 ("MOD1" means "MOD with a base of 1") which works exactly like MOD but uses the range 1..n instead of 0..n-1? This would simplify my life.

E.g.,

Column 1 Column 2
1 MOD 3 => 1 1 MOD1 3 => 1
2 MOD 3 => 2 2 MOD1 3 => 2
3 MOD 3 => 0 3 MOD1 3 => 3
4 MOD 3 =>1 4 MOD1 3 => 1

There are a few languages which seem to use 1 as the base for MOD, like APL, Lua, R and MATLAB.

I see now that "MOD1" isn't the best name for it, because the "1" looks like an operand, which is confusing. I'm trying to come up with other words that would look nice. The operation that we call MOD is sometimes also called "circular increment" or "wrapping increment." Therefore perhaps a 1-based wrapping operator could be called "WRAP".

E.g., 4 WRAP 3 => 1
E.g., 4 CIRCLE 3 => 1

After pondering this, I think WRAP would be the best operator name for a 1-based MOD.

Are there any other KM users here who would like to see a 1-based MOD operator? Or do you usually need MOD to work with 0..n-1?

You are probably aware of this fix, but this is the way I set it up when needing this:

((i - 1) MOD n) + 1

With your MOD 3 example:
((1 - 1) MOD 3) + 1 => 1
((2 - 1) MOD 3) + 1 => 2
((3 - 1) MOD 3) + 1 => 3
((4 - 1) MOD 3) + 1 => 1

Yes, and the fix you are proposing is the very problem I am trying to solve. :slight_smile:

1 Like

Surely MOD is 0..n-1 -- there's no "usually" about it. It's "the remainder after division" and, as such, has to include 0 and can't include n.

I'm not sure what you mean about other languages doing it differently -- for example, from Matlab help:

Find the remainder after division for a vector of integers and the divisor 3.

a = 1:5;
m = 3;
b = mod(a,m)
b = 1×5

     1     2     0     1     2

...and I'd argue that anything that does do it differently isn't doing mod at all...

3 Likes

Similarly in Lua, both of these expressions print 0

print(3 % 3)

print(math.fmod (3, 3))

and the Lua 5.2 Reference Manual defines math.fmod(x, y) as follows:

Returns the remainder of the division of x by y that rounds the quotient towards zero


My understanding is that definitional variations turn on the sign of the remainder:

Yes, I agree! That's why I wanted it renamed to WRAP, short for "wrapping increment." It's not MOD. This is just semantics. I'm sure you understand what I want, because I made it very clear. And I asked whether people use 0-based or 1-based wrapping calculations, and nobody has replied.

I retract my claim about other languages using 1-based MOD. Sorry.

The number of potentially useful operators is not finite.

Efficiency and elegance both suggest minimising the number of those that are predefined.

1 Like

Well, I have made requests before for new functions that were implemented. So it's possible. I'm hopeful, not pessimistic.

1 Like

TBH I just go with the more verbose but self-documenting:

image

If an extra millisecond or two is really that important you can do it in one action using a ternary:

image

True, a couple of extra millisecond usually makes no human perceivable difference. Ease of reading is much more important. And I must admit that for me, as someone not yet having gone the paces learning myself the boolean operators, simple arithmetic just reads much more fluently.

To me this calculation feels like an operation just straight doing the thing; instead of having to check what was done, possibly correcting it. But I understand that the IF statement (or boolean operations) is possibly the more conventional approach

I'm aware of the ternary operator, for sure, but doesn't that mess prove my case exactly? I don't want to be encoding and then debugging long calculations like that when it could look as simple as this:

image

Of course, I know 90% of my requests are not going to be implemented, but I can still ask.

We're just showing two different approaches to a common problem:

  1. Construct what you need from primitives
  2. Have built-in function to do a (relatively) specific thing

Other languages let us make our own functions within our scripts using primitives -- KM doesn't, though we can spoof them with favourites and/or routines and sub macros.

I'm just not sure that what you want is generally useful enough that it warrants its own built-in function.

That's an interesting idea. Maybe the KM Editor's favourites will help. I use them, but I don't think about them very often.

Or you could get really fancy and write a plug-in:

I whipped this together pretty quickly, so I'm not 100% positive it's foolproof, but it seems to work in testing. To use, drop the zip file (do not unzip!) on the Keyboard Maestro dock icon, then relaunch the editor and the engine.

WRAP function.zip (6.3 KB)

Then just add a new action to a macro—if you're using the Actions list, you'll see the WRAP Function action in the Third Party Plug Ins section of the list. If you're using Edit → Insert Action → By Name (as you should be :slight_smile: ), just type WRAP and it should show up in the list.

Requisite disclaimer: Claude helped me get the modified MOD working in Perl.

-rob.

3 Likes

I cannot imagine I would add an inbuilt operator for MOD1, as it's not really a standard sort of thing. It's possible that I will add some sort of ability to add custom functions, though I imagine that would have some horrible complexities (for example - are they a kind of preference, independent of the macros, but then they can't be used with shared macros, or macro syncing, or are they some sort of new style of macros, but how on earth would that work, it certainly couldn't be made up of actions because calculations have to be instant results.

Hmm. Everything is always more complex than you think it will be.

1 Like

Thanks Peter. Whatever the future holds for KM, I'm very happy about it.