Tuesday, December 27, 2011

Dynamically Adding a Style Sheet

I've been looking at some of Google's code for their Html5Slides project and like the way they dynamically link in a style sheet:
var el = document.createElement('link');
  el.rel = 'stylesheet';
  el.type = 'text/css';
  el.href = 'http://www.Example.com/...' + 'styles.css';
  document.body.appendChild(el);
I think they code it this way so people using their HTML5 slide template don't have to include a bunch of extra css files, just this one JavaScript file. If people get the file dynamically from Google all the time, Google can change the styles without breaking people's links. It's just one less dependency.

HTML5 is not XML, Time To Get Over It

I feel like Captain Malcom Reynolds who fought for the resistance against the Alliance, but failed and now lives in the shadows of the all powerful Alliance.

I love XML ( ... I know there's 12 step programs for people like me). XML makes it so easy parsing well-structured, schema-verified XML. I applauded the efforts of the W3C to make the next generation HTML to be XHTML2.0 with all the clean syntax.
But the fight for XML championed by W3C.org has failed. WhatWG (re: the Alliance) has won over W3C.org (re: the Browncoats ) and HTML5 is not XML. It's time to get over it.
What does this mean?
1. Well, we shouldn't close void tags (those who can't have nested elements) like "<br />, it should be "<br> (Although some people I respect disagree like Estelle Weyl.) Reading WhatWG docs, I sense they really don't want us to close void tags.

The w3's documentation in section 8.1.2 Elements defines void elements to be

area, base, br, col, command, embed, hr, img, 
input, keygen, link, meta, param, source, track, wbr

2. Attributes do not have to have a value
<input type='checkbox' checked='checked' ...>
This looked a little silly anyway. Now you can have an attribute without a value.
<input type='checkbox' checked ...>

3. Attributes values usually do not have to be quoted
<input type=checkbox ...>

4. We can't process html5 pages with an XML parser. Really in the old days, you could only parse your pages anyway, and any included files from Google or your ad server would probably break your XML anyway.

In the WhatWG FAQ they recommend not using an XML parser on pages, but using an HTML to XML parser.

We fought the Alliance and they won. Come on all you XML-loving Browncoats like me, it's time to move on.

Monday, December 26, 2011

jQuery just makes life too easy

One of my most popular pages on my web site is the history of the world timeline. I've always wanted to make if configurable so people could select just certain topics, like "military" or "science" and then concentrate on the topics they love. I did a little research and jQuery just makes this so easy.

This just takes three steps:
1. Include jQuery. We try to get it from Google, but if Google fails us, we get it from a local cache. I got this method from Paul Irish and his excellent HTML5 Boilerplate.
  <script src="//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
  <script>window.jQuery || document.write('<script src="js/libs/jquery-1.6.2.min.js"><\/script>')</script>

2. At the top of the page in a form we have this scrap of JavaScript which just toggles the visibility of rows which have the class of "military".
  <input type="checkbox" id="military" checked onclick="$('.military').toggle();">
  <label for="military">Military</label>

3. Lastly we add the class "military" to the row with that topic.
  <tr class="military"><td>70</td><td>After 6 month siege the Romans 
under the direction of Titus destroy Jerusalem killing one and a half million Jews.</td></tr>
Now the user can toggle on categories at will.
One of the nice things about this is that the work is all done on the client side, so the server is untaxed and the user has faster response time.

Wednesday, December 21, 2011

Agile Exchange at HomeAway

Agile Austin, a group dedicated to improving software development practices, sponsors an Agile Exchange where developers can visit other companies and hear about their Agile software practices.
Last month's Agile Exchange was with HomeAway and Jack Yang gave a dozen of us a tour of the HomeAway office and a description of their software development framework.
Below are my brief notes:

