In Commentary on
17 March 2010 tagged HTML, JavaScript, Web development with no comments
Dojo developer Alex Russell continues to look out for view source:
If HTML is just another bytecode container and rendering runtime, we’ll have lost part of what made the web special, and I’m afraid HTML will lose to other formats by willingly giving up its differentiators and playing on their turf. Who knows, it might turn out well, but it’s not a vision of the web that holds my interest.
I linked to his previous warning on this subject back in January.
In Commentary on
17 March 2010 tagged health care, politics with no comments
The big question I’ve had this week with regard to health care reform is, “Why is it taking so long to vote?” The path forward is that the House will pass the Senate bill, and then the House and Senate will pass a small bill that amends the Senate bill by way of reconciliation, so that it can be passed with a simple majority in the Senate. My impression was that the holdup was due to the Democrats having insufficient votes to pass both bills, but that’s actually not the case.
Jonathan Cohn explains:
But, as Lori Montomery explains today in the Washington Post, the devil really is in the details. And the devil, in this case, has a name: the Congressional Budget Office (CBO). In order to satisfy the requirements for the budget reconciliation process, through which Congress will consider the amendments, CBO must certify that the changes will reduce the deficit both in the decade following enactment and the decade following that.
By “reduce the deficit,” I mean reduce the deficit relative to whatever the Senate health care reform bill would do on its own. And that is no small thing. The Senate bill, as written, was projected to save quite a bit of money. As such, the amendments must result in reform, as a whole, saving even more money than the CBO projected originally.
So basically legislators are tinkering with the reconciliation bill and then letting the CBO score it until they get a bill that accomplishes what’s necessary and is eligible for reconciliation. Once we have a bill that’s been scored acceptably by the CBO, we’ll see if the Democrats have enough votes to send it to Obama for his signature.
In Commentary on
16 March 2010 tagged Ruby, sports with no comments
As you may or may not know, the NCAA Tournament starts this weekend, and people around you are probably doing their best to predict the winners of all of the games in the tournament. Most years I join one (or more) pools, but I don’t watch enough college basketball to make educated guesses about who will win each game. This year, I wrote a program to do it for me.
I started with Ken Pomeroy’s team ratings. Here’s his explanation for how the system works:
My ratings produce a number that actually means something–it’s the chance of beating an average D-I team on a neutral floor. For instance, Michigan’s current rating of .8006 means that the Wolverines would win 8 out of 10 games against the average D-I team. Every March, I borrow Bill James’ log5 formula to take these ratings and compute probabilities for each team to win its conference tournament.
I’m not sure how the log5 formula got its name, but it’s fairly intuitive. Think of a coin with one side labeled “win” and the other side labeled “loss.” The chance of the coin landing on “win” is the team’s rating. Log5 is derived from the probability that a team’s coin will land on win and its opponent’s coin will land on loss. (If they land on the same side, you re-flip.)
My script takes the source from Pomeroy’s ratings page and reads in all of the teams and their ratings, and then picks a random winner for each game based on the log5 comparison of Pomeroy’s ratings. Here’s the output for a hypothetical Final Four the script generated:
FINAL FOUR
Maryland has a 45% chance of beating Syracuse
Winner: Syracuse
Kentucky has a 56% chance of beating Baylor
Winner: Kentucky
NATIONAL CHAMPION
Syracuse has a 51% chance of beating Kentucky
Winner: Kentucky
The script has no way of knowing which teams will upset higher seeded opponents, other than by giving teams that Pomeroy’s system likes a better chance of winning, but it should pick roughly the right number of upsets based on the odds.
I’ve uploaded the script to a repository named bracketologist on GitHub if you want to play with it. It’s written in Ruby.
In Commentary on
15 March 2010 tagged Android, Google, iPhone with 5 comments
Here’s Tim Bray (now officially part of the loyal opposition) on the iPhone:
The iPhone vision of the mobile Internet’s future omits controversy, sex, and freedom, but includes strict limits on who can know what and who can say what. It’s a sterile Disney-fied walled garden surrounded by sharp-toothed lawyers. The people who create the apps serve at the landlord’s pleasure and fear his anger.
I hate it.
I hate it even though the iPhone hardware and software are great, because freedom’s not just another word for anything, nor is it an optional ingredient.
I love using the iPhone, but to a growing degree I’m starting to hate the fact that I love using the iPhone.
In Commentary on
14 March 2010 tagged Java, open source with no comments
Dave Johnson on why he’s migrating his build scripts for Roller from Ant to Maven:
I was a Maven hater and resisted it for a long time but over the years Maven has gotten much better, it’s well supported in IDEs and as far as I can tell, Maven has replaced Ant as the de facto build system for Java projects. If you want new developers be able to easily build, debug and run your code via command or their favorite IDE then Maven is the way to go, and that’s especially true for open source projects like Roller.
This is my impression as well. I started to create a new, open source Java application the other day, and it occurred to me that for the build script, I should use Maven because it seems like that’s the way everybody is handling dependency management these days. Dave’s post is one more indication that I was probably right about that.
In Commentary on
13 March 2010 tagged TV with 5 comments
The good news is that Tivo is releasing a new DVR. It looks awesome. I have been a Tivo customer for many years, in fact, Tivo is perhaps my favorite product of all time.

