Why do I get an error message when I pick a random item from a list?

I have this list:

property persons : {¬
	{fnamn:"Mary", lnamn:"E Neumann"}, ¬
	{fnamn:"Mark", lnamn:"Lance"}, ¬
	{fnamn:"Connie", lnamn:"Mey"}, ¬
	{fnamn:"Mary", lnamn:"E Neumann"}, ¬
	{fnamn:"Mark", lnamn:"Lance"}, ¬
	{fnamn:"Connie", lnamn:"Mey"}, ¬
	{fnamn:"Mary", lnamn:"E Neumann"}, ¬
	{fnamn:"Mark", lnamn:"Lance"}, ¬
	{fnamn:"Connie", lnamn:"Mey"}, ¬
	{fnamn:"Sara", lnamn:"Wern"}}

I want a random item from this list:

on getPerson(persons)
	if (count of persons) > 0 then
		set i to (random number from 1 to (count persons))
		set person to item i of persons

When the random number is 1 I get this error??

tell current application
	random number from 1 to 9
		--> 1
	(*Error: Can’t get items 1 thru 0 of {{fnamn:"Mary", lnamn:"E Neumann"}, {fnamn:"Mark", lnamn:"Lance"}, {fnamn:"Connie", lnamn:"Mey"}, {fnamn:"Mary", lnamn:"E Neumann"}, {fnamn:"Mark", lnamn:"Lance"}, {fnamn:"Connie", lnamn:"Mey"}, {fnamn:"Mark", lnamn:"Lance"}, {fnamn:"Connie", lnamn:"Mey"}, {fnamn:"Sara", lnamn:"Wern"}}. (-1728)*)

What does Can’t get items 1 thru 0 of mean?? Why “0”? Where does it come from?

I have tried this:


set i to (random number from 1 to 1)
set person to item i of persons

with the same list and it works every time.

try this…

on getPerson(persons)
	local person
	if (count of persons) > 0 then
		set i to (random number from 1 to (count persons))
		set person to item i of persons
	end if
	return person
end getPerson

I suggest you reduce your script to it’s minimal configuration that reporduces the error and post that.

I ran this from ScriptDebugger with no errors. So there seems to be some context that is interfering with your script.

property persons : {¬
	{fnamn:"Mary", lnamn:"E Neumann"}, ¬
	{fnamn:"Mark", lnamn:"Lance"}, ¬
	{fnamn:"Connie", lnamn:"Mey"}, ¬
	{fnamn:"Mary", lnamn:"E Neumann"}, ¬
	{fnamn:"Mark", lnamn:"Lance"}, ¬
	{fnamn:"Connie", lnamn:"Mey"}, ¬
	{fnamn:"Mary", lnamn:"E Neumann"}, ¬
	{fnamn:"Mark", lnamn:"Lance"}, ¬
	{fnamn:"Connie", lnamn:"Mey"}, ¬
	{fnamn:"Sara", lnamn:"Wern"}}

repeat 1000 times
	if (count of persons) > 0 then
		tell current application
			set i to (random number from 1 to (count persons))
			set person to item i of persons
		end tell
	end if
end repeat

1 Like

Unless there’s a specific reason you want to generate a random number yourself, keep it simple:

to getRandomPerson from persons
        tell persons to if its class is in ¬
                [record, list] and it ≠ {} ¬
                then return some item
        missing value
end getRandomPerson

some item of... returns a random item from a list, record, or string. I recall reading somewhere (although I can’t remember where) that it results in a greater degree of randomness than the random number command, which may or may not be true.

1 Like

The reason I use a random number/index is that I remove that entry from the list afterwards. Are there better ways?

I have done that. I have tested with a minimal on run () handler that just initiates the list and call the getPerson () handler with the list.

You still haven’t posted your entire script so we can see that’s going on.

It is indeed the full script and the full output. Yes I saw that estockly couldn’t reproduce it.

I just noticed that you have a global property defined calles persons:

And… your handler declares a local parameter also called persons:

This ordinarily shouldn’t be a problem as the two identifiers are scoped. But, you also go on—although it’s unclear exactly where—to do this:

If this tell block is used inside the local scope of your handler, it’s going to breach containment and make it easy to reference the persons variable outwith the intended scope.


At no point in this thread have you posted your complete script. In fact, you haven’t posted any code that could constitute a partial script, with the exception of your initial property declaration.

Here are your code snippets from your original post combined into a continuous code block:

property persons : {¬
	{fnamn:"Mary", lnamn:"E Neumann"}, ¬
	{fnamn:"Mark", lnamn:"Lance"}, ¬
	{fnamn:"Connie", lnamn:"Mey"}, ¬
	{fnamn:"Mary", lnamn:"E Neumann"}, ¬
	{fnamn:"Mark", lnamn:"Lance"}, ¬
	{fnamn:"Connie", lnamn:"Mey"}, ¬
	{fnamn:"Mary", lnamn:"E Neumann"}, ¬
	{fnamn:"Mark", lnamn:"Lance"}, ¬
	{fnamn:"Connie", lnamn:"Mey"}, ¬
	{fnamn:"Sara", lnamn:"Wern"}}

on getPerson(persons)
	if (count of persons) > 0 then
		set i to (random number from 1 to (count persons))
		set person to item i of persons

tell current application
	random number from 1 to 9
	
set i to (random number from 1 to 1)
set person to item i of persons

If this is copied into Script Editor, it obviously wont compile.

Multiple users requested your full script, and my discussion about variable scope above indicates why providing it would have been crucial in order for people to assist you. For future reference, providing a full script would necessarily mean that the code compiles (unless the issue at hand is one of syntax) and execute (up to the point where the issue at hand throws an exception).

1 Like