Initially software was developed in an ad hoc fashion with inconsistent results and a lot of disappointment. Jack ran one team on Agile principles and it was a success. The agile team members were dispersed to other groups to encourage them to adopt agile. It failed to catch on. Two more teams were trained and produced good results with Agile. Slowly other teams started to be interested, but it was a very organic growth. Now all twenty teams are doing Agile, with some of the more advanced doing Lean (Kanban). Software development is more predictable now.
Some teams do twice weekly deployments, others once a month.
Each team implements it's own version of Agile.
Cucumber is used for testing.
Each programmer is expected to do 5 hours of actual "hands on keyboard" programming a day although this varies by project; the rest is spent in meetings and other activities.
BigLever is used for variation management for over 20 brands.
The company, like everyone else, is moving to Git for version control.
Ruby on Rails will be used for the front end of the website, although the front end is expected to be language agnostic - whatever works best for their teams to get the job done well.
Java is used on the back end.
The business people at HomeAway really look at the Business Intelligence reports on how customers use their web sites.
Programmers use Macs.
Rally software is used to handle software issues.
Ruby scripts are created to access the Rally software from scripts.
Problems in Agile are the same - communication with people.

I would encourage developers to attend one of the Agile Exchange sessions; this last one was fun and informative.
Thanks to Brad Bellamy for organizing Agile Exchange.

Monday, November 28, 2011

Shopping for the End Times

I don't know who the Antichrist will be, but while shopping today at Goodwill, I learned his suit is ready.

Wednesday, November 23, 2011

Arduino Boot Camp III


We had our third Arduino Boot Camp on Saturday. I got my second project working - a green light that slowly increases and decreases in intensity. It's not much, but it's a start. And programmers love all our babies, no matter how small.
The source code:
const int redLedPort = 11;
const int greenLedPort = 10;
const int blueLedPort = 9;
int minBrightness = 0;
int maxBrightness = 255;
int deltaBrightness = 10;
int currentBrightness = 0;
int wait = 200; //milliseconds
unsigned long previousMilliseconds = 0;
unsigned long currentMilliseconds = 0;

void setup() {
pinMode(greenLedPort, OUTPUT);
pinMode(redLedPort, OUTPUT);
pinMode(blueLedPort, OUTPUT);
Serial.begin(9600);
Serial.println("Started");
previousMilliseconds = millis();
}
void setColor(int red, int green, int blue) {
Serial.print(red);
Serial.print(", ");
Serial.print(green);
Serial.print(", ");
Serial.println(blue);

analogWrite(redLedPort, red);
analogWrite(greenLedPort, green);
analogWrite(blueLedPort, blue);
}
void loop()
{
currentMilliseconds = millis();
if(currentMilliseconds > (previousMilliseconds + wait)) {
setColor(currentBrightness/2, currentBrightness, currentBrightness/2);
currentBrightness += deltaBrightness;
if(currentBrightness >= (maxBrightness - deltaBrightness) || currentBrightness <= (minBrightness)) { deltaBrightness *= -1; } previousMilliseconds = currentMilliseconds; } }

Monday, November 21, 2011

sp_executesql executes extremely slowly

On a legacy system, we had a query that in query analyzer is very fast, around a millisecond.
But in production it is slower than molasses in winter, up to three seconds.
The table being queried is simple and tall, around 25 million rows, with a clustered index on "bid":
CREATE TABLE [dbo].[BookHistory] (
[bid] [varchar] (64) COLLATE SQL_Latin1_General_CP1_CI_AS  NOT NULL,
[source] [varchar] (16) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[src] [varchar] (32) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,  
[bookCode] [varchar] (32) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[bookStatus] [varchar] (32) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[actionTime] [datetime] NOT NULL 
) ON [PRIMARY]
GO
CREATE CLUSTERED INDEX [BID_INDEX] ON [dbo].[BookHistory] 
(
 [bid] ASC
)
GO
The code is trying to retrieve all the records, typically a dozen, for a particular "bid" which should be faster than greased lightening.
exec sp_executesql N'SELECT bookCode as name,bookStatus,
DATEDIFF(DAY, actionTime, GETDATE()) as days  
FROM BookHistory with(nolock) 
WHERE bid = @bid AND source = @source AND src = @src'
,N'@source nvarchar(5),@bid nvarchar(10),@src nvarchar(4000)'

