Can Galactic Empires Exist Without Faster-Than-Light Travel?

Tag clouds and the value of visuals

I’ve been looking into the various infographics sites trying to do something different (more on that in a future post) and I came across something interesting.  I was trying out some tag cloud services and realized just how powerful a visual look at your data can be.

On my first shot, making a Wordle, I found that the most prominent word in my RSS feed wasn’t anything near what I would have guessed:

“False”?  Really?  That’s the most prominent word?  Well, of course that’s not the image that I want to convey when someone comes to my blog.  For reference, here’s the Wordle without it:

I’m not really sure why “false” was that prominent; I’m sure it’d in the code examples, but … really? Ironically, with it gone, the most prominent term is “value” — which I’m happy to have associated with my blog.  

A second service, WordItOut, doesn’t have the original “false” quite so prominent:

So I might have missed it if I’d started out there.

But there’s yet another wrinkle to this.  A third service, Tagxedo, lets you arrange your tag clouds into an image.  I couldn’t find the Stormtrooper they were showing on the home page, but here’s the cloud based on Abe Lincoln:

Now, I’m pretty sure this is based on the actual text on my home page rather than my feed, which is why my name is disturbingly prominent rather than the code terms in the other two clouds. (NoTooMi also shows up nicely.)  But my point here is that adding this extra layer of visual is neat but distracts from the idea of making sense of the data.  (Of course, if all you’re interested in is a cool looking visual, go for it. Tagxedo is a great service.)

The moral here?  Visuals can be extremely useful, but be careful not to get TOO creative, or they’ll lose their power to show you the data you’ve actually come for.

Why it’s a bad idea to build your business on someone else’s platform (hear that, Facebook?)

I’ll be honest, it’s only lately I’ve been sucked into using Facebook much, and that’s just because my wife pulled me into it.  I really do try to avoid anything that soaks up my time without providing me much in return.  And to me, Facebook is just a morass of pictures of dogs needing rescuing and cute kitties.

My wife, however, is addicted to George Takei’s Facebook feed.  And it’s funny.  Very funny.  Thing is, she and I are both subscribed, but only she gets the posts.  I, apparently, am not in lucky 15%.  What lucky 15% is that, you ask?  Well, in case you missed it, only a very small percentage of your Facebook friends get your posts — unless you’re willing to pony up $200 per post to reach all of them.  Dangerous Minds has a great explanation of the problem, in which they ask if Facebook is THE BIGGEST ‘BAIT N’ SWITCH’ IN HISTORY?

The root of it is this: when you build your business on Facebook — or any platform you don’t control — you are putting your time and money into building a presence for someone else, and then you’re at their mercy.  That’s the root of it.  Now, if you’re Pepsi, you don’t care.  $200 to promote a post is a rounding error.  But for small businesses… it’s different.

I’m not saying don’t make use of Facebook, or Twitter, or any other platform at your disposal.  I’m just saying that you need to control your own destiny, your own presence, your own content.  Sometimes that means you forego what seems like “easy” traffic for something more lasting.  Sometimes that means you take a chance and use someone else’s platform, knowing that you might have to pay to get that traffic back — or give it up altogether.

How to use quotes in XPath/XSLT statements

OK, this one frustrated me for a while, so once I got it licked I wanted to pass it on to anyone else in this situation.

The problem is this:  You cannot embed a quotation mark or an apostrophe in a quoted string.   In other words, this may be the function that you want:

substring-after(., 'XE "')

But when you actually include it in the stylesheet, it becomes…

<xsl:value-of select="substring-after(., 'XE "')" />

and that’s wrong.

You can’t escape it, either.  This is still wrong:

<xsl:value-of select="substring-after(., 'XE "')" />

The answer to this problem is to create a global variable, which doesn’t require the quote to be in quotation marks:

<xsl:stylesheet version="1.0"
            xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:variable name="quot">"</xsl:variable>
...

You can then use the concat() function to include it in your string, as in:

<xsl:value-of select="substring-after(., concat('XE ', $quot))" />

This way you can use the quotation mark anywhere in your stylesheet.  You can use the same method for any other character that’s difficult to add to expressions, such as the aposotrophe.

Why events should happen on the server, not in the client

I have a guilty pleasure.  I like to game occasionally.  Not a lot, mind you; I have zero spare time.  But occasionally, when I’m waiting for something, I might pick up my iPad and play a game.  In particular, I like this game where you … well, I won’t tell you exactly what the game is, for reasons that will become apparent in a moment.

