Set number of digits to randomly generate

I’ve got some Applescript code to generate a random number, but I’m not quite sure how to take user input from the dialog box to set the number of digits to generate.

Here is my code so far…

set rand_num to my makeRandomNumbersString(15, 9, "")

on makeRandomNumbersString(arraySize, numberMax, numberDelimiter)
	set rndArray to {}
	repeat with n from 1 to arraySize
		set rndArray to rndArray & ((random number (numberMax) as integer) as string)
	end repeat
	set {olddelims, text item delimiters} to {text item delimiters, numberDelimiter}
	set retVal to rndArray as string
	set text item delimiters to olddelims
	return retVal
end makeRandomNumbersString

display dialog rand_num

I was thinking of something like

set arraySize to text returned of (display dialog "How many digits?" default answer "")

but that doesn’t seem to work.

Model: MacBook Pro
AppleScript: 2.21
Browser: Google Chrome 5.0.307.9
Operating System: Mac OS X (10.6)

Hi,

try this


set arraySize to text returned of (display dialog "How many digits?" default answer "")
set rand_num to my makeRandomNumbersString(arraySize as integer, 9, "")

How I would do it:

set quantity to displayDialogInteger("The amount of digits")

randomNumbersString(quantity, 0, 15, " ")

on randomNumbersString(aLength, aMin, aMax, aDel)
	set myArray to {}
	repeat aLength times
		set end of myArray to random number from 1 to aMax
		set end of myArray to aDel
	end repeat
	if (count myArray) > 1 then set myArray to items 1 thru -2 of myArray
	return myArray as string
end randomNumbersString

on displayDialogInteger(aMessage)
	set myNumb to text returned of (display dialog aMessage default answer "")
	try
		set myNumb to myNumb as integer
	on error
		set myNumb to displayDialogInteger("\"" & myNumb & "\" couln't be converted into a number")
	end try
	
	return myNumb
end displayDialogInteger

Ief2

Thanks very much for that, that solves it :slight_smile:

Pretty cool handler.

As I understand it, it is unique in that it bypasses AppleScript’s maximum integer limit. With it, you can build numerical strings of rather large length.

I would just remove unnecessary coercions (as integer as string) in the repeat loop:


set rand_num to my makeRandomNumbersString(15, 9, "")

-- or
-- set arraySize to text returned of (display dialog "How many digits?" default answer "15")
-- set rand_num to my makeRandomNumbersString(arraySize as integer, 9, "")

on makeRandomNumbersString(arraySize, numberMax, numberDelimiter)
	set rndArray to {}
	repeat with n from 1 to arraySize
		set end of rndArray to random number numberMax
	end repeat
	set {ATID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, numberDelimiter}
	set retVal to rndArray as string
	set AppleScript's text item delimiters to ATID
	return retVal
end makeRandomNumbersString

Also, it would be interesting to know if there is a way to do the same without the repeat loop?

So far my question is purely academic because I don’t see any practical application yet. Perhaps a handler can be used to effectively randomize media across 10 (or fewer) playlists.

NOTE: as integer coercion no need because random number with integer parameter returns integer by default. As string coercion no need because this coercion does set retVal to rndArray as string code line.

The user can get random real between 0 and 9 this way:


random number 9 as real
-- or:
-- random number 9.0

random number without parameters returns real between 0 and 1, as I checked now:


random number

→ 0.558887445683

Without the “as integers” this returns a real.

If the direct parameter, or either of the from/to numbers are reals random number returns a real. If they’re all integers, it returns an integer.

As per the dictionary, the default direct parameter is 1.0, a real.


set numberOfDigits to 5
random number from 10 ^ (numberOfDigits - 1) as integer ¬
	to (10 ^ numberOfDigits) - 1 as integer

Now, suppose you needed a Random Number with more than 8 digits, but it could be a string…

repeat with numberOfDigits from 1 to 100
	set anUnlimitedRandomNumber to my NoLimitRandomNumber(numberOfDigits)
	set numberSize to count of anUnlimitedRandomNumber
	if numberOfDigits - numberSize is not 0 then
		beep
	end if