As the more astute of you can probably see now, the issue is with the data type of "bid". In the database it's a varchar(64), but in the trace it's a nvarchar(4000).
In the C# code the type of the parameter of "bid" was left to the default, which is "nvarchar", so...... SQL server was thinking, "I've got this nifty little index for 'bid', too bad I can't use it since the incoming query is an 'nvarchar', oh well, I guess I'll do a scan and convert all those 'bid' thingys to nvarchar on the fly." That's why the SQL statement was glacial.
For the interim, I patched the SQL statement with a cast, since that can be done without a full deployment, to be
exec sp_executesql N'SELECT bookCode as name,
bookStatus,DATEDIFF(DAY, actionTime, GETDATE()) as days  
FROM BookHistory with(nolock)
 WHERE bid = cast(@bid as varchar(64)) AND source = @source AND src = @src',
N'@source nvarchar(5),@bid nvarchar(10),@src nvarchar(4000)'
And the statement that used to take a few seconds now takes a few milliseconds. Mystery solved.
Postmortem: The clue was that the execution plan was doing a scan instead of using the real index.
Moral: Always set the type of the SQL parameter when using SqlCommand directly.
Moral2: Don't use SqlCommand directly. Use NHibernate or some other ORM so it can figure out all that stuff for you (Although in legacy systems you don't always have that luxury).

Thursday, November 17, 2011

Sql Server Management Studio intellisense not working