In this game, there are contests.  They run them every couple of weeks, and if you reach a certain goal a certain number of times, you get a reward, which you can use in the game.  The reward is normally something you’d either earn slowly (like one per day) or pay hard cash for.

Unfortunately, every time they run a contest and I participate, when it’s over, I have a problem.  That problem is a bug that causes the app to crash right after displaying a message that I’ve been awarded the Bronze level of prizes in the event.  First, this annoyed me; no matter what I did, I couldn’t get it to stop crashing, even following instructions from support.  But now, I welcome it.  Why?

Because every single time the app displays the message, I get my prize.

So far, since yesterday, I’ve been able to take my balance from 231 … let’s call them “stars”, to 1513 at last count.

Now, the company hasn’t lost any money off of me; I wouldn’t have spent hard cash for those stars, regardless of how useful they are in the game.  But I’m sure there are people who would have, and in any case, it illustrates a point:

Never, ever, give the client app control it doesn’t need.

The are only two reasons a client should control an aspect of your application, and even then, the client is subordinate to the server:

  1. If it’s directly related to the user experience.  For example, it’s perfectly reasonable to send raw data to the browser and have Javascript and CSS take care of displaying it in a way that’s customized for the user, rather than having the server customize a page for every single user.  (I’m not saying it’s always best to do that, I’m just saying it’s reasonable.)  In this case, the data is coming from the server, and, if you’re smart, so is the information needed to perform that customization.
  2. In a game or other environment in which either presentation or data needs to react immediately to user action, you would obviously want user interactions to happen in the client for performance reasons; keeping things local prevents lag due to network latency.  But information about what happened needs to get back to the server for persistence, so if the client crashes information isn’t lost.

Why is this so important?  It’s important for two reasons.

First, like it or not, you have no control over what happens in the client.  Sure, you can hope that only authorized users get their hands on it, and it’s not tampered with, and nobody creates a pirated version that does Bad Things.  But if you’re successful, those things are going to happen.  You need to deal with it, and you deal with it by safeguarding your users’ data and experience in the environment you do control: the server.  Take my “stars” example; the company could easily prevent this problem by simply awarding the stars once, on the server, at the end of the game.  Then it doesn’t matter how many times the app displays the message and then crashes, because I am not getting 32 new stars every single time.  Even if they only wanted to add the stars once I’d logged in — for example, if it affected the leaderboard — they should still be checking —  on the server — whether they’d been added yet.

The second reason is more philosophical than technical.  It’s because as we move deeper into cloud, users are increasingly expecting a “access anywhere” mentality.  If an app crashes, or a device crashes, or they just move to something new, they want their experience to come with them.  And they can only do that if it’s on the server.

What do you think?  Do you prefer to have the client manage things?  Or are there other reasons one way or the other that I haven’t thought about?

Update:  Shortly after this post, the game was finally updated so that it doesn’t crash.  Hopefully they fixed the architecture, too!  (Of course, now I have to earn my stars the hard way. :) )

How to use a Java ResourceBundle and properties file

OK, one thing that I put off learning for a long time is how to use Java ResourceBundles.  It just seemed like something complicated that I didn’t really need to do.  After all, I could always just drop information into a standard file and read that, right?  But this approach has its limitations, as pointed out handily in this article:

  • Setting absolute file locations is a Bad Thing, so knowing where to find them can be tricky.
  • Setting relative file locations can be a problem too, as they are relative to the JVM, which can be anywhere.
  • Easily providing localization — different text for different languages — can be an issue, as you have to programmatically determine which file to use.

No, instead, you’re better off using a ResourceBundle backed by a properties file and fortunately it’s actually pretty easy, as you’ll see in this post, where I use it to configure NoTooMi‘s logging properties.  Using a properties file gives you a couple of advantages:

  • As long as the properties file is somewhere in your classpath, you don’t have to worry about exactly where it is.
  • ResourceBundles can automatically pick the right file, depending on what locale you’re looking for.

So today I’ve decided that I’ve gotten sufficiently complicated in my logging scheme on NoTooMi that it’s time for me to break this out into a ResourceBundle.

Continue reading How to use a Java ResourceBundle and properties file →

How to patch open source software

As a developer, I very often use open source software, but sometimes you run into a situation where the binary (that’s that package you just download and stick in your classpath) needs to be patched. Maybe it’s an obscure bug fix that you need that hasn’t been released yet, or maybe it’s a feature that’s still on the trunk (that’s the “main” stream of code).