The bad news is that Tivo is a perpetual money loser, and lost 730,000 subscribers last year.
For many years I’ve had a DVR provided by Time-Warner hooked up to the second TV. It is the worst product I use on a regular basis. The interface is terrible, the remote is ungainly, and the performance of the device is pathetic. But what we’ve learned over time is that people are not willing to pay the premium for the Tivo experience — the cable company DVRs are good enough for most people. I doubt that many people even know that the Tivo is so much better.
One big problem Tivo faces is that it’s a lot easier for a cable company to ship a DVR that you just plug in and start using than it is for Tivo to do the same. In addition to the Tivo, we have two cable cards that enable it to tune in digital channels, and a tuning adapter that the Tivo needs to tune in SDV channels. Getting the CableCards to work was incredibly painful and required several visits from the cable guy and many phone calls with tech support, and the tuning adapter required for SDV crashes frequently and sometimes takes the Tivo down with it. The miserable piece of crap that is the cable company DVR just works.
I’ve always wished that a cable company would license Tivo’s software and use it in their own DVRs, but it has never happened. That’s a pity, because I continue to worry about Tivo’s viability as an independent concern.
In Commentary on
12 March 2010 tagged philosophy with 1 comment
Here’s Scott Berkun on The Cult of Busy:
The phrase “I don’t have time for” should never be said. We all get the same amount of time every day. If you can’t do something it’s not about the quantity of time. It’s really about how important the task is to you.
When I was in college around 20 years ago, I remember a friend telling me that he tried to read the Wall Street Journal every day. I told him I didn’t have time to read the newspaper, which was a ridiculous statement, because I always had plenty of time to play Tetris in the dorm or go out and eat cheap Tex-Mex. He told me that it wasn’t a question of time, but of priorities. I don’t know that I ever claimed not to do something because I didn’t have time again. This was one of the few really useful lessons that I really picked up early.
In Commentary on
10 March 2010 tagged politics, TV with 3 comments
Fred Clark argues that on health care reform, Democrats are playing Jeopardy while Republicans are playing Family Feud:
At the recent health care reform “summit,” Republican leaders made it clear that they’re not interested in playing Jeopardy. That would be a losing proposition against President Ken Jennings. Obama was eager to show that he really does have the right answers — cost containment, near-universal coverage, lower premiums, better quality care, deficit reduction. All of that is well covered in the plan he’s pushing and any attempt to challenge him on the facts would be doomed.
So the GOP has decided to play a different game — to switch from Jeopardy to Family Feud. That way it’s not about the facts, or about what works, or about the actual effect of actual policies on actual people. In the subjective guessing-game of Family Feud, none of that matters. Family Feud is all about perceptions — about what those hundred people surveyed think or guess or dimly remember having heard something about.
This is perhaps my favorite blog post I’ve read this year and a gold medal winner in the Metaphor Olympics.
In Commentary on
10 March 2010 tagged cars, statistics with 3 comments
Robert Wright breaks down the numbers on Toyota’s safety record given all of the recent reports of uncontrolled acceleration:
My back-of-the-envelope calculations (explained in a footnote below) suggest that if you drive one of the Toyotas recalled for acceleration problems and don’t bother to comply with the recall, your chances of being involved in a fatal accident over the next two years because of the unfixed problem are a bit worse than one in a million — 2.8 in a million, to be more exact. Meanwhile, your chances of being killed in a car accident during the next two years just by virtue of being an American are one in 5,244.
This is the article I’ve been looking for since the mass hysteria about acceleration problems began. It strikes me as undoubtable that a Toyota purchased today is significantly safer than most of the cars I’ve driven over the course of my life. I used to own a 1977 Ford pickup truck that caught on fire under the hood more than once.
Update: It’s also worth mentioning that if the accelerator sticks on your cars, there are several ways to stop.
In Commentary on
9 March 2010 tagged JavaScript, jQuery, Web services with no comments
About a month ago I asked what people would use to build a new Web service from scratch, without providing any real details on what the application would do. People seemed to all agree that basing the service on JSON was the best way to go, and that’s the route I took, so I thought I’d write it up.
In this case, I have a PHP front end talking to a Java back end that uses Spring and Hibernate. The application in question is the administrative console for a test harness for a SOAP Web service. We use a third party SOAP service and needed the ability to provide responses that are guaranteed to always be the same for the purpose of creating tests. So my test harness stands in for the third party service, requiring only a URL change, and returns the data managed via the client application to which my question referred.
The application itself is very simple — it’s a single table with a lookup mechanism. The client enables users to find and edit individual records from the table. I needed four basic operations:
- Search for records
- Retrieve a single record
- Update a record
- Create a record
- Delete a record
The Server
This is a Java application that uses Spring and Spring MVC. I use Spring’s Web Services support for the SOAP stuff, but it wasn’t worth it to bother with that for the administrative client. So instead I mapped every URL ending in .json to a Spring DispatcherServlet. Like all sensible Java developers who’ve worked in Rails, I hate configuration in general and XML configuration files in particular. So I used Spring’s ControllerClassNameHandlerMapping, which extracts the path from the URL and maps it to a Spring controller.
So a path like /myapp/responses/search.json calls the search() method in the ResponsesController class. Simple.
I won’t go into the boring details of my implementation, other than to talk about how I’m passing the messages back and forth. The client uses standard form submission (name and value pairs) to submit the data, and expects to get JSON back. So in the case of search, I extract the field name and query value, go to the database and run a query to retrieve the records in question, and then package them up and encode them using JSON to be sent back to the client.
The JSON encoding is handled by Google’s GSON library, and it’s ridiculously simple. It accepts a plain Java object, and serializes it and all of its children using reflection. Any properties that are null are omitted. So for my application, I created a wrapper object that was well-suited to being encoded using GSON. It includes a hash for error messages, a property for a single response object, and a collection of response objects for search results.
Then I created a view for Spring called SimpleGsonView, which accepts a wrapper (or any object), encodes it using GSON, and then sends the results to the client. Here’s the whole thing:
@Override
protected void renderMergedOutputModel(Map aMap,
HttpServletRequest aRequest,
HttpServletResponse aResponse) throws Exception
{
Object wrapper = aMap.get("wrapper");
Gson gson = new Gson();
aResponse.setContentType("application/json");
ServletOutputStream out = aResponse.getOutputStream();
out.print(gson.toJson(wrapper).replaceAll("\\\\n", ""));
logger.debug(gson.toJson(wrapper));
out.flush();
}
One thing you may notice is that I do a search and replace on the JSON. It removes all occurrences of \n from the encoded data. That’s a hack to get around a client side bug that I got tired of trying to fix. I’ll talk about that later.
So for this application, to add new functionality, I just add a new method to my controller, process the input parameters and put the correct results in the wrapper, and then pass that to the view I created. Very simple. I added an autocomplete feature to the search page, and this is all I had to do to add support for it on the back end:
public ModelAndView complete(HttpServletRequest aRequest,
HttpServletResponse aResponse)
{
String searchField = aRequest.getParameter("field");
String searchQuery = aRequest.getParameter("query");
List<String> results = Collections.emptyList();
if (searchField.equals(FIRST_NAME))
{
results = getFirstNameCompletions(searchQuery);
}
else if (searchField.equals(LAST_NAME))
{
results = getLastNameCompletions(searchQuery);
}
else if (searchField.equals(KEY))
{
results = getKeyCompletions(searchQuery);
}
else if (searchField.equals(ZIP))
{
results = getZipCompletions(searchQuery);
}
return new ModelAndView(new SimpleGsonView(), "wrapper",
results);
}
The methods to retrieve the data are in another class, but I removed the reference to it for simplicity.
So that’s the server piece. I could have done more to make it RESTful but since the service is just for me, I went with the simplest possible approach.
The Client
For legacy reasons the client is a PHP application, and I decided to use jQuery and a little PHP to implement the client features. Here’s how each operation is implemented:
Search: The search feature is pure jQuery. The home page for the client has a search form on it with a pulldown of fields that can be searched and a text box for the search terms. I used the autocomplete feature from jQuery UI to make the search form a bit friendlier. I catch the submission of the search from (or the selection of an item in the list provided by autocomplete) and submit the results to the server using jQuery’s getJSON() method. Then I create a table on the page with the search results in it.
Retrieve a single record: This is the only place I used PHP to connect to the server. I decided that I wanted each item to have its own URL, and although I could have written the code to pull the key for the item in the URL, fetch it, and build the page in JavaScript, I opted to use PHP instead. To do so, I grabbed a copy of the Services_JSON library and included that in my app. PHP supports JSON natively starting with version 5.2, but my server is running PHP 5.1. I chose Services_JSON because it’s a single file. So when you go to the edit or show page, I use PHP to fetch the JSON for the key in the URL from the server and put it on the detail page or in the edit form. This is where the bug comes in. My service returns XML documents (encoded as a value in a JSON hash), and sometimes Services_JSON won’t decode the data properly. When I started stripping \n from the XML, it worked, so I went with it.
Create a record: This form uses jQuery’s post() method to submit the contents of the form to the server. If the request returns a successful result, it redirects the user to the detail page for the new item. If it doesn’t, it displays the errors included in the result.
Update a record: This form works just like the create form.
Delete a record: This is the simplest operation of all. It submits the key to be deleted, and the server simply returns true or false.
Upshot
This was just about the easiest implementation of an application and accompanying Web service I’ve ever done, in spite of the fact that I’m a pretty terrible JavaScript developer. The server side was much easier to implement than I’d anticipated, it took less code in Java than it would have in PHP, and not much more code than it would have taken in Ruby. This is the application that really convinced me that there’s essentially no development overhead involved with using AJAX rather than traditional server-side request processing when building Web applications, at least if you bring libraries like jQuery and GSON to the party to make things easier.