My intellisense in Sql Server Management Studio (SSMS) stopped working months ago and I finally decided to get it back.
Turns out that installing VS2010 R1 disables intellisense in SSMS. Who knew?
The solution? Install the cumulative update 7 for SqlServer2008.
1. Go to here and select "SQLServer2008R2_RTM_CU7_2507770_10_50_1777_x64" if you are running the 64-bit version (it's fifth from the bottom). Download it. Well, you can't just download it. Frustratingly, you have to enter your email address and then they email you the link.
<grip text="Why can't microsoft just have a menu option in SSMS under "Help" for "Update to latest patches" - even Quicken does that." />
2. Click on it to execute it and wait. Wait some more. Then realize, it's not going to run the installer it just unzips it to a directory.
3. Go to that directory and run "SQLServer2008R2-KB2507770-x64.exe" and that will install the update.
4. Although it doesn't encourage you to do it, reboot your system.
Worked for me.

Monday, November 14, 2011

Aparapi - Accessing the Power of the GPU from Java

Gary Frost from AMD presented the Aparapi library to the Java Users Group last Tuesday, Nov 8th, 2011. The Aparapi library makes it easy to write parallel java programs on the GPU using OpenCL. Gary has done some very impressive work with Aparapi. Before Aparapi programmers had to code large blocks of repetitive boilerplate code to get their algorithms to be executed on the GPU. Aparapi does that for us automatically.
If a GPU is not present Aparapi will use separate threads to enhance performance.
Gary showed an example of the nbody problem where two galaxies collide to demonstrate the power of the GPU.
Some of the performance hit of transferring data to and from the GPU and the CPU should vanish when AMD's fusion chip, which has the GPU and CPU on the same chip, becomes widely used.
Gary mentioned that we are entering a world of throwaway CPU power. He gave the example of parsing an XML file by dividing it into two parts. One thread would parse the first section, but the second part of the file might depend on the 67 states that the first part might be ending in. The solution is to have the CPU/GPU parse the second half in all 67 possibilities, so that when the first part is done the second part will already be finished.

Thursday, October 20, 2011

A Tale of Two Servers

"It was the best of times, it was the worst of times..."
Recently I came across two database servers, one with fast execution times, the other with slow execution times. Both machines were running windows server 2003, both had similar hardware, both had similar disk access speeds, yet one was over three times as fast as the other.
We puzzled over what could be the cause of the difference.
Can you take a guess?

Turns out the fast machine was running the 64-bit version of Windows 2003 and the slow one was running the 32-bit version. The fast 64-bit machine could load entire tables directly into its 8 Gig memory making it much faster. The other machine, when it wasn't hammered by disk thrashing, was probably wondering what it was doing with all that extra memory it couldn't access.

Friday, October 14, 2011

All My Apps Disappeared When Upgrading to iOS5

I upgraded my iPhone 3GS to iOS5. All my apps disappeared promptly. Here are instructions on restoring some of your apps:
In ITunes, on the left side select your iphone under "DEVICES" (I don't know why they shout at us in all caps).
Then on the horizontal menu bar across the top, select "Apps".
In the upper left corner of the window, select the "Sync Apps" checkbox.
In the app list below, check all the apps you want to restore.
Then in the bottom right select "Apply".

This reloaded all but my apps living in a subfolder. They are still missing. I'll update here if I can bring them back.

Tuesday, October 11, 2011

Pictures from HTML5tx October 8, 2011 Austin TX

This last Saturday the HTML5tx conference was in Austin.
The conference was very well organized with good food and good directions around the campus. An Open Space component was running simultaneously with the prepared sessions. To my surprise the Open Spaces were well attended.
To me the major theme of last week's Pablo's Fiesta and this week's HTML5 was "Regressive Enhancement"; with modernizr and pollyfills we can actually start using the features in HTML5 now, even in older browsers, yes Virginia, even in IE6.

Here's a few photos:
Opening session
http://www.fincher.org/images/2011-10-08-0835-IMG_4349.jpg
Mike Taylor from Opera gave a talk on the HTML5 DOM and the associated IDL. I was impressed with Opera Dragonfly, a debugging environment shipped inside Opera.
http://www.fincher.org/images/2011-10-08-0931-IMG_4350.jpg

http://www.fincher.org/images/2011-10-08-0933-IMG_4351.jpg
Alex Sexton gave an excellent overview of modernizr and yepnope and the whole polyfill game.
http://www.fincher.org/images/2011-10-08-1025-IMG_4352.jpg
HTML5 even has its own gang sign (Be sure to remember it if your caught in a dark alley between a gang of Ror guys and those PHP punks)
http://www.fincher.org/images/2011-10-08-1025-IMG_4354.jpg
Estelle Weyl at www.standardista.com presented a very informative session on HTML5 forms.
(If you see her, be sure to wish her a happy Columbus day). Estelle showed how to style invalid input boxes with CSS. I liked her presentation format of using
http://www.fincher.org/images/2011-10-08-1544-IMG_4355.jpg
We ended with a panel discussion
http://www.fincher.org/images/2011-10-08-1633-IMG_4360.jpg
Mike Wilcox gave an interesting history of video on the web, including H.264 (based on Quicktime), MPEG/4, WebM. Some browsers support some video encoders natively, but no video format enjoys support from all browsers. Mike's solution? Upload your video to YouTube and let them figure all that out.

A few useful sites:
CanIUse.com Summary of browser features like HTML5, CSS3 and SVG
html5boilerplate.com examples of best practice in html5 and CSS
schema.org for schemas
microformats.org/

Monday, October 10, 2011

VS2P4 - A Visual Studio Plugin for Perforce

I've been using VS2P4 for a while and really like it. VS2P4 automatically checks out files in Visual Studio. Dale Brubaker has done a fantastic job with this plugin.

Saturday, October 08, 2011

Pictures From Pablo's Fiesta - Open Space Austin TX Oct 30,2011

I went to my first Open Space Conference, Los Techies's Pablo's Fiesta. Here's a few photos:

Doc Lister started by giving the ground rules of an Open Space Conference. Four ideas and one rule; or was it four suggestions and two golden rules? Whatever.
http://www.fincher.org/images/2011-09-30-1757-IMG_4246.jpg
http://www.fincher.org/images/2011-09-30-1813-IMG_4249.jpg
http://www.fincher.org/images/2011-09-30-1814-IMG_4250.jpg
Matt Hinze was one of the suggesters of sessions for the next day.
http://www.fincher.org/images/2011-09-30-1818-IMG_4252.jpg
http://www.fincher.org/images/2011-09-30-1823-IMG_4253.jpg
Jeffery Palermo suggested a session on how to hire programmers.
http://www.fincher.org/images/2011-09-30-1827-IMG_4254.jpg
http://www.fincher.org/images/2011-09-30-1827-IMG_4255.jpg
http://www.fincher.org/images/2011-09-30-1845-IMG_4257.jpg
Our list of sessions:
http://www.fincher.org/images/2011-09-30-1847-IMG_4261.jpg
We did a "fishbowl" exercise with five chairs, one has to be empty, and people talked about software quality - reminded me of Zen and the Art of Motorcycle Repair.
http://www.fincher.org/images/2011-09-30-1856-IMG_4263.jpg
http://www.fincher.org/images/2011-09-30-1856-IMG_4264.jpg
Jeffery Palermo and Steve Done hosted a session on how to hire good employees. Jeffery asked a good set of questions:
How long does it take to learn you've made a mistake in hiring? How can you simulate the process in hiring to avoid making that mistake?
Jeffery did something very good near the end of the talk. He asked everyone who had contributed to the discussion to be quiet so we could hear from those who were quiet. This had the effect, for a little while, of silencing those who had been a little too verbose early on.
http://www.fincher.org/images/2011-10-01-0936-IMG_4332.jpg
http://www.fincher.org/images/2011-10-01-0937-IMG_4335.jpg
http://www.fincher.org/images/2011-10-01-1056-IMG_4338.jpg
http://www.fincher.org/images/2011-10-01-1056-IMG_4339.jpg
http://www.fincher.org/images/2011-10-01-1225-IMG_4342.jpg
http://www.fincher.org/images/2011-10-01-1236-IMG_4343.jpg
http://www.fincher.org/images/2011-10-01-1617-IMG_1353.jpg

My random tidbits:
Test your site in IE early. Sometimes IE's JavaScript is so glacial your site is unusable.
Check out Blueprint.css for web templates.
Node.js is a server-side JavaScript library to host simple web sites.
Watin is preferred for Web GUI testing.
Use Socket.IO library for web sockets
http://dailyjs.com/ for your daily dose of JS.
Cloud9ide.com is an interesting site - your browser is the ide. Cloud9 will publish your site directly to github. Cloud9 doesn't do compiling, because the cool kids are writing in scripting languages.
Checkout John Teague's blog. He did a great session on Node.js
coffeekup.org
Use nhprof.com to profile your nhibernate code. Other ORMs: dapper, petaPoco, Massive
Sql 98 GoldParse.txt
CQRS - Command Query Responsibility Segregation
SignalR is an event sourcing library that degrades well over different browsers. It tries WebSockets. If the browser doesn't support them it tries a flash program, then long polling to communicate with the server. (This can be bad if you have a lot of customers using old browser using long polling - can tie up threads on the web server)
trello uses SignalR
NServiceBus

Tuesday, September 13, 2011

ADNUG: Justin Pope on Advanced jQuery




Justin Pope from Headspring spoke to 70 people at the Austin .Net Users Group last night on Advanced jQuery. Justin started by giving a brief overview of jQuery, which I appreciated, and moved to major components like Datatables and UI. Along the way Justin gave warnings of land mines in jQuery, like always use "thead" and "tbody" in tables. Justin is a great presenter with a good sense of humor.
My jumbled notes:
Use a mirror site for JavaScript libraries so your page loads faster since browsers may limit simultaneous connections to a site.
Put your JavaScript at the bottom of the page instead of the headers so the page loads faster.
Golden Rule: Select by class instead to id.
Use Datatables from Datatables.net
"Flot" is a great free graphing package; High Charts is great, but costs money. (protoviz was also mentioned by the audience.
Diamond Rule: Use special characters, like "-" in naming to make finding JavaScript classes easier.
Platinum Rule: Use separate classes for styles and functionality.
Justin recommended the book "JavaScript: The Good Parts", and Rebbecca Murphy's site jqfundamentals.com

Friday, August 26, 2011

And the winner is ... SmallPox

Interesting visual about the most deadly diseases in history.
Malaria kills almost 800,000 people a year and yet our first world news seldom mentions it. Few organizations target it. Malaria is the elephant in the room few talk about. Fortunately the Bill and Melinda Gates foundation takes the suffering of millions of people seriously.
The Deadliest Disease Outbreaks Visualized
Infographic by Visual News

Arduino Boot Camp II

Our intrepid band of Arduino wannabes met again and Blake Freeburg taught us how to read sensors, this is part two of an eight part series in learning the Arduino way.
http://www.fincher.org/images/2011-08-22-2130-Arduino1.jpg
http://www.fincher.org/images/2011-08-22-2130-Arduino1__0_.jpg
http://www.fincher.org/images/2011-08-22-2130-Arduino1__1_.jpg
http://www.fincher.org/images/2011-08-22-2130-Arduino1__2_.jpg
http://www.fincher.org/images/2011-08-22-2130-Arduino1__5_.jpg
http://www.fincher.org/images/2011-08-22-2130-Arduino1__6_.jpg
Rachel watched "Beauty and the Beast".
http://www.fincher.org/images/2011-08-22-2130-Arduino1__3_.jpg


Quicken 2010 Cannot Connect to Bank of America

Quicken is so awful in many respects and somewhat competent in others, but I have used it for years and have a lot "invested" in the product.
Recently it stopped connecting to Bank of America and I got it to reconnect by basically disconnecting it from "OneStep Update" and then adding it back. Here's my suggestions:

1. Select your Bank of America account from the navigation pane on the left side.
2. Click on the "Account Actions" dropdown list on the upper right side.
3. Select "Edit Account Details".
4. Select the "Online Services" tab.
5. Select the "Remove from One Step Update" button.
6. Then add the account back by selecting "Activate One Step Update".
7. Bank of America will give you a challenge question.
8. My account then successfully could connect again to Bank of America.

Monday, August 22, 2011

Why Software Is Eating The World

Marc Andreessen has a great article in the wsj about why software matters more than most people think. (Granted he is heavily invested in software, and it's to his advantage for people to think software is important, but he makes valid points).
"... every company I work with is absolutely starved for talent. Qualified software engineers, managers, marketers and salespeople in Silicon Valley can rack up dozens of high-paying, high-upside job offers any time they want, while national unemployment and underemployment is sky high."
I am currently seeing this in Austin. I bump into old friends in the industry and their companies are hiring not just one software developer but 8 - 10 people. It's a great time to be a really good polyglot software developer.
For the past decade enrollment in software as a major has been falling. I think High School seniors hear the news about all the software jobs going to India and China and they think no more jobs will be left here. The seniors are partially right. The low skilled software jobs are going off-shore, but many of the highly technical jobs go begging for applicants here in the US. So Seniors, if you have a love of programming and technology, heed Marc's advice, go into computer science and write the software that will eat the world.

Wednesday, August 10, 2011

Austin .Net Users Group Meeting August 8th, 2011 Business Intelligence

Jeffery Palermo spoke about how developers can make their data more usable by Business Intelligence software. He talked about using Fact tables and Star schemas. He gave a great example of some very ugly SQL to produce a report that was turned into clean SQL by using a fact table.

Saturday, August 06, 2011

Arduino Boot Camp

Blake hosted an Intro to Arduino, the open design controller.


At the end I had my Arduino board blinking lights.

Bruce Tate Speaking at Agile Austin August 2th, 2011

Bruce Tate gave a talk on "Languages and Leverage: The impact of programming languages on high-leverage programming". I'm a big fan of Bruce since he wrote Beyond Java, Bruce has been willing to move on to new technologies after making a huge investment in Java.
Bruce took old movies and identified each one with a language making the time more fun.

2011/2011-08-02-1828-IMG_8714__Small_.jpg
2011/2011-08-02-1828-IMG_8713__Small_.jpg2011/2011-08-02-1840-IMG_8719__Small_.jpg
2011/2011-08-02-1840-IMG_8719.jpg
2011/2011-08-02-1840-IMG_8718.jpg
2011/2011-08-02-1840-IMG_8718__Small_.jpg

My random notes (which may or may not be what Bruce actually said):
Complexity is expensive; oversimplification leads to complexity.
Scala is good for java developers to come to the functional party, but perhaps not a good language for those not vested in java.
Lisp is the most powerful language with possible exception of Haskel.
Every 3-5 years Lisp makes a comeback.
The language matters a lot in a project, especially since it affects communication with team members. The community around a language matters.
Bruce uses RubyOnRails for his company.
We are all polyglot programmers now - javascript, css, html, and our main language.
Don't put in more languages on a whim, make sure adding a new language buys more than the overhead it costs.
Every 10-15 years programming goes through a paradigm shift - we are starting the transition to functional programming to take advantage of all those cores that Intel gifts us.