AppleScript for Python Programmers (Comparison Chart)

Written by on July 01, 2005

I'm a Python programmer who switched to Mac OS X. Being nerd and needing to automate common tasks, the learning of the AppleScript language was unavoidable. To speed up the process I've took some notes, comparing the new commands to Python statements. The result is this document.

As the name says, it's intended for Python programmers. But if you're an applescripter interested in Python you may also learn a lot.

Python AppleScript
indexes start with 0 indexes start with 1
string comparison considers case string comparison ignores case
# comments -- comments
command # half-line comment command -- half-line comment
"""
multiline comment block (sort of)
"""
(*
multiline comment block
*)
a = 5 set a to 5
a = "foo" set a to "foo"
print "Hello World" display dialog "Hello World"
syslog.syslog(msg)
or
print >>sys.stderr, msg
log(msg)
print "\a" beep
say "Hello World"
Data types
type("foo").__name__ class of "foo"
None missing value
True, False true, false
2 2
"foo"
or
'foo'
"foo"
"""foo
bar"""
"foo
bar"
[ 1, 2, 3 ] { 1, 2, 3 }
( 1, 2, 3 )
{ "foo": "bar" } { foo: "bar" }
str(5) 5 as text
int("5") "5" as integer
float(5) 5 as real
float("5") "5" as real
list("foo") characters of "foo"
"".join([ "f","o","o" ]) { "f","o","o" } as text
"".join([str(x) for x in [ 1, 2, 3 ]]) { 1, 2, 3 } as text
String
S = "" set S to ""
S = "foo" set S to "foo"
len(S) length of S
or
count S
S[2] item 3 of S
S[len(S)/2] middle item of S
S[random.randint(0, len(S)-1)] some item of S
S[2:-2] items 3 thru -3 of S as text
S + "foo" S & "foo"
S.index("z")
or
S.find("z")
offset of "z" in S
S.startswith("z") S starts with "z"
S.endswith("z") S ends with "z"
S.count("z") User function countSubstring()
S.split() words in S
S.split()[2] word 2 of S
S.split(":") set AppleScript's text item delimiters to ":"
text items of S
set AppleScript's text item delimiters to ""
":".join(LIST) set AppleScript's text item delimiters to ":"
LIST as text
set AppleScript's text item delimiters to ""
S.lstrip() User function lstripString()
S.rstrip() User function rstripString()
S.strip() User function stripString()
S.lower() User function lowerString()
S.upper() User function upperString()
S.capitalize() User function capitalizeString()
S.replace() User function replaceString()
"z" in S "z" is in S
\\ \" \t \n \r \\ \" \t \r space tab return
S = "foo\nbar" set S to "foo" & return & "bar"
S = """foo "bar" baz""" set S to "foo \"bar\" baz"
List
L = [] set L to {}
L = [ 77, "foo", True ] set L to { 77, "foo", true }
L = [ 1, [ 2, [ 3 ]]] set L to { 1, { 2, { 3 }}}
len(L) length of L
or
count L
[x for x in L if isinstance(x, int)] integers in L
[x for x in L if isinstance(x, str)] strings in L
L[2] item 3 of L
L[2][2] item 3 of item 3 of L
L[len(L)/2] middle item of L
L[random.randint(0, len(L)-1)] some item of L
newlist = L[:] set newlist to every item of L
or
copy L to newlist
L[2:-2] items 3 thru -3 of L
L + [ 1, 2 ]
or
L.extend([ 1, 2 ])
L & { 1, 2 }
L.append("foo") set the end of L to "foo"
or
copy "foo" to the end of L
L[2] = "foo" set item 3 of L to "foo"
del L[2] set L to items 1 thru 2 of L & items 4 thru -1 of L
L.index("foo") User function getListItemIndex()
L.count("foo") User function countListItem()
L.pop(0) first item of L
set L to rest of L
L.pop(0) ; L[:] rest of L
L.reverse() reverse of L
L.sort()
"foo" in L "foo" is in L
L[0] == "foo" L starts with "foo"
L[-1] == "foo" L ends with "foo"
Dictionary / Record
D = {} set D to {}
D = { "foo":"bar", "spam":"eggs" } set D to { foo:"bar", spam:"eggs" }
len(D) length of D
or
count D
D["foo"] foo of D
D["foo"] = "bar" set foo of D to "bar"
D + { "foo":"bar" }
or
D.update({ "foo":"bar" })
D & { foo:"bar" }
newdic = D.copy() copy D to newdic
del D["foo"]
D.keys()
D.values()
D.has_key()
D["foo"] == "bar" foo of D is "bar"
D.get("foo") == "bar" { foo:"bar" } is in D
Expressions
1 + 1 1 + 1
1 - 1 1 - 1
1 * 1 1 * 1
1 / 1 1 div 1
1.0 / 1.0 1 / 1
or
1 ÷ 1
1 % 1 1 mod 1
1 ** 1 1 ^ 1
(2 + 4) * 2 (2 + 4) * 2
1 == 1 1 = 1
or
1 is equal 1
1 != 1 1 ≠ 1
or
1 is not equal 1
1 > 1 1 > 1
or
1 is greater than 1
1 < 1 1 < 1
or
1 is less than 1
1 >= 1 1 >= 1
or
1 ≥ 1
or
1 isn't less than 1
1 <= 1 1 <= 1
or
1 ≤ 1
or
1 isn't greater than 1
1 is 1 1 is 1
1 is not 1 1 is not 1
1 is 1 or 2 is 2 1 is 1 or 2 is 2
1 is 1 and 2 is 2 1 is 1 and 2 is 2
(1 is 1) and (2 is 2) (1 is 1) and (2 is 2)
Conditionals
if VAR == 1: print "OK" if VAR = 1 then display dialog "OK"
if VAR == 1:
print "OK"
if VAR = 1 then
display dialog "OK"
end if
if VAR == 1:
print "OK"
else:
print "Error"
if VAR = 1 then
display dialog "OK"
else
display dialog "Error"
end if
if VAR < 10:
print "Need more!"
elif VAR > 20:
print "Too much!"
else:
print "It's OK"
if VAR < 10 then
display dialog "Need more!"
else if VAR > 20 then
display dialog "Too much!"
else
display dialog "It's OK"
end if
Loops
for i in LIST:
print i
repeat with i in LIST
display dialog i
end repeat
while 1:
break
repeat
exit repeat
end repeat
while 1:
continue
while VAR is False:
# do something
repeat while VAR is false
-- do something
end repeat
while VAR is not False:
# do something
repeat until VAR is false
-- do something
end repeat
for i in range(10):
# do something
repeat 10 times
-- do something
end repeat
for i in range(1, 10, 2):
# do something
repeat with i from 1 to 10 by 2
-- do something
end repeat
Functions
def add_numbers(a, b):
return a + b
on add_numbers(a, b)
return a + b
end add_numbers
five = add_numbers(2, 3) set five to add_numbers(2, 3)
def optional(a=0, b=""):
Class / Script
class FooBar(Father):
VAR = 0
def setValue(self, val):
self.VAR = val
script FooBar
property parent : Father
property VAR : 0
on setValue(val)
set my VAR to val
end setValue
end script
myFoo = FooBar()
myFoo.setValue(5)
myData = myFoo.VAR
copy FooBar to myFoo
tell myFoo to setValue(5)
set myData to VAR of myFoo
File Read/Write
F = open("/tmp/foo")
TXT = F.read()
F.close()
set F to "/tmp/foo" as POSIX file
set TXT to read F
F = open("/tmp/foo")
LINES = F.readlines()
F.close()
set F to "/tmp/foo" as POSIX file
set LINES to read F using delimiter (ASCII character 10)
F = open("/tmp/foo", "w")
F.write("Hello!\n")
F.close()
set F to "/tmp/foo" as POSIX file
set F to open for access F with write permission
write "Hello!" & return to F
close access F
Path
(requires tell app "Finder")
os.path.isfile(F) file F exists
os.path.isdir(F) folder F exists
os.path.abspath(F) file F as text
os.path.dirname(F) folder of file F as text
os.path.basename(F) name of file F
F.split(os.path.extsep)[-1] name extension of file F
os.stat(F)[6] size of file F
pwd.getpwuid(os.stat(F)[4])[0] owner of file F
grp.getgrgid(os.stat(F)[5])[0] group of file F
open(newfile, "w").write(open(F).read()) duplicate file F to file newfile
os.rename(F, newfile) set name of file F to newfile
os.unlink(F) delete file F
Date & Time
time.asctime() current date as string
T = time.localtime() set T to current date
T = time.strptime(
"Jan 31, 2005 17:59",
"%b %d, %Y %H:%M" )
set T to date "Jan 31, 2005 17:59"
orig = time.mktime(time.strptime(
"Jan 31, 2005 17:59",
"%b %d, %Y %H:%M" ))
plus = time.mktime(time.strptime(
"4 3 2 1970",
"%d %H %M %Y" ))
T = time.localtime(orig+plus)
set orig to date "Jan 31, 2005 17:59"
set plus to 4 * days + 3 * hours + 2 * minutes
set T to orig + plus
time.strftime("%A", T) weekday of T
time.strftime("%d", T) day of T
time.strftime("%B", T) month of T
time.strftime("%m", T) month of T as integer
time.strftime("%Y", T) year of T
time.strftime("%X", T) time string of T
time.strftime("%x", T) date string of T
fmt = "%H*3600 + %M*60 + %S"
eval(time.strftime(fmt, T))
time of T -- Seconds since midnight
Other
try:
# do something
except:
# do something
try
-- do something
on error
-- do something
end try
try:
# do something
except error, errmsg:
# do something
try
-- do something
on error errMsg number errNum
-- do something
end try
os.system("ls /etc/ | head -n 1") do shell script "ls /etc/ | head -n 1"
global VAR global VAR
eval("4 + 4") run script "4 + 4"
chr(64) ASCII character 64
ord("@") ASCII number "@"
time.sleep(10) delay 10
random.randint(5, 10) random number from 5 to 11
foo, bar = 1, 2 set {foo, bar} to {1, 2}
D = {"foo":1, "bar":2 }
var1, var2 = D["foo"], D["bar"]
set {var1, var2} to {foo, bar} of {foo:1, bar:2}
[ 0, 1, { "foo":"bar" }][2]["foo"][0] character 1 of foo of item 3 of {0, 1, {foo:"bar"}}
import foo
foo.do_something()
set foo to load script "foo.scpt"
tell foo to do_something()
"a" == "A" # returns False "a" = "A" -- returns true
considering case
"a" = "A" -- returns false
end considering
"1 2 3 4" == "1234" # returns False "1 2 3 4" = "1234" -- returns false
ignoring white space
"1 2 3 4" = "1234" -- returns true
end ignoring
sys.exit() tell me to quit

