Modding Numbers - A Response...

A response to Craig Smith’s Math Article…

"I am not a mathematician by any means, so I have very little idea about why this is called mod, or even what it is really useful for, but I think that it at least has a coolness factor that deserves discussion. "
“Modular arithmetic (sometimes called modulo arithmetic, or clock arithmetic because of its use in the 24-hour clock system) is a system of arithmetic for integers, where numbers “wrap around” after they reach a certain value ” the modulus. Modular arithmetic was introduced by Carl Friedrich Gauss in his book Disquisitiones Arithmeticae, published in 1801.” from http://en.wikipedia.org/wiki/Modular_arithmetic

“And although interesting, I still can’t think of a real world application for this.”


set r to {}
set desiredRepeatValue to 9 -- This is the highest value I want to use
repeat with a from 1 to 30 -- But I have 30 things to iterate through...
	set r to r & (a mod (desiredRepeatValue + 1)) -- So I mod my incrementer by my highest value + 1.
	-- Without the "+1" you won't get the high value because any clean division of a number equals zero.
	-- Poorly worded maybe... In this case, clean means "a factor of" like 30 is a factor of 10. Hey I'm no mathmagician either!
end repeat
-- returns: {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 1, 2, 3, 4, 5, 6, 7, 8}

I often use mod for times when I need a series of repeating values. Say I need to make 20 picture boxes, each with an Applescript tag of “Image_1” (“Image_2”,etc.), on a each page but I have 10 pages to do this on. I know every page will require me to “reset” my variables so the boxes fall in the same place on each page. This allows me to iterate through the 10 pages with the mod function “resetting” the variable at each page interface.

Very simplified example…


set r to {}
set numberOfPages to 10
set highestTagValue to 20
repeat with a from 1 to (numberOfPages * highestTagValue)
	set r to r & (a mod (highestTagValue + 1))
end repeat

Hopefully that wasn’t too horrible of an explanation. It’s not a function you necessarily use everyday but there are some clever uses some of you may not have thought of.

Jim Neumann
BLUEFROG

Jim:

This is exactly the kind of stuff I was talking about; a clever use of an obscure mathematical function. Do you mind posting it as a reply to current article? I think it is tremendous.

Glad you liked it. I felt brain dead when I wrote it this morning so I wasn’t sure it even made sense! :slight_smile:

So how do I post it specifically as a reply to your article?

-Jim

Also:

-- Hours, minutes, and seconds from current time (pre-Tiger):
set t to time of (current date)
set hr to t div hours
set min to t mod hours div minutes
set sec to t mod minutes

-- Is one number an exact multiple of another?
set n1 to 369
set n2 to 3
if (n1 mod n2 is 0) then "Yes!"

-- Similarly, is a number even?
if (n1 mod 2 is 1) then "No!"

-- Current system version:
tell (system attribute "sysv") to set sysv to ((it div 4096) as Unicode text) & it mod 4096 div 256 & "." & it mod 256 div 16 & "." & it mod 16

-- Number to binary string:
set n to 4097
set bin to ""
repeat until (n is 0)
	set bin to bin & n mod 2
	set n to n div 2
end repeat
if (count bin) is 0 then set bin to "0"
bin

-- Next Thursday's date:
tell (current date) to set nextThursday to it - (it - («data isot3130303030313032» as date)) mod weeks + weeks

-- Etc..

Hi Jim,

Great to hear from you. :smiley:

As Craig’s article was just released this morning, it is on the ‘cover’ so there is no way to comment right now. [sorry!!]

However, once it runs its course, it will be moved to unScripted, which at that time you may post your above as a comment.

I hope this helps you, and hope this isn’t an inconvenience.

Ray: Shouldn’t be a problem since I’m on MacScripter at least 5 or 6 times a day every day that I’m near a computer. :cool: (And I usually make a PDF archive of the front page every Monday for my library!)

Nigel: Well played, old chap. I forgot to post my use in determining Odd / Even but I had forgotten mod’s utility in date manipulations. And the other examples are new to me. Very cool stuff.

-Jim

Thanks for posting, BLUEFROG. :slight_smile:

I think this is similar to what you posted, but I thought I would share it.

set fileList to {"a", "b", "c", "d"}
set fileCount to count fileList

repeat with counter from 1 to fileCount
	(counter + (fileCount) - 2) mod (fileCount) + 1
	set prev to item result of fileList
	
	(counter) mod (fileCount) + 1
	set next to item result of fileList
	
	log {prev, next} -- Check the event log
end repeat

The prev/next lines are from one of my first AppleScript apps. (Thanks to whoever helped with that!)

That said, I usually use modulo to determine if a number is even or odd. I’ve also used it to switch ones and zeros:

set n to 1
set n to (n + 1) mod 2
-- Append an English ordinal suffix to a number, returning the result as string.
on ordinalise(n)
	set units to n mod 10
	if (units > 3) or ((n - units) mod 100 is 10) or (units < 1) or (units mod 1 > 0) then return (n as string) & "th"
	return (n as string) & item units of {"st", "nd", "rd"}
end ordinalise

ordinalise(123)