end repeat
on NoLimitRandomNumber(numberOfDigits)
	if numberOfDigits < 9 then return (random number from 10 ^ (numberOfDigits - 1) as integer ¬
		to (10 ^ numberOfDigits) - 1 as integer) as text
	set TheRando to {}
	set rootNumber to numberOfDigits
	set numberOfDigits to 8
	repeat
		set the end of TheRando to (random number from 10 ^ (numberOfDigits - 1) as integer ¬
			to (10 ^ numberOfDigits) - 1 as integer) as text
		set rootNumber to rootNumber - numberOfDigits
		if rootNumber = 0 then exit repeat
		if rootNumber < 9 then set numberOfDigits to rootNumber
	end repeat
	set saveTID to AppleScript's text item delimiters
	set AppleScript's text item delimiters to {""}
	set TheRando to TheRando as text
	set AppleScript's text item delimiters to saveTID
	return TheRando
end NoLimitRandomNumber

(There are probably more efficient ways of doing this)

Your example is extremely bad. Because the result of raising to a power is a real.

10 ^ 2 --> 100.0

Also, what’s the point of you repeating my words about what type of parameter AppleScript determines what type of random number to generate?

As for the script in post #7, it’s more useful. I tested it just now. It is very faster than the original solution. Thank you for this. I refined it little:


on noLimitRandomNumbersString(numberOfDigits, numberDelimiter)
	if numberOfDigits < 9 then
		set theRando to (random number from 10 ^ (numberOfDigits - 1) to (10 ^ numberOfDigits) - 1) as integer
	else
		set {theRando, rootNumber, numberOfDigits} to {{}, numberOfDigits, 8}
		repeat until rootNumber = 0
			set end of theRando to (random number from 10 ^ (numberOfDigits - 1) to (10 ^ numberOfDigits) - 1) as integer
			set rootNumber to rootNumber - numberOfDigits
			if rootNumber < 9 then set numberOfDigits to rootNumber
		end repeat
	end if
	set {ATID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, ""}
	set theRando to characters of (theRando as text)
	set AppleScript's text item delimiters to numberDelimiter
	set theRando to theRando as text
	set AppleScript's text item delimiters to ATID
	return theRando
end noLimitRandomNumbersString

noLimitRandomNumbersString(180, " ")

Which is why it’s coerced to integer. Very little overhead there.

I didn’t repeat your words. I explained it more fully and clearly, and pointed the reader to the dictionary, which also explains that behavior.

I will have a look, thanks

Am I missing something? Providing a “numberDelimter” parameter and then using it to separate digits in the number does not seem necessary, and slows things down.

If I ever needed to do that, I think I would have a separate routine.

I don’t think that this will give you the full range of possibilities (i.e. 100,000 for 5 digits). Using ‘10’ as your base gives you a floor of 10000 and a ceiling of 99999 — or 90000 possibilities. You won’t ever get a result below 10000.

Likewise, if you try it with 1 or 2 digits —because it is easier to envision— you will get a range of 1 to 9 (instead of 0 to 9) or 10 to 99 (instead of 0 to 99). Also, by using these smaller numbers, you can quickly see that no results from the lowest decile ever appear.

If your ceiling is 10^x -1 then your floor should be 0. It shouldn’t vary with the number of digits.

In this case, the OP wanted a random number with a specific number of digits.

The low and high numbers represent the smallest integer with the specified number of digits and the largest integer with that number of digits.

What you’re suggesting is simply setting a high limit and the number of digits of the result could be anywhere from 1 to numberOfDigits.

Which is fine, if that’s what you want, but I don’t think that’s what the OP wants.

First off, I don’t think any of the posts from this decade are deeply concerned with the OP’s desires. However, taking that post into account — where does it say that the random number should exclude 10% of numbers in the range?

Please look again because your solution will not actually produce the ‘smallest integers’. You might consider re-reading my post as well since I am actually suggesting that the lower limit should be 0 and thus, the range would be 0 to 9 for each digit — which is generally how random numbers are generated.

You said this:

Any integer result below 10000 would have less than 5 digits.