# Writing FizzBuzz like this makes me feel like a small child

For the sake of full disclosure, this was written with bananas, not apples. The doctor may not be kept away.

### For Copy&Pasting:

activate application "TextEdit"
tell application "System Events"
repeat until first window of application "TextEdit" exists
tell application "TextEdit" to make new document at the front
delay 1.0E-3
end repeat
repeat until process "TextEdit" is frontmost
set frontmost of process "TextEdit" to true
delay 1.0E-3
end repeat
set focused of first window of process "TextEdit" to true

repeat with i from 1 to 100
if i mod 15 is 0 then
keystroke "FizzBuzz"
keystroke return
else if i mod 3 is 0 then
keystroke "Fizz"
keystroke return
else if i mod 5 is 0 then
keystroke "Buzz"
keystroke return
else
keystroke i
keystroke return
end if
end repeat
end tell


I feel like I want to write functions... but I don't know what's available in AppleScript for modularizing code... err script... I'm just getting my toes wet here.

It may be fun watching it type out FizzBuzz, but interacting with the UI directly has its pitfalls. For example, if the user focuses a different application while your script is running, you will now be typing in the wrong place; and if you refocus the application, that could be annoying.

Fortunately, there is a better way. Rather than activating the application, waiting until a window appears, and making the window frontmost, you could just…

tell application "TextEdit" to set text of first document to "Hello, world!"


This is much less problematic. The only issue is if TextEdit is already open, in which case it will overwrite the existing document. In that case, you could use

tell application "TextEdit" to set text of (make new document) to "Hello, world!"


Either way, you’re not interacting directly with the UI any more, which eliminates a lot of potential problems.

The actual meat of the FizzBuzz implementation (barring the use of keystroke) looks fine, although you might consider something like keystroke "FizzBuzz" & return rather than keystroke "FizzBuzz" and separately keystroke return.

The main problem that I see is the lack of separation of concerns. The FizzBuzz code has no business being run in the System Events context, and it ought to reside in its own handler.

to fizzbuzz from low to high
repeat with i from low to high
if i mod 15 is 0 then
output("FizzBuzz")
else if i mod 3 is 0 then
output("Fizz")
else if i mod 5 is 0 then
output("Buzz")
else
output(i)
end if
end repeat
end fizzbuzz


I've factored out the keystroke calls as well, since they looked repetitive. Since you opted to use the simulated keystroke option to output the text instead of just telling application "TextEdit" to set the text of the first document to the fizzBuzzOutput, you really ought to go all the way and make it type out slowly, like in the movies.

on output(something)
tell application "System Events"
repeat with c in (something as string)
keystroke c
delay 0.05
end repeat
keystroke return
end tell
end output


With those two handlers in place, you would call

tell application "System Events"
repeat until first window of application "TextEdit" exists
tell application "TextEdit" to make new document at the front
delay 1.0E-3
end repeat
repeat until process "TextEdit" is frontmost
set frontmost of process "TextEdit" to true
delay 1.0E-3
end repeat
set focused of first window of process "TextEdit" to true
end tell
fizzbuzz from 1 to 100


Note that there doesn't seem to be any need to tell application "TextEdit" to activate.