.

Hey! Less of the “old”! :wink:

:smiley: Wow! :smiley: this has got to be one of the best threads I’ve read in awhile (and not because I started it :lol:)

Modding numbers (if I may coin a phrase… I’ve always wanted to) is one of those “I’ve seen it but don’t know what it’s for topics” and these snippets give some really useful conceptual starting points. I’m wondering if this should be moved and/or crossposted to the Code Exchange section. Ray? Bruce?

I’ve always had some good modding tricks up my sleeve but man, this is inspiring stuff.

and Nigel: Thanks, young chap! :stuck_out_tongue:

Cheers,
Jim

Whilst not interesting a real world use for me is just plain old metric imperial conversions. My CAD files come with metric measusers marked on my artwork files require both. I use the clipboard as go between as it avoids “smart quotes” in my apps. I too use for even & odd, left & right pages in my case.

try
	set MMmeasure to the clipboard as integer
	-- round to nearest inch
	set Inchmeasure to round (MMmeasure / 25.41) rounding to nearest
	-- return string with measure marks
	set TheAnswer to ((Inchmeasure div 12) & (ASCII character 39) & space & (Inchmeasure mod 12) & (ASCII character 34)) as string
	set the clipboard to TheAnswer
on error
	display dialog "Copy your numbers only please!" buttons {"OK"} giving up after 2 with icon caution
end try

Sounds OK to me; Moving to Code Exchange…

you guys are incredibly amazing. :cool:

Nigel wrote:

-- Next Thursday's date:
tell (current date) to set nextThursday to it - (it - («data isot3130303030313032» as date)) mod weeks + weeks

Adam asks: how was “Thursday, January 2, 1000 12:00:00 AM” derived as «data isot3130303030313032»?

Hi, Adam.

Reverse engineering. :slight_smile:

date "Thursday 2 January 1000 00:00:00" as «class isot»
--> «data isot313030302D30312D30325430303A30303A3030»

You’ll instantly recognise those numbers as the hexadecimal of the ascii codes for “1000-01-02T00:00:00”, the date in ISO standard format:

date "Thursday 2 January 1000 00:00:00" as «class isot» as string

The nice thing about thing about this is that it’s portable as text in AppleScript fora and coercing it to date should work on an OS X system of any nationality. The time portion and the dashes weren’t necessary for the “Next Thursday” script, so I edited the data to contain just the hexadecimal codes for “10000102”. :slight_smile:

Neat as always, Nigel. While the following could be easily compressed, it shows your process:

set tDate to "Jan 2, 1000"
set isot to (date tDate) as «class isot» as string
--> "1000-01-02T00:00:00" -- the iso date/time
set O to (offset of "T" in isot) - 1 -- find the end of the date string portion
set isot to (text 1 thru O of isot) as «class isot» -- grab the first part
--> «data isot313030302D30312D3032»

And as an aside:

set baseDate to "T00:00:00" as «class isot» as date
--> date "Tuesday, November 23, 0002 12:00:00 AM"

Back on topic: :wink:

on isLeapYear(y)
	return (y mod 4 is 0) and not ((y mod 100 is 0) and (y mod 400 > 0))
end isLeapYear

{isLeapYear(1900), isLeapYear(1904), isLeapYear(2000), isLeapYear(3507)}

Edit: A minor optimisation to lose the ‘not’:

on isLeapYear(y)
	return (y mod 4 is 0) and ((y mod 100 > 0) or (y mod 400 is 0))
end isLeapYear

The handler also works if the second and third conditions aren’t parenthesised together “

on isLeapYear(y)
	return (y mod 4 is 0) and (y mod 100 > 0) or (y mod 400 is 0)
end isLeapYear

“ but is measurably slower over a range of 400 years. (Even slower than the ‘not’ version, in fact.) With the parenthesis in place, (y mod 400 is 0) is only tested on the 4 occasions out of 400 that y is divisible by 100. Without the parenthesis, it’s tested those 4 times plus (uselessly) the 300 times out of 400 that y isn’t divisible by 4. I love details like that. :slight_smile:

i’ve used the mod function for circular queues/stacks in java and c++. i’ve never used the mod function in applescript, but im still learning. thanks for these tips guys.

Late to the party, but…

On the topic of mod arithmetic.

I use it frequently in routines that lay out rows of icons on my desktop, but those are pretty pedestrian uses (beneficial none the less). But one place it’s very much in use is the implementation of the RSA public key encryption algorithm. This includes RSA’s use in PGP as well as many other crypto schemes.

One uses the mod operator both to encrypt and to decrypt the ciphertext in this scheme. The public key includes both an exponent and a modulus (as does the private key). The gory details aren’t going to mean a lot to you, but just understand that it’s a vital part of the RSA scheme.

The actual RSA implementation isn’t really very difficult at all. Just a few easy to understand equations. But understanding the number theory behind it to know WHY it works to encrypt something so strongly is rather daunting. Something Nigel would be entertained with though. He’s a clever mathematician. :slight_smile:

  • web

Hi, Bill. Welcome to these fora. Hope we’ll see you around quite a bit. :slight_smile: