Basically, I need to accomplish the following: “1, 2, 3, 4, 5” → {1, 2, 3, 4, 5}
I do NOT want this: {“1”, "2, “3”, “4”, “5”}
…and I definitely do NOT want this: {“1”, ", ", “2”, ", " “3”, ", ", “4” ", ", “5”}
For some reason, the following doesn’t work properly when copied into this site, but here’s a part of what it is I’m trying to do:
set question to display dialog "Enter number of trials:" default answer "1000"
set trials to (text returned of question)
set choice_wolfram to "\"http://api.wolframalpha.com/v2/query?appid=UERAH9-KW3Y2UHXE8&input=" & trials & "%20random%20integers%20between%201%20and%203" & "&format=plaintext\""
set choice_output to do shell script "curl " & choice_wolfram
set first_choice to text ((offset of "<subpod title=''
primary='true'>
<plaintext>{" in choice_output) + 54) thru ((offset of "<subpod title=''
primary='true'>
<plaintext>{" in choice_output) + ((54 + (trials * 3)) - 3)) of choice_output
set x to "1, 2, 3, 4, 5"
set saveTID to AppleScript's text item delimiters
set AppleScript's text item delimiters to {","}
set theList to text items of x
set AppleScript's text item delimiters to saveTID
repeat with i from 1 to count of theList
set item i of theList to (item i of theList as integer)
end repeat
You could also use the more hack-ish:
set x to "1, 2, 3, 4, 5"
set theList to run script ("{" & x & "}")
It’s a lot shorter, but takes a lot longer to run.
Thank you! The script works perfectly with that! I was a bit worried about adding more repeats to this, but if that really is the only work around for this, it doesn’t seem to add too much extra time to the calculation… So again, thank you!
This works for natural numbers including zero, just as an alternative, I have no idea if it is any faster, or anything, just that it won’t accept decimal numbers (at least not with my decimal separator which is “,”) and negative whole numbers (everywhere). It is here for terseness.
set l to {}
tell (a reference to words of "1, 3 , 2, 3, 4, -5")
repeat with i from 1 to (count of it)
set end of l to item i of it as number
end repeat
end tell
I sat down to test these methods and even with the shortest list I’d use in my script (100 data points) that method was only ever 1 second longer than the other… at most. The difference only went down from there, so I’ll be using the shorter method.
Yvan KOENIG (VALLAURIS, France) vendredi 29 novembre 2013 17:34:29
It was not that. The numbers were formatted the French way with a no break space used as thousand separator.
When I used numbers without this separator, the script did its duty (4440 numbers of 4/5 digits) in less than one second.
Ok… more testing: The run script method is by far the fastest of the two Shane provided, but I get a stack overflow after 8078 items. I personally don’t mind it, but is there a way to remove this limit and keep the fast conversion time?
set x to "1"
repeat 8077 times
set x to x & ", 1"
end repeat
say (count words of x) using "Alex" speaking rate 220 pitch 10 modulation 70
say "Delimiter method:" using "Alex" speaking rate 220 pitch 10 modulation 70
set saveTID to AppleScript's text item delimiters
set AppleScript's text item delimiters to {","}
set theList to text items of x
set AppleScript's text item delimiters to saveTID
repeat with i from 1 to count of theList
set item i of theList to (item i of theList as integer)
end repeat
say "complete" using "Alex" speaking rate 220 pitch 10 modulation 70
delay 1
say "Run script method:" using "Alex" speaking rate 220 pitch 10 modulation 70
set theList to run script ("{" & x & "}")
say "complete" using "Alex" speaking rate 220 pitch 10 modulation 70
set x to x & ", 1"
delay 1
say (count words of x) using "Alex" speaking rate 220 pitch 10 modulation 70
say "Delimiter method:" using "Alex" speaking rate 220 pitch 10 modulation 70
set saveTID to AppleScript's text item delimiters
set AppleScript's text item delimiters to {","}
set theList to text items of x
set AppleScript's text item delimiters to saveTID
repeat with i from 1 to count of theList
set item i of theList to (item i of theList as integer)
end repeat
say "complete" using "Alex" speaking rate 220 pitch 10 modulation 70
delay 1
say "Run script method:" using "Alex" speaking rate 220 pitch 10 modulation 70
set theList to run script ("{" & x & "}")
say "complete" using "Alex" speaking rate 220 pitch 10 modulation 70
You can’t address more than 2^14 elements. I don’t think there is a cure although I haven’t tested having several script objects in one main script, each containing a list of say 2^14 prime numbers.
set x to "1, 2, 3, 4, 5"
script o
property lst : {}
end script
set saveTID to AppleScript's text item delimiters
set AppleScript's text item delimiters to {","}
set o's lst to text items of x
set AppleScript's text item delimiters to saveTID
repeat with i from 1 to count o's lst
set item i of o's lst to (item i of o's lst as integer)
end repeat
return o's lst
Even with lists up to 1200 items it’s better to use the method above (I didn’t test larger files).
Just for the record, my solution in post #5 also uses references, and should be quite fast, since the string literal is turned into a reference to list a of words when it starts to convert the list into positive integers.
The same caveat about positive integers still holds however, so for maximum flexibility unless you aren’t dealing with primenumbers etc, then the script above is better when you have to work around the constraint that you have reached.
You also may try to split it into two lists of course, if that is practical, before you use the run script to convert the strings of numbers into lists.
set x to "1"
repeat 4 times
set x to x & ", 1"
end repeat
say ((count words of x) as text) & " items:" using "Alex" speaking rate 220 pitch 10 modulation 70
script o
property lst : {}
end script
set saveTID to AppleScript's text item delimiters
set AppleScript's text item delimiters to {","}
set o's lst to text items of x
set AppleScript's text item delimiters to saveTID
repeat with i from 1 to count o's lst
set item i of o's lst to (item i of o's lst as integer)
end repeat
say "completed" using "Alex" speaking rate 220 pitch 10 modulation 70
delay 1
repeat 9995 times
set x to x & ", 1"
end repeat
say ((count words of x) as text) & " items:" using "Alex" speaking rate 220 pitch 10 modulation 70
set saveTID to AppleScript's text item delimiters
set AppleScript's text item delimiters to {","}
set o's lst to text items of x
set AppleScript's text item delimiters to saveTID
repeat with i from 1 to count o's lst
set item i of o's lst to (item i of o's lst as integer)
end repeat
say "completed" using "Alex" speaking rate 220 pitch 10 modulation 70
If you want to turn negative numbers into positive numbers you should still use:
set x to read file ((path to desktop folder as string) & "testnumbers.txt")
script o
property lst : {}
end script
set o's lst to words of x
repeat with i from 1 to count o's lst
set item i of o's lst to (item i of o's lst as integer)
end repeat
return o's lst
The script in post #5 hangs with an list of 7000 items (showing beach ball after 1 minute) while this version still does it in less than a second. The difference in code relies only in creating an list of strings, this version just ignores any kind of punctuation including the hyphen.
Not so happy. I timed my version just for the hell of it, and discovered, that that kind of reference didn’t quite work as a reference to a property in a script object. And I don’t even get a beach ball!
I agree fully to the sentiment about negative numbers, that is why I stated that the “word” version only worked with positive, since any dashes gets filtered out as it is not reckognized as a word character.
If you’re talking large numbers, an ASObjC library is a good alternative:
use framework "Foundation"
on intsFromString:y
set aString to current application's NSString's stringWithString:y
return ((aString's componentsSeparatedByString:",")'s valueForKey:"intValue") as list
end intsFromString:
OMM, the difference for 1000 items is 0.004 seconds vs 0.042 seconds. But it’s probably going to be slower for fewer than about 40 items.
Just in case if anyone wants to create the random list by itself instead of grabbing from an webservice:
createRandomList(1, 45, 10000)
on createRandomList(f, t, s)
script o
property orderedNumbers : {}
property randomNumbers : {}
end script
repeat with x from f to t
set end of o's orderedNumbers to x
end repeat
repeat s times
set end of o's randomNumbers to some item of o's orderedNumbers
end repeat
return o's randomNumbers
end createRandomList
That was mostly me just playing with the WolframAlpha api, but yeah… using AppleScript to generate the list does simplify things a bit further.
The link in my original post uses WolframAlpha, but I’ll use AppleScript from now on.
This is pretty much near final:
set pool to 1000
set trial to 1
set trials to ""
on createRandomList(f, t, s)
script o
property orderedNumbers : {}
property randomNumbers : {}
end script
repeat with x from f to t
set end of o's orderedNumbers to x
end repeat
repeat s times
set end of o's randomNumbers to some item of o's orderedNumbers
end repeat
return o's randomNumbers
end createRandomList
script o
property lst : {}
end script
repeat
set question to display dialog "Enter size of data pool:" with title "The Monty Hall Problem" default answer pool
set pool to (text returned of question)
set first_choice to createRandomList(1, 3, pool)
set the_car to createRandomList(1, 3, pool)
set the_goat to createRandomList(1, 2, pool)
set final_choice to {}
set choice_tf to {}
set choice_true to ""
repeat with x from 1 to pool
if item x of first_choice is equal to 3 then
if item x of the_car is equal to 1 then set item x of the_goat to 2
if item x of the_car is equal to 2 then set item x of the_goat to 1
if item x of the_goat is equal to 1 then set final_choice to final_choice & 2
if item x of the_goat is equal to 2 then set final_choice to final_choice & 1
end if
if item x of first_choice is equal to 1 then
if item x of first_choice is equal to item x of the_car then set item x of the_goat to (item x of the_goat) + 1
if item x of the_car is equal to 2 then set item x of the_goat to 3
if item x of the_car is equal to 3 then set item x of the_goat to 2
if item x of the_goat is equal to 2 then set final_choice to final_choice & 3
if item x of the_goat is equal to 3 then set final_choice to final_choice & 2
end if
if item x of first_choice is equal to 2 then
if item x of first_choice is equal to item x of the_car then
if item x of the_goat is equal to 2 then set item x of the_goat to 3
end if
if item x of the_car is equal to 1 then set item x of the_goat to 3
if item x of the_car is equal to 3 then set item x of the_goat to 1
if item x of the_goat is equal to 1 then set final_choice to final_choice & 3
if item x of the_goat is equal to 3 then set final_choice to final_choice & 1
end if
if item x of final_choice is equal to item x of the_car then
set choice_tf to choice_tf & true
set choice_true to choice_true + 1
else
set choice_tf to choice_tf & false
end if
end repeat
set percent to ((choice_true * 100) / pool)
set final_output to (trial as text) & ": " & "Switching wins " & choice_true & " out of " & pool & ", or " & percent & "%."
set dialog_text to trials & final_output
set question to display dialog dialog_text with title "The Monty Hall Problem" buttons {"Quit", "Run another trial"} default button 2
if button returned of question is equal to "Quit" then
error number -128
else
set trials to trials & final_output & "
"
set trial to trial + 1
end if
end repeat