Very often when you read about these situations, the author will just say, “apply this patch” or “this has been fixed in this Jira”, which is great, but unless you work with a team or on a major project, it’s not something you do every day.

Fortunately, it’s not as difficult as it would seem to be. Here’s how you do it.

In my case, I ran into a situation where I needed to apply a patch to Apache Nutch to add parameter support to its integration with Solr. Now, this is a Java project, but I suspect the steps are pretty much the same (at least concept-wise) for other languages. So here are the steps:

1) Download the source. Typically, you do this in the same location where you got the binaries. In my case, I downloaded http://www.alliedquotes.com/mirrors/apache/nutch/apache-nutch-1.4-src.zip.

2) Uncompress the source to an accessible directory.

3) Download the relevant patch. In this case, it was https://issues.apache.org/jira/secure/attachment/12505095/NUTCH-1213.diff. You’ll want it in the same directory as the src directory.

4) If you’re on Windows, you’re going to need Cygwin; make sure that you install “patch”, which is under “Utils”.

5) Run the patch like so:

patch < NUTCH-1213.diff

In my case, the utility wasn't finding the source files, so I had to type the location, but that's (usually) not a huge deal.

6) At this point you have patched the source, but you still need to create the binaries you'll need to actually run the software. This may sound intimidating, but it's not. Most open source software includes some easy way to build it because the developers need to do that all the time. In the case of Java projects it's usually in the form of a configuration file for Maven (pom.xml) or Ant (build.xml).

Nutch has both, and I already have Ant on my system, so the next step is to make sure that JAVA_HOME and ANT_HOME are set to their proper locations (use your actual locations):

export JAVA_HOME=/cygdrive/c/sw/jdk1.7.0_02
export ANT_HOME=/cygdrive/c/sw/apache-ant-1.8.3

Then you can run the build:

cd <directory with build.xml<
$ANT_HOME/bin/ant

You should see a long string of messages that tell you what happened. Hopefully at the end you'll see this message:

BUILD SUCCESSFUL

If not, take a look at the actual errors and see what's going on; usually it's something simple, like a missing system variable.

If everything works, you're done. You've now got a patched version of that open source software that's so useful!

Not so tough, right?

Now, I confess, I've only done this for Java projects. Anybody have a good resource for other languages?

It’s good to be old

There was a time — not that long ago, really — when I was the up-and-coming kid in the office. I was young, I was hip, I was on top of everything new. I was the one who, in 1995, went to the people running the interactive agency where I was working and said, “You know, guys, we really should start looking into building websites for people. It’s going to be big.”

Now I find myself working with people who weren’t even born yet when Star Wars was in the theaters. Heck, they were in diapers when the web was born.

At the ripe old age of 43, I find myself feeling like the grand old man.

Not that I’m not still on top of things, always chasing the latest technology wave. (OK, I admit it, I hate texting. But that’s just because … well, honestly, I’m not sure why it is. Maybe I’m just anti-social.)

So this past week, as I was trying to solve a problem in creating eBooks that would be “cross-platform” — meaning a single ePub (the format used by iBooks) that would convert to a reasonable .mobi, if you’re interested — I was glad to find that for once, my age was an asset.

Turns out that the Mobi format, which is used for Kindles, is based on old — and I mean O-L-D — HTML standards. Like, pre-HTML4 stuff. No CSS (for the most part), no nothing. So while Apple is pushing ePub3, which lets you create all kinds of interactive eBooks, I was dealing with a format that doesn’t even let you use an image as a link.

At this point, I have seen many younger programmers give up. “Sorry, can’t do it,” they say. It’s a phrase I hear all the time, and it’s starting to get on my nerves. Sure, there are times when you can’t do something. Some things are just impossible. (Like getting around full justification in iBooks, if the user has it turned on. Grrrrrrr.)

But I don’t, in general, give up that easy. So here is a technique for displaying a text link in a Mobi file, while the ePub displays an image link.

The situation is this: I’m programmatically generating an ePub, which is then run through Calibre to create a Mobi file. The relevant HTML looks like this:

<a class="indexTopLink" href="index.html#top">
   <img class="indexTop" width="100" height="0" src="backToTop.png"/>
</a>
<a class="textTopLink" href="index.html#top">top</a>

