Interview Questions

Once when I was interviewed I was asked to write a recursive routine that walked a directory tree and pulled out all the Excel spreadsheets. It was actually a bit of a trick question - the recursive part is fairly straightforward but Excel has a number of file extensions (xls, xlw, xlsx, etc) that you have to figure out and then there are the intangibles.

What happens when the file is locked? You

did handle this in a transaction

didn't you? Meh.

So like a good geek you're probably rolling some code in your head right now with DirectoryInfo.GetDirectories() and so on. Go ahead... write it up in your favorite language...

or you can just Google it and cheat.

Either way - it's a routine we've all needed to write at one point or another in our careers. And every time we do - "well sheee-it I can't believe I don't have that code handy. How did I do that again?"

I dare suggest that the recursive directory-walk is probably the most rewritten routine in all of CS. Or maybe it's just me and my horrible memory. And maybe I should get to the point of this post.

N+1 Words

I like using pictures

in the videos I do as well as the slides I use for presentations. A lot of people ask me where I come up with them... and that will be my secret :). I can tell you that they end up all over my hard drive. Sometimes I pop them next to the presentation file - other times they're buried with the video clip.

Wherever they are - I don't want to lose them and I was about to lay into a dandy shell script when

I remembered one of my favorite books. It's a book dedicated to showing you how you can write some nifty Ruby scripts rather than arduous shell scripts. And that's what I needed. So I dropped into my Tekpub directory (where all my videos/presentations and so on are) and I kicked up Vim:mvim rakefile.rb

I'm on a Mac, but if you have Ruby installed on your PC - hey just kick up a text file with the same name.

Next I need to write some code to traverse a directory and pull out files according to a particular pattern. For me - it's just the image files - jpegs, gifs, pngs. Simple enough - so being relatively new to Ruby I decided to place a bet: how many lines would it take me to do this?

My initial thought was "5-8 and that's if I'm lucky." The thought then occurred to me that some smartass probably could write this in one line.

I was right.files = Dir.glob("*/.{jpg,png,jpeg,gif}")

The only thing is that this isn't some "smart-ass-y" code, this is the way you do it with Ruby. It looks like Regex but it's not - it's a glob (Unix-y wildcard-y stuff) that's meant to be used specifically for file searches. We're handing that glob to Ruby's Directory class and telling it to traverse all subdirectories (the "**") with the additional provision that we only want files with jpg, png, and gif extensions.

When I ran this in my Rake task and watched all my files - buried in well over 120 subdirectories - splash on my console screen I bust out laughing. That was just too easy.

So here's my script for pushing all the image files in my Tekpub directory to a new directory (called ImageLibrary):

require 'rubygems' require 'fileutils'

desc "Image mover" task :move do Dir.glob("*/.{jpg,png,jpeg,gif}") do |file|, "/Users/rob/ImageLibrary/") puts "# { file } moved!" end end

As with most things Ruby - you can pull out the files into an array - or pass in a block like I did here. I'm using FileUtils (another Ruby class) to pick up the files and move them all.

512 files - scraped and moved in 8 seconds. That's pretty exciting.

Extra Credit

I decided I also needed to get rid of those annoying "camrec" files that Camtasia uses to hold the raw uncompressed videos from your screen captures (I used to use Camtasia to do the screencasts). Simple enough:

require 'rubygems' require 'fileutils'

desc "Image mover" task :move do Dir.glob("*/.{camrec}") do |file| File.delete(file) puts "# { file } deleted!" end end

It's worth noting that if you have a one-liner fetish you could do the above in a single line (minus the Rake decorations). I don't mind the extra readability here.

Finally - the last thing I wanted to do was to delete out all the screen-capture raw files taken by IShowU (the Mac capturing tool I use). These are uncompressed Quicktime files and build up quickly. When IShowU captures a file - it calls it "captureX" where X is some number.

This requires a bit of tweaking to the script:

desc "Scratch deleter" task :delete_scratches do Dir.glob("**/capture[0-9][0-9].mov") do |file| File.delete(file) puts "# { file } deleted" end end

That looks like Regex - but again it's not. It's a glob format which differs slightly (and I think has been around longer). It's simple to test this with irb - make sure your pattern works before blowing files up on your machine.