How I Learned to Program

HTML/CSS

I wish I had learned HTML and CSS before learning anything else. You can reach the largest group of people and quickly and visually express yourself the easiest by building a web site. And a lot of the projects you work on with other languages will eventually lead you to building a web site to showcase those projects. It’s available on every operating system as well, so you can reach everybody.

Regular Expressions

Regular expressions have let me do massive renaming projects. I’ve experimented with a few different file naming schemes over the last year, and using Regexes made it easy to match patterns and change file names to new patterns in a few seconds. Also, using grep and Ruby’s Regex support, it’s improved my searching on the hard drive and finding patterns in my programs. If you’re a programmer, you have to learn Regex if you want to be as effective as you possibly can be.

JavaScript

JavaScript is another language that’s ubiquitous. All web browsers support it and it’s a great fall-back. It’s probably because I learned Ruby before JavaScript, but I picked up the syntax quickly, and after having studied Ruby, the oddities of JavaScript drove me a little nuts. Having to declare variables with var, the verbose functions and having to end everything with semicolons was insane to me. Thankfully, [CoffeeScript][http://coffeescript.org] exists. CoffeeScript started of as a Ruby gem for cleanly and succinctly writing JavaScript and because of that, the syntax for CoffeeScript is a lot like Ruby. In some ways, CoffeeScript’s syntax is even cleaner than Ruby’s is.

You can declare constructor variables like this:

Class Person

constructor: (@name,@age)

Now, you’ve created a Person class and you don’t have to even do the Ruby thing of @name = name or @age = age. I’m kind of in love with CoffeeScript, and since JavaScript is new to me, I’m really excited about writing CoffeeScript that will turn into JavaScript and be used with HTML5 and CSS to build some great web sites in the future. I’ve already got some ideas.

Shell

The Unix shell was actually the second language I learned. I’m not even sure it’s a language. It’s a collection of awesome small programs that glue together in the most amazing ways though. It seems like every day, I find some Unix program I never knew about. The day I discovered at was great. I wrote up a bunch of timer scripts for myself that I now use on a daily basis. The shell is also the hardest language to wrap your head around. A lot of it was written a long time ago and the documentation is spotty at times. The “community” surrounding Unix and shell scripting isn’t as welcoming as say Ruby’s is. They’re not also eager to help and often the discussions they’re having are over a beginner’s head. It would behoove every Mac user who wants total control over OS X to learn to utilize Unix’s power.

Ruby

Ruby was the third language I learned and probably my favorite (although CoffeeScript is giving it a run for its money). It’s very powerful and yet flexible in its abilities and acceptable syntax. It’s easy to invoke system commands so you can leverage the power of Unix in your Ruby programs too. The Ruby community is a sprawling and friendly one.

AppleScript

And then there’s AppleScript. It was the first language I learned. While many dismiss it as not a real language and some say that its day in the sun has past, AppleScript was the most immediately useful language to me. I wanted to script OmniFocus and a few other OS X apps. The only way to do that was to learn AppleScript. I learned not only how to script through AppleScript but I also picked up the general theories driving computer programming. Maybe Ruby or Python would’ve been better to start out with, but I had a goal, scripting OmniFocus, and because of that goal, I probably was driven to stick with it.

I’ll admit it’s not a great general purpose programming language. It’s only useful on Macs, there’s no built-in Regex support, problems often arise when manipulating files, and you can’t do much with applications if they don’t support AppleScript in the first place.

The Future

I see myself using AppleScript when I need it, although Apple keeps breaking support in their own applications. OmniFocus 2.0 Pro will have AppleScript support so I’ll definitely still be writing scripts there. I use shell scripts whenever possible because they’re often the simplest and fastest solutions to basic scripting problems. I’m working towards eventually building a Rails app, so Ruby will a major part of my programming life. And CoffeeScript/JavaScript is mandatory if I’m going to build interactive web sites, so I’ll continue working in them as well.

I know I’m still a novice, but I’m getting better every day. I hope I just didn’t wait too long to start being a programmer to do something with it.

Baby’s First Programming Language

AESadFace

AppleScript gets a bad rap amongst programmers. It’s true, it’s not the most efficient language. It’s miserable at manipulating text. Regex support is non-existent, you have to roll your own sorts and reverses, and it’s got two different file types for compiled and compiled scripts. I’m now on the road to being a Rubyist, and I love Ruby, but AppleScript was the language that got me into programming. The best way to get good at programming is to have a task that you need programming to accomplish. Given a goal, you’ll learn how to make the tool work to perform the task you need it to do. For me, it was scripting OmniFocus, and in order to script OmniFocus, I needed to learn AppleScript. I went through countless online tutorials, bought Hamish Sanderson’s book on AppleScript and then read a lot of Googled and DuckDuckGo’d articles from MacScripter. And while I may have gone about learning AppleScript the hard way (not book first!) I have a pretty good understanding of AppleScript now, and I can often just look at an app’s dictionary and figure out how things should work. (When that fails, email the developer of the app you’re scripting. They often have great example scripts to share.)

I did quickly realize AppleScript’s two big flaws:

  1. It’s slow.
  2. It sucks for general purpose work.

AppleScript lacks the low-level speed of a Bash script and it also lacks the nifty iterators that Ruby has. Both writing and running AppleScripts can be slow. If you’re not doing a lot of data manipulation, it’s not that big of a deal, but it’s something to think about.

Probably the bigger problem though is that AppleScript isn’t great with non-application scripting tasks. In order to sort a list in AppleScript, you’ve gotta write your own handler. In Ruby:

a = [1,3,5,10,2,6]
a.sort => [1, 2, 3, 5, 6, 10]

or maybe…

string = "Brandon is a sexy man."
string.reverse=> ".nam yxes a si nodnarB"

I thought all these handy methods in Ruby were awesome, coming from just a background in AppleScript. Bash functions can be extremely hard to write and while I understood how to do them in AppleScript, it’s just a pain to implement.

So, while I do most of my programming in Ruby now (and occasionally Bash), I realize that AppleScript has its uses and that there are certain things (like scripting existing applications) that AppleScript excels at. Don’t be a hater of AppleScript. Best thing we can do is keep using it while at the same time making sure Apple knows people still care about it and want to see it improve.

Revisiting SmartPerspective

CheckMark

I’ve finally done it! (I think…)

I wrote up a little script called SmartPerspective for OmniFocus that smartly opens up different perspectives depending on whether certain conditions have been met. If tasks in my “Daily” project (all the junk that needs to be done every day), it opens the “Daily” perspective. If that’s clear, it looks for flagged tasks in every context and if any exist, it opens “Flagged”. After that, if any available tasks are left, it opens “Next Actions”. Lastly, if none of these conditions have been met, it opens up the “Someday” perspective and then you can look at stuff that isn’t blocked (by a start date) but isn’t in an active project.

The first version of the script stupidly closed all windows and then created a new document window. This was awkward and slower than just resetting the perspective name property for the document window. Now, if a front document window is visible, it resets the perspective name property. If one isn’t visible, then a new document window is created. This is faster and smarter. Also, this approach finally seems to make using Keyboard Maestro’s application trigger “when OmniFocus activates” open the right perspective every time.

Check out the SmartPerspective Gist.

The Today Card/Journal File

I saw Patrick Rhone’s post about his Today Card and it reminded me that I may have never talked about my journal and accompanying AppleScript to file it in OmniFocus at the end of the day.

I keep a basic plain text journal in Dropbox and I open it up quickly using Keyboard Maestro.

Screen Shot 2013 08 16 at 10 42 41 AM

wkg="$HOME/Dropbox/Documents/Markdown"
journal="$wkg/Journal.md"
touch $journal;open -a "BBEdit" $journal

At the end of the day (I run a Launch Agent every day at 8pm to file my journal) I run this AppleScript to import my journal into OmniFocus.

set the_file to "Users:your_username:Dropbox:Documents:Markdown:Journal.md" as alias

open for access the_file
try
   set the_text to read the_file as «class utf8»
on error
   return "Journal empty."
end try
close access the_file

tell application "OmniFocus"
   tell front document
    make new inbox task with properties {name:"Journal for " & ¬
    date string of (current date), note:the_text, flagged:true}
   end tell
end tell

set eof of the_file to 0

Set the_file to wherever you keep your journal file, and then if the file has text in it, it will create the task in OmniFocus. If there’s no text in the file, it will error out and do nothing. Run this with launchd every day and you have an automatic way to dump your daily journal into your inbox.[1]


  1. I use as «class utf8» in order to properly read and write Japanese characters.  ↩

SmartPerspective for OmniFocus

Screen Shot 2013 08 15 at 3 47 56 PM

I have an order to the tasks I work on. If something’s flagged in OmniFocus, it should be done first. If there aren’t any flagged tasks, then I move on to regular next actions. If there aren’t any next actions, (which is rare) then I move on to “someday” tasks. This AppleScript checks if tasks fit those conditions, and shows you the proper perspective.

Check out SmartPerspective here.

If you want to take it a step further, run SmartPerspective with Keyboard Maestro and have it run anytime OmniFocus activates. If there’s no front window, nothing will happen. If there isn’t a front window, then the proper perspective will open up.

Update: 2013-09-14

I’ve finally done it! (I think…)

I wrote up a little script called SmartPerspective for OmniFocus that smartly opens up different perspectives depending on whether certain conditions have been met. If tasks in my “Daily” project (all the junk that needs to be done every day), it opens the “Daily” perspective. If that’s clear, it looks for flagged tasks in every context and if any exist, it opens “Flagged”. After that, if any available tasks are left, it opens “Next Actions”. Lastly, if none of these conditions have been met, it opens up the “Someday” perspective and then you can look at stuff that isn’t blocked (by a start date) but isn’t in an active project.

The first version of the script stupidly closed all windows and then created a new document window. This was awkward and slower than just resetting the perspective name property for the document window. Now, if a front document window is visible, it resets the perspective name property. If one isn’t visible, then a new document window is created. This is faster and smarter. Also, this approach finally seems to make using Keyboard Maestro’s application trigger “when OmniFocus activates” open the right perspective every time.

Import Moves for iOS Logs to Day One

I’ve been using Moves for iOS to track my movement and I wanted to add the saved images the app can produce to Day One for OS X for journaling purposes.[1] So, if you create a Hazel rule to check if you have one of these images, you can then process them with this AppleScript. This script assumes you created the log the following day (or the moves) and then it uses that created day –1 to create a Day One entry for the day the moves actually happened.

set theFile to choose file

tell application "System Events"
    set old_date to creation date of (info for theFile)
    set new_date to old_date - days * 1
    set processed_date to ((month of new_date as number) & "/" & day of new_date & "/" & year of new_date as text) & " 11:59PM"
end tell


set photo_path to quoted form of POSIX path of theFile

set the_script to "echo \"Moves\"" & "| /usr/local/bin/dayone -d=\"" & processed_date & "\" -p=" & photo_path & " new"

do shell script the_script

When you’re running this as an embedded script in Hazel, just remove the line where you set theFile. Also, you’ll have to manually export the file from Moves. There’s no way to automate that unfortunately.


  1. You will need the Day One CLI.  ↩

«class UTF8» in AppleScript

I commented about this subject to a fellow nerd and he wanted to know why using «class UTF8» when accessing text in files with AppleScript was important. If you’re working with just English, you’ll never run into this problem, unless you use special characters like say, the ° used for degrees. I noticed that when I was running a script that was putting “Fever°” into a “links to post” file. It’s also important to use UTF8 when you think international alphabets will be used. I live in Japan and a lot of the text I use is Japanese and Japanese doesn’t play well with AppleScript’s plain old as text parameter. Like this:

Screen Shot 2013 03 15 at 11 00 08 PM

Here’s the same thing when done using as «class UTF8»:

Screen Shot 2013 03 15 at 11 01 05 PM

As you can see, the Japanese does’t display correctly unless you use UTF8. It’s a small pain to have to include and it would be great if AppleScript used it by default, but it’s not so bad and you could just make a TextExpander for it if you’re gonna need it a lot.

Note: You get « by typing ⌥ + \\. You get » by typing ⌥ + ⇧ + \\.

A Tickler Folder System for OS X

FolderAction

Updated on 2013-03-14

I made some bug fixes to the “check” apps and now they are pretty fail-proof. I also altered the “maker” app so that it creates a “Tickler” folder and then puts all the other folders inside that one. It looks cleaner and makes it easier for the “check” scripts to see if the “Tickler” folder already exists or not.


I created a nifty little AppleScript that will build a 43 Folders tickler folder system. When you launch the app, it asks you where you want to build the hierarchy, and then proceeds to build a folder for every month and a folder for every day inside each month’s folder. You can then combine that with two more scripts I wrote for checking today’s tickler and tomorrow’s tickler. I’d recommend setting these two up as launch agents with Lingon or Launch Control and have them auto-open at certain times of the day so that you can see if you have any files coming up that need to be acted on.

Download the set of files here.