So you’ve got two links in the HTML. The height attribute on the arrow image — yes, Virginia, we used to actually set height and width on the actual image, back when dinosaurs roamed the earth — tells the Mobi reader to render the image with a height of 0, so it’s invisible, but the width attribute makes it wide enough to provide some spacing. Then the Mobi reader displays the text link, which actually works.

Now we deal with the ePub. We add some CSS:

.indexTop {
   height: 24px;
   width: 100px;
}
.textTopLink { 
   position: relative; 
   left: -9990px;
}

The first rule tells the ePub reader to over-ride the image attributes and display the image at the correct size, so it’s visible. The second tells it to move the text link over to the left so that it’s not.

Because the Mobi reader ignores the class attribute these rules are ignored, so we have an image link for ePub, and a text link for the Mobi.

And all with techniques that fell out of favor long before a lot of today’s web programmers even started college.

It’s good to be the grand old man.

“Success” is a relative term

OK, so right about this time last year, I was announcing the Year of Living Socially, in which I was planning to:

#1 — Really focus on just three content areas I think are important. They are cloud computing and social media, which I believe will be big in 2012, and intelligent search, which I’ve been championing in one way or another for a long, long time. (I’ll get more into exactly how I define each of those topics in future posts.)

#2 — Finally build a project I’ve been kicking around for years: an information aggregator that tames the information overload that gets worse every year. (The project has yet to be named, but I’ll talk about what it actually does — and solicit feedback and priorities — in a future post.) I will build this out in public, with deadlines anybody can see. I probably won’t open-source the code itself, but I will likely write articles and tutorials about the different technologies I use as I go along.

#3 — Implement best practices for using social media, including regular postings to Twitter and either LinkedIn, Facebook, or both. (I’ll do the analysis in a future post.)

I did set some ground rules, though. In doing that, I would also have to keep these things in mind:

First and foremost, client work can’t suffer; I’m a professional and if you’re paying me to do something, you take top priority. (Plus I have a family and they can’t suffer, so this will also have to be ‘the year of living within time management best practices’.)

Second, I’ll be using open-source and publicly available software, preferably cloud-based, unless there’s a good reason not to for a particular task, which will be a discussion in and of itself.

Third, all decisions, from what software development methodology to what search solution to use, will be made “in public”, so to speak, with analysis and conclusions out there for everyone to see.

So the big question is, how did I do?

Well, from the outside, it looks very much like the answer is “not too well”, but it’s actually not as bad as it looks.

#1 — I was right about cloud, social, and search being on the rise, and I did actually focus on those three technologies in 2011. About 2/3 of the work I did involved either search or social media, and just about everything was cloud-related in one way or another (if you’re really generous in your definition of “cloud”.) Unfortunately, most of that was client work that I couldn’t post here.

#2 — I did actually build the project, NoTooMi, and quietly launch a first beta of it. Unfortunately, it was built on a product that has subsequently changed its architecture (I knew that was a risk when I built it) so I need to rebuild a few parts of it before I can relauch. Also, while it does integrate Twitter, I haven’t yet finished Facebook integration, so it looks a little anemic right now. I’m hoping to have a public version up in the next couple of weeks.

#3 — OK, I’ll admit it, I definitely fell down on the job here as far as regular postings to Twitter and Facebook. (I did get my LinkedIn profile filled out enough that I picked up a client from it, however.)It’s my personality; I don’t like to talk unless I have something to say, and I get a little weirded out about whether people want to actually hear it. I promise to try and loosen up in 2012.

And what about the requirements? How did I do there?

#1 — Well, giving client work the priority definitely worked. There was not one instance all year in which client work suffered because of this project. If anything, it’s the opposite; I’ve been so busy with client work this year that I haven’t had time to do what I wanted on NoTooMi. (I even got my corporate website redesigned and rewritten.)

And on the personal front, I’m happy to say that while my last remaining children at home drive me nuts at times (which is, I suppose, their job) my marriage is better than ever, and after all these years, that’s saying something, especially since we spent November opening Sarah’s gift shop to try and beat the Christmas rush. (Website to come shortly; we barely got the doors open in time.) (Oh, and for you Doctor Who fanfic fans, Sarah and I were finally were able to launch a huge and ambitious story I’ve wanted to write for a couple of years. When it’s done we’re going to tackle a novel. Seriously.)