Handy functions

The AppleScript language is very limited on data handling. The programmer must build his own tools (functions) to have Python-like functionality to manage strings and lists.

countSubstring()

-- Counts how many times a string appears in a text
-- Note: Its splits the text by the substring and count the items
--
on countSubstring(theText, theSubstring)
 set AppleScript's text item delimiters to theSubstring
 set counter to (count of every text item of theText) - 1
 set AppleScript's text item delimiters to ""
 return counter
end countSubstring

lstripString()

-- Trims the provided string from the text's beginning
--
on lstripString(theText, trimString)
 set x to count trimString
 try
 repeat while theText begins with the trimString
 set theText to characters (x + 1) thru -1 of theText as text
 end repeat
 on error
 return ""
 end try
 return theText
end lstripString

rstripString()

-- Trims the provided string from the text's ending
--
on rstripString(theText, trimString)
 set x to count trimString
 try
 repeat while theText ends with the trimString
 set theText to characters 1 thru -(x + 1) of theText as text
 end repeat
 on error
 return ""
 end try
 return theText
end rstripString

stripString()

-- Trims the provided string from the text's boundaries
-- Note: Requires the lstripString and rstripString functions
--
on stripString(theText, trimString)
 set theText to lstripString(theText, trimString)
 set theText to rstripString(theText, trimString)
 return theText
