I’ve written about Workflow recently, and how I’ve really enjoyed playing with it and seeing what I could accomplish. In speaking about it on a recent episode of ATP, I was asked what problems I was really solving with Workflow. I had answers, but admittedly, none of them were very good.

Now, I have a better example.

As with all egomaniacs podcasters, I check our download statistics regularly. We use a Perl script that John wrote that will aggregate our numbers and emit JSON. We can then put this URL into Panic’s wonderful app, Status Board, and see a graph of our recent numbers

It should go without saying all these numbers are made up for the purposes of this post.

Fake Download Graph

That’s all visual, and is great to show trends. Sometimes, I like to know actual numbers. Last night, it occurred to me I could parse the JSON that we use for that graph using Workflow, and have it perform the calculations for me. I wanted to calculate the lifetime average, as well as the average for the last 10 episodes.

The JSON that generates that graph, and that I used for Workflow, looks approximately like the following:

{
  "graph" : {
    "refreshEveryNSeconds" : 900,
    "title" : "ATP",
    "datasequences" : [
     {
       "datapoints" : [
         {
           "value" : "123456",
           "title" : "88"
         },
         {
           "value" : "126543",
           "title" : "89"
         }
       ]
     }
   ]
  }
}

You can get more information about the JSON schema on Panic’s site.

The workflow I wrote, without the requisite JSON URL, is here, but I’d like to replicate it below as best I can:

  1. Start with the URL of John’s script
  2. Translate the contents of that URL into a Workflow dictionary
  3. Get the value for the key graph
  4. Get the value for the key title
  5. Get the value for the key datasequences
  6. Get the value for the key datapoints
  7. Set that item (the array of datapoints) as the variable Episodes
  8. Count the number of items in that array
  9. Set that count to the variable Count
  10. Start with the number 0
  11. Set that number to the variable Sum
  12. Start by getting the variable Episodes
  13. Repeat with each episode:
    1. Get the value for the key value
    2. Perform an addition with the variable Sum
    3. Store the sum in the variable Sum
  14. Start by getting the variable Sum
  15. Perform a division with the variable Count
  16. Format that number to have only one decimal place
  17. Set that average to the variable Lifetime
  18. Start with the number 0
  19. Set that number to the variable Sum
  20. Start by getting the variable Episodes
  21. Repeat 10 times:
    1. Get the variable Count
    2. Perform a subtraction with the index of this loop
    3. Perform a subtraction with the number 1
    4. Set this to the variable Item Number
    5. Get the variable Episodes
    6. Get the item at index Item Number from the list
    7. Get the value for the key value
    8. Perform an addition with the variable Sum
    9. Store the sum in the variable Sum
  22. Get the variable Sum
  23. Perform a division with the number 10
  24. Format the number to only have one decimal place
  25. Set that average to the variable Last Ten
  26. Start with the text: Average Downloads\nLast 10: {Last Ten}\nLifetime: {Lifetime}
  27. Store that text in the variable Message
  28. Show an alert with the body Message

That is, admittedly, quite a few steps. The rough equivalent of the above, as written in Javascript, is below. The Javascript is quite a bit easier for me to understand — and write — than what I’ve done in Workflow.

Nevertheless, like I said in my previous post about Workflow, part of the appeal to me is making something complex work with relatively rudimentary tools. That’s exactly what I’ve done above.

In combination with Status Board, I can quickly and easily get either qualitative or quantitative data. Status Board provides me with a visual representation, while Workflow gives me quantitative information.

I am still really impressed with the power of Workflow, even if it comes at the price of being clunkier to work with than a true programming environment.