#2 — NoTooMi is based on Apache Solr, so in that respect, yes, it’s based on open source. And the service that I built it on was indeed cloud-based. And it worked pretty well, too, but now it looks like I’m going to bring it back to pure Solr. But I admit that thanks to client requirements on something else I have been seduced by IntelliJ and have been using it instead of Eclipse as my programming environment. Sorry guys.

and #3 … Well, yeah, not so much. Sorry about that. See #1.

So where do we go from here? Well, first, I’m going to try and get out of my head a little bit and not worry so much about whether I’m boring people. If I find it interesting, I’ll post it. I would like to think that there are people out there who are interested by the same things I’m interested by.

And I am also going to try and obsess a little less about what I do write. One piece of advice I got from a book about blogging was to do short tips — and to get good at just banging them out. I learn about a ton of different little things over the course of a year. Not every post about them has to be a tutorial. Just a quick tip will do. Really. (Nick takes a deep breath….)

As far as technologies, “cloud” is still a great buzzword, but I think that it’s pretty well established at this point, as least as far as I’m concerned, so I’m going to start focusing on mobile, which is where I think the bulk of innovation will be in the next couple of years. I spent the last couple of weeks really delving into eBooks as a prelude to app-building (tips, I know, tips!), so I’m hoping to have something to show for mobile in 2012.

OK, so those are my goals for 2012. As for measurable objectives:

  1. Post something, somewhere, once a week.
  2. Get my new office at the store furnished and ready for receiving clients. (It’s cool, there’s a separate room and a back entrance just for me.)
  3. Launch a private beta of NoTooMi before March 1.
  4. Go to public beta before July 1.
  5. Finish the Doctor Who arc we’ve been working on, and start planning a novel.
  6. Publish at least one “pay to download this” item, whether it’s a mobile app or a Kindle Single, even if it’s also available here for free.

So that’s where I am today. How did you do on your goals for 2011, and what are you planning for 2012?

A Case Study In Social Media Customer Service Done Right: Enterprise Rent-A-Car

It’s nice to hear about social media case studies, but maybe it’s even better to experience one first-hand.

This past Saturday, on the freeway about an hour from home, my transmission quit. After coasting about an mile and a half to an exit, I called AAA, and they made arrangements for me to speak with Enterprise Rent-A-Car about getting transportation while my van was in the shop. Because it was Saturday afternoon, none of the local offices were open, so I wound up making a reservation at the airport.

Two problems there. The first was immediately obvious: Enterprise’s slogan, “We’ll pick you up”, only applies to the local offices, so I had to get someone to drive me to the airport. OK, I understood that. But when I got to the airport, I discovered the second problem: the airport locations won’t rent on a debit card unless you’re flying in and out. The agent was apologetic, but there was nothing he could do.

Fortunately my sister-in-law had waited with us. ‘No problem,’ I thought. ‘We’ll go home, and I’ll call my local office and get a ride on Monday morning.’ I’ve rented with Enterprise dozens of times; because I’m the only driver in the house, “We’ll pick you up” makes them my rental agency of choice.

Unfortunately, when I went to book that car for this morning, I was horrified to see that there were no cars available at the two closest offices. The nearest office with a car was 25 minutes away, and I was definitely out of their territorial range.

And that’s where social media comes in. Frustrated, I tweeted:

The one downside of living in the country is that when your car breaks down, you pray Enterprise has a car. Naturally, they don’t. Sigh.

A few minutes later, I found the following @mention from @enterprisecares:

@NickChase We are listening. Is there anything we can help with? If yes, please tweet/follow us & I’ll DM our contact information (amanda)

Surprised, I did as they asked, and, receiving the customer care email address, explained the situation to them. By this time I’d made a reservation at the distant location (hoping I could find someone to take me down there), and Amanda told me she’d email over there and make sure they did everything they could to help.

And that’s exactly what they did.  This morning I called, and true to her word, Amanda (or someone) had let the office know my situation. “Mister Chase, we are going to do whatever it takes to get you going here today,” Paula said. “What time do you have to have the car by?”

Turns out that cars were in short supply because of hail damage here in North and South Carolina, and that was why my local office was sold out. But not only did they find me a car, they did indeed come and pick me up, and I was able to do everything I needed to do today.

And I’m very glad, because I like Enterprise, and didn’t like feeling badly about using them.

So the moral of the story is this: Pay attention to what’s being said about you. Because Enterprise Rent-A-Car spent the resources to monitor social media, they were able to turn a frustrated (and vocal) customer from a source of negative sentiment to a champion of their brand.

What are you doing to monitor what’s being said about you?