end stripString

lowerString() / upperString() / capitalizeString()

-- Translate characters of a text
-- Note: Pass the From and To tables as strings (same lenght!)
--
on translateChars(theText, fromChars, toChars)
 set the newText to ""
 if (count fromChars) is not equal to (count toChars) then
 error "translateChars: From/To strings have different lenght"
 end if
 repeat with char in theText
 set newChar to char
 set x to offset of char in the fromChars
 if x is not 0 then set newChar to character x of the toChars
 set newText to newText & newChar
 end repeat
 return the newText
end translateChars
-- Convert a text case to lower characters
-- Note: Requires the translateChars function
--
on lowerString(theText)
 set upper to "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
 set lower to "abcdefghijklmnopqrstuvwxyz"
 return translateChars(theText, upper, lower)
end lowerString
-- Convert a text case to upper characters
-- Note: Requires the translateChars function
--
on upperString(theText)
 set lower to "abcdefghijklmnopqrstuvwxyz"
 set upper to "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
 return translateChars(theText, lower, upper)
end upperString
-- Capitalize a text, returning only the first letter uppercased
-- Note: Requires translateChars, lowerString and upperString
--
on capitalizeString(theText)
 set firstChar to upperString(first character of theText)
 set otherChars to lowerString(characters 2 thru -1 of theText)
 return firstChar & otherChars
end capitalizeString

replaceString()

-- Replace all occurences of one string for another in a text
-- The trick here is to change the internal delimiter,
-- spliting and joining the text
--
on replaceString(theText, oldString, newString)
 set AppleScript's text item delimiters to oldString
 set tempList to every text item of theText
 set AppleScript's text item delimiters to newString
 set theText to the tempList as string
 set AppleScript's text item delimiters to ""
 return theText
end replaceString

getListItemIndex()

-- Returns the integer index of a list item (zero if not found)
--
on getListItemIndex(theList, theItem)
 repeat with i from 1 to count of theList
 if item i of theList is theItem then return i
 end repeat
 return 0
end getListItemIndex

countListItem()

-- Returns the total count of a specific item in a list
--
on countListItem(theList, theItem)
 set counter to 0
 repeat with i from 1 to count of theList
 if item i of theList is equal to theItem then
 set counter to counter + 1
 end if
 end repeat
 return counter
end countListItem

Thank You Very Much!

This document was reviewed and got valuable contributions from:

  • Alfredo Kojima
  • André Ruiz
  • Osvaldo Santana Neto
  • Rudá Moura
  • Ryan Wilcox
  • Sérgio Bruder
— EOF —
Please enable JavaScript to view the comments powered by Disqus.
GitHub

AltStyle によって変換されたページ (->オリジナル) /