Tuesday, January 29, 2013

How to batch convert using sips on Mac

Have you ever had a bunch of images that you needed to quickly convert into a different format? I have! The Mac has some great tools like GraphicConverter and PhotoShop, but it also has a flexible command line image converter that comes with every Mac: sips, the scriptable image processing system.

I had a problem where I had a lot of web images in different formats (png, jpg, gif) and wanted to run a scenario of how much space I'd be able to save by converting all the images to low-quality jpeg. The following bash script expects a wildcard argument (e.g., *.jpg, *.gif, *.*) then creates a directory 'low' and makes low-quality versions of all the images in the argument in the low directory.
if ! [-d 'low']       # if low doesn't exist, make it
  then mkdir 'low';
for i in $FILES; 
  # find the extension on files that may have multiple periods or
  # extensions like 'jpeg'
  NF=$(echo $i | awk -F "." '{print NF}');  
  NF=$(($NF - 1));
  EXT=$(echo $i | awk -F "." '{print $NF}');
# convert image using 50% quality and save in 'low' folder as jpg
  sips -s format jpeg -s formatOptions 50% $i --out "low/"$(echo $i | sed "s/"$EXT"/jpg/g")

Monday, January 28, 2013

Lost Cat, Found

A lost kitty cat found its way to my mom's house about December 18 while I happened to be visiting for the holidays. We snapped a few photos of her and uploaded them to Craigslist. Mom also drafted up a few hand-written bills and pasted them up around her neighborhood.

We kept an eye on PetFinder for a few days but we didn't see a match. My mom swore she'd get rid of the cat, but she kept putting off bringing it to the pound.

Fast forward to today. I was checking my junk folder and saw a message about the cat sent two weeks ago! Oh no, it had slipped past. I called Mom to let her know, but by amazing coincidence the kitty's owners had managed to find out Mom had the cat, so they picked her up over the weekend. The cat and her family were reunited!

Heartwarming. :)

Friday, January 25, 2013

The challenge of legacy website maintenance

Following departure of one of our web developers, I'm starting to get a closer look at how our weekly content is updated at work. Some of the data is tightly bound to the presentation layer, which requires manual updates. Although some content is built using a house templating system, there are still parts that are too complicated for the house template solution to handle.

The problem has the following aspects:

  • Information for the website updates is not centralized.
  • Metadata for updates is not centralized or even captured in a system. Some of it is in the head of developers like me. 
  • The house template solution is deeply embedded in the workflow, but is not very flexible. 
  • The content updating is spread amongst multiple web editors and coordination is handled via scheduled workflow rather than any scripted process. 
  • A variety of clever workarounds can obfuscate the purpose of some weekly update items. 
Along with this list of challenges is the knowledge that our vendor is working on a next-generation CMS. The question becomes, should we try to fix our legacy workflows? The answer is, maybe

Changing processes is costly. First, there's the cost of researching the existing process and its solution. Second, there's the development cost. Finally, there's the cost of implementing the new process. 

For me, with my hacker mentality, it's easy to see opportunities for improvement without taking into consideration the implementation cost. But what good does it do to make something "work better" if the people who are meant to benefit from the improvement have to climb a learning curve to take advantage of it? In the long run the tradeoff is probably worth it, assuming the long run is sufficiently placed in the future. 

The real challenge is not the existing workflow hiccups, it's knowing whether they're worth the expense to fix. The "can we do it" part is already obvious. Yes, we can streamline processes. Can we do it in a way that serves all the stakeholders? That's the real heart of the question. 

Sometimes it is best to leave a legacy process alone until the foundation can be replaced. As a developer my duty is to notice these opportunities and bring them to the attention of my team, and then to be sensitive and responsive to the other stakeholders. Just because something is possible doesn't make it right to do. 

Wednesday, January 23, 2013

Excel 2010 loading Excel 2011 file

Damn you, Microsoft. It's 2013, why does your software still operate as though it was built to cause frustration?

I've been keeping extensive project notes in Excel 2011. Normally I use Google Docs, but I wanted to take advantage of the more sophisticated row and column formatting options in Excel 2011.

This week I shared the location of the file with a co-worker. He opened the file, found the whole project blank (like, without even a single worksheet) and just figured I hadn't added any notes yet.

