a sql quiz + is a lower hourly rate cheaper?

Suppose you have a task to write some JDBC code and you need to do so in the cheapest way possible.  Having your people grow should not be considered here, just the rate.

Person A

Charges 3X per hour and can write working code on the first shot, test it and complete it within an hour

Person B

Charges X per hour, but needs to multiple cycles to fix once the code is typed.  (This includes the time to identify what the problem is for each, build cycles and fix time.) For the SQL quiz , see how many errors you can find in the following code. I’ll post the answers as a comment. See if you can spot any I didn’t insert on purpose.

PreparedStatement stmt = null;
ResultSet rs = null;
try {
  String sql = "select count(*) from table" + "where column = ?";
  stmt = conn.prepareStatement(sql);
  stmt.setString(1, "test");
  rs = stmt.executeQuery();
  System.out.println(rs.getInt(1));
  sql = "select count(*) from table2" + "where column = ?";
  stmt = conn.prepareStatement(sql2);
  stmt.setString(1, "test");
  rs = stmt.executeQuery();
  System.out.println(rs.getInt(1));
} finally {
  stmt.close();
  rs.close();
}

Which is better

In today’s economy, driving down costs is a hot topic.  One phrase service providers consider is “how can we lower the rate.”  This is the wrong question.  The question should be how to lower costs overall.  Person A is going to be cheaper overall even though the hourly rate is three times as high.  We’ve all heard the comment that a good developer is many times more productive than an average one.

Granted, my example is extreme.  It shows the difference between an experienced person and an someone new to JDBC.  The point is to use the extreme to emphasize that it’s not all about the hourly rate.  In the real world, training the entry level person has value too of course.

Another view

This reminds me of the methodologies that ask you to estimate how many hours/days/weeks a task will take without saying who will do the work.  Well, if I do it, the work will take a week.  If an entry level person is doing it, it may take four.  If someone experienced is doing it who doesn’t know the system, it may take two.  How do we balance the differences in people when estimating?

Google Releases GWT Designer

Last week, Google released the GWT 2.2 update. While this was a relatively minor update, at least compared to previous version updates, there was one new feature mentioned in the release notes that was much needed: GWT Designer.

UiBinder’s Missing Cousin

The GWT 2.0 version saw the release of the UiBinder framework, a technique for creating GWT components in HTML, analogous to building applications in MXML over ActionScript in Flash/Flex. For example, the following UiBinder snippet creates a GWT panel and list box in an HTML-based template:

<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'    xmlns:g='urn:import:com.google.gwt.user.client.ui'>
       <g:HTMLPanel>
              Hello, <g:ListBox ui:field='listBox' visibleItemCount='1'/>.
       </g:HTMLPanel>
</ui:UiBinder>

What was severely lacking in the GWT 2.0, though, was the ability to edit this layout using a visual tool. There was really no compelling reason to switch to UiBinder, since it required learning a new syntax with limited benefits over writing it directly in Java.

Enter GWT Designer, now included in the Eclipse GWT 2.2 plugin, which allows you to create UiBinder components directly using a visual editor! Below is a sample screen-shot from a UiBinder class created in GWT Designer:

GWT Designer

But wait, there’s more!

GWT Designer is actually part of the WindowBuilder Pro family of graphical editors that includes SWT Designer and Swing Designer. Google offers the option of downloading the full stand-alone application, which includes support for 3rd party GWT add-ons such as GWT-Ext, GXT and SmartGWT.

With the GWT 2.2 release, Google also added support for HTML5, although it is marked as experimental/beta for the time being. To some surprise, they also deprecated support for Java 1.5 so if you have not upgraded to Java 1.6 yet, you will now get warnings in your application. Overall, the GWT 2.2 release helps to round out the GWT feature set leading to more powerful and easier to use tools.

I'm Speaking at TheServerSide Java Symposium Reminder: Jeanne and I are both presenting at TheServerSide Java Symposium next month. My lecture is entitled “GWT Roundup: An Overview of Google’s Web Toolkit and Hybrid Integration” and Jeanne’s presentation is called “Throw Away All The Rules. Now What Process Do You Follow?“. The conference is being held in Las Vegas and it’s not too late to register to attend!

3 plus/3 minus in WPILibj robotics library

WPILibJ is a library used for FIRST robotics code when programming in Java.  Helping the Stuypulse team gave me the opportunity to look at some of the code.  In honor of ship date this year, I decided to blog some thoughts on the library.  You can see the JavaDoc to follow along.

Good design point #1
The class names have strong ties to the “business.”  Class names like Joystick , DigitalInput and SpeedController are very clear and provide a mapping to a good concept.  They also encourage good object oriented code.

Good design point #2
For the most part the documentation is good and the classes logical.  Many classes have useful comments and tips on usage.

Good design point #3
There are patches released through the competition season.  Care is taken for changes to be backward compatible and not break existing code.  Much appreciated on a six week project.

Surprise #1
In the Image class, care appears to be taken for immutability (classes that cannot be changed.)  It has a package private constructor.  Only getters are provided.  The object can be written to a file, but you need to create a new object if you want to read from a file.  Then comes the surprise.  The image instance field is public!  And that public field is of type Pointer – a wrapper to native memory.   Eek.  Memory leak if you mess with it without being careful?

Surprise #2
The CANJaguar class had the biggest surprise.   When you instantiate an object, you pass the control mode.  Straightforward.  I expect the code to behave differently when different modes are passed.  Then you try to call setVoltageRampRate.  The JavaDoc clearly states what it does:

Set the maximum voltage change rate. When in percent voltage output mode, the rate at which the voltage changes can be limited to reduce current spikes. Set this to 0.0 to disable rate limiting.

Then there is what it does in reality.  If the control mode is kPercentVBus or kVoltage, a formula is used to set the ramp rate.  For the other three modes, the method does nothing.  That’s right nothing.  It doesn’t throw an exception or set it to zero or log an error or anything.  Which means you don’t realize it doesn’t do anything without reading the code.

Surprise #3
I can’t really call this a surprise as I’ve known about it since beta testing.  But I was surprised then.  Last year, there was a Dashboard class for custom output.  It was hard to use and they added a SmartDashboard class this year.  And logically, they added an interface IDashboard for the commonalities between them.  There aren’t many commonalities, but that’s not what I find surprising about the interface.

To use the old Dashboard, you write:


Dashboard d = DriverStation.getInstance().getDashboardPackerLow()
d.addXXX();

To use the new SimpleDashboard, you write:
SmartDashboard.init();
SmartDashboard.logXXX();

That’s right – the new one uses statics. This is where the interface becomes confusing. If we are calling static methods, an interface doesn’t make sense.

The worst bug
The worst bug we encountered wasn’t actually in the WPILib code.  It was in the underlying National Instruments code and affected all three wrapper APIs (Java, C++ and LabView.)  The Encoder class works in an illogical manner. In particular, it only lets you use the first, third, fifth and eighth encoders to get the rate of movement.  (No, that isn’t a typo.  It is a seemingly random collection of orders rather than every other.)  That’s if you are in one mode.  In another mode, the working encoders change.  We have to fool the low level code by creating dummy ones to the “real” encoders get the proper constructor call ordering.  While this was documented on chief delphi (the unofficial FIRST robotics forums), we wasted a lot of time assuming we were doing something wrong.

Conclusion
The longer text for the surprises doesn’t mean that the code is bad.  Just that there is more to write about unexpected things. All in all, I appreciate all the API gives us. Congratulations to team #694 (Stuypulse) on a great build season and for completing an awesome robot on time!