An average morning
I was looking at some numbers on a web page. A wide variety of fairly large numbers. The web page didn’t provide any kind of average for the numbers, and I was curious. Curious, of course, meant writing a script to solve the problem. Yes, I could have copied the numbers out, punched them into a calculator one by one, or opened up Numbers and pasted them into cells… bah. I wanted to be able to copy text with all kinds of other junk in it and just get the average of all the values in contained quickly and easily (even if that meant wasting twice as much time up front).
I wrote the basic script in Ruby to run as a TextMate command:
input = STDIN.read
# Quick function to add commas to long values
def add_commas( number )
number.to_s.reverse.scan(/(?:\d*\.)?\d{1,3}-?/).join(',').reverse
end
# Scan for numbers in the text
arr = input.scan(/\.?\d[\d,]+(?:\.\d+)?/).map{|line|
# remove non-decimal characters from results and convert to float
line.gsub(/[^\d\.]/,'').to_f
}.sort
print input # output the original text
# if there were 2 or more numbers found, output the additional information
print "\n - Average of #{arr.size} numbers ranging from #{arr[0]} to #{arr[arr.size-1]}: " + add_commas(arr.inject(0.0) { |sum,el| sum + el } / arr.size ) unless arr.empty? || arr.size == 1
The script is simple enough that it should be easily adjustable to perform any kind of basic math on the array of numbers found in the text. The numbers don’t have to be in any order in the input; they can be listed vertically or horizontally or can just be scattered throughout text or messy table code. The regular expression should find them.
The TextMate command suited my needs just fine, but then I started thinking about sharing it. What format would make the most sense? A System Service that accepted text and appended a line with the average? A TextExpander snippet that ran on the clipboard? A LaunchBar action that worked with Instant Send or Copy/Paste? I couldn’t decide, and since the script was the only time-consuming part, I went ahead and made all of the above.
The TextExpander snippet is now in the Tools group of my TextExpander projects. If you’re subscribed to that group via URL, your group already updated with the “Average numbers in clipboard” snippet. Otherwise, go ahead and download it or set up a new subscription.
The other two versions (and the script) are in the download below, and I threw in the original TextMate command, too. The LaunchBar action is actually a Script Bundle with the Ruby script packaged inside. If you’ve ever wondered how to reference a self-contained script in AppleScript, it’s a decent example. It installs to ~/Library/Application Support/LaunchBar/Actions
. The System Service is a standard Automator action using the script above, and installs to ~/Library/Services
.
Want to see a video of it? Really? Why? I’m in that semi-asleep state where I thought it would be easier to show what it does than explain it. Since I doubt anyone else really has a need for this script, the video is a tribute to my ability to waste time in the early morning.
Average Numbers in Selection v1
Download Average Numbers in Selection v1
A Ruby script, an OS X System Service and a LaunchBar action for finding any numbers in a block of text and returning the average. Also see the Tools group of the TextExpander Tools for a snippet version.
Published 09/02/11.
Updated 09/02/11. Changelog