Today we learned that Excel 2010 didn't like opening the file that was made in Excel 2011. I tried saving it in old-fashioned .xls format. He still couldn't open the file. I was able to open it in Excel 2007, but even after saving it as both .xlsx and .xls, it still didn't open.

A little while after I'd given up trying he noticed that Excel 2010 had tried to pop up a window with the spreadsheet off screen. Like, as though he were running a virtual desktop, even though he isn't. And apparently Excel 2010 doesn't have a 'cascade window' menu item any more, so he had to do all sorts of contortions to get the spreadsheet to appear.

Microsoft, man, I sure hate you sometimes.

Sunday, January 20, 2013

Learning underscore.js

Playing with underscore.js this weekend to take a crack at solving one of the workflow challenges with the site Science home page.

There are two news feeds on the home page, Daily News and Careers. The Careers feed is pre-generated on the back end using a house templating application. The Daily News feed is constructed from a Google Feed API and the markup is generated in JavaScript.

This is suboptimal for a couple of reasons. First, any changes to the markup must be made in both the JavaScript on the client side and in the house templates on the back end. To fix this we can use underscore.js's template function to define the template once. Deploying changes to the template could be done much more quickly, although it's questionable how helpful this would be since the templates aren't changed often.

Second, since the Careers data is not separated from its presentation, making reuse challenging. Considering the number of places on the site we use headline-type data, it would be nice if we could define a "headline" data format, and then any Science publication (Careers, News, the three journals) would only need to be responsible for publishing a data feed (in JSON) while underscore.js handles the templates.

In fact, with a little bit of meta-data in the feed, we could use underscore.js's collection functions to highlight headlines depending on what type of article a visitor was reading.

Adopting underscore.js to solve this particular problem may not gain us benefits to offset the development costs, but it's interesting to play with new ideas. It's hard to tell when one of them might take off.

Tuesday, January 15, 2013

Pirate Cinema

I bought the Humble Bundle e-book bundle a couple of months ago, and was finally getting around to Cory Doctorow's Pirate Cinema. Doctorow's book was one of the reasons I was excited about the bundle. Down and Out in the Magic Kingdom was amazingly compelling, and it even inspired a real-life effort to develop a reputation-based currency called whuffie. Cory Doctorow is a visionary.

It pains me to say this, but I could not make it through Pirate Cinema. I'm a reader. Heck, I just finished Middlemarch, weighing in at over 300,000 words. Doctorow is a political activist who focusses on Internet-related policies like loosening copyright law, privacy, copyright, and so on. And he walks the walk: many of his works can be downloaded for free from his website.

Despite being sympathetic to many of his political positions, having them shoved into my face every page for the first four chapters was exhausting. His characters hardly spoke about anything but Doctorow's politics. They weren't really even having dialogue, they just lectured at each other. Once I finished the third chapter and dug partly into the fourth I started to skip around to see if there was just a rough rhetorical patch I needed to get through, but it looked like screed straight to the end. Such a bummer!

His older work is must-read speculative fiction. Skip this though.

Saturday, January 12, 2013

Backbone.js on Code School

Thanks to Code School, I was able to work through some Backbone.js tutorials.

Code School is setup to present a topic in multiple sections. Each section begins with a 15 minute video which covers a few key points about the topic. For example, in the Backbone.js tutorial one section explained how the event model worked, using a todo list as an example application. After the video, there is a small interactive quiz that reinforces the key points from the section. The quiz part includes a code editor, and when you submit your answer it actually runs the code and judges you on the results, not on the code itself.

Although the two courses I ran through today had high production value, the site itself is narrowly focussed on Ruby and JavaScript. I won't be buying a Code School membership after this trial, but I'll keep my eye on it and if the number of tutorials that interest me continues to expand, I may revisit that decision.

Ora et Labora

I picked up a new board game tonight at Labyrinth in DC called Ora et Labora. It's from the same designer who made Agricola and La Havre. The mechanics look more streamlined than either of those games. Like Agricola, it looks like its major gameplay mechanic is resource management making this an economics-oriented game.

48 hours of Code School for free

Code School is running a promotion this weekend offering any of their classes free for 48 hours. I'm reviewing my jQuery and learning some Backbone.

jQuery has been in my toolset for years, but it's helpful to spend some time skimming through materials looking for gaps in my knowledge. Most of my experience with jQuery is in the 1.5 and earlier era, so maybe there will be some bits that are new to me.