About Fitzblog

Greetings!  I'm Pat Fitzsimmons, a software entrepreneur in Cambridge, MA.  I work for HubSpot, a startup building B2B Marketing Software.  My roles include writing code, designing the product, and plotting strategy.  More about me ...

Developers wanted

HubSpot is hiring developers.

Get Posts by Email

Your email:

My Projects

HubSpot has everything you need to market on the web: web site & blog tools, analytics, seo tools, and marketing campaign tracking.  It's the software used to build this site.  Check it out.

WebSiteGrader - You just spent big money on your new web site. How's it working out for you?  Grade your site.

Current Articles | RSS Feed RSS Feed

Installing pymsssql on Vista/Windows 7 and python 2.6

 | Submit to Digg digg it | Submit to Reddit reddit | Add to delicious delicious | Submit to StumbleUpon StumbleUpon 

Today I was trying to install pymssql using the automated installer.  When I ran python and imported pymssql I received an error: "ImportError: DLL load failed: The specified module could not be found."

Turns out that I needed a newer version of ntwdblib.dll   The folks at UserScape had made this DLL available here.  I downloaded it into my python26/Lib/site-packages folder, overwrote the existing ntwdblib.dll, and then it worked.

Googling around for the answer was not easy, so I'm posting this in case other searchers run into this problem. 

 

 

Tags: 

Nine Javascript Gotchas

 | Submit to Digg digg it | Submit to Reddit reddit | Add to delicious delicious | Submit to StumbleUpon StumbleUpon 


1) Comma Caused Coruption




<script>
  var theObj = {
        city : "Boston",
        state : "MA",
  }
</script>

Notice the comma after "MA"?  It will be the source of many woes.  Firefox will pay it no heed, but it will create a syntax error in IE.  Worst of all, IE will not tell you where the actual bug is.  The only soution is to scan through your entire 2,500 line javascript file trying to find that extra comma.



2)  "this" can change which object it's pointing at



Take a look at this code sample.

<input type="button" value="Gotcha!" id="MyButton" >
<script>
var MyObject = function () {
    this.alertMessage = "Javascript rules";
    this.ClickHandler = function() {
          alert(this.alertMessage );
      }
}();
document.getElementById("theText").onclick =  MyObject.ClickHandler
</script>


The function MyObject.ClickHandler will actually give a different alert, depending on how it's being called.

If you call MyObject.OnClick(); you will get a popup saying "Javascript rules". 

However, if you click on the button "MyButton", the popup will say "undefined"

When you assign MyObject.OnClick to the even handler, the special variable "this" now referes to the button, not to MyObject.

There are several ways to refer to MyObject.  My favorite is to introduce the "self" variable as a replacement for "this":

<input type="button" value="Gotcha!" id="theText" >
<script>
var MyObject = function () {
    var self = this;
    this.alertMessage = "Javascript rules";
    this.OnClick = function() {
          alert(self.value);
      }
}();
document.getElementById("theText").onclick =  MyObject.OnClick
</script>

Now the alert will say "Javascript rules" no matter what you call. The variable "self" will always refer to MyObject.

Note there is one more gotcha with the above code.  Do not forget the "var" in "var self" or IE will throw a mysterious exception.


3) Identity Theft



Never name a variable the same as an HTML ID:

<input type="button" id="TheButton">

<script>
    TheButton = get("TheButton");
</script>

This will work fine in Firefox but cause and object undefined error in InternetExplorer


4)  String replace only replaces the first occurrence



You might have a code to turn a title into a URL slug:

<script>
    var fileName = "This is a title".replace(" ","_");
</script>

To your chagrin, fileName is actually equal to:
    "This_is a title"

Unlike replace in other languages such as C# or Python, only the first occurence is replaced.  That's because the first argument to replace is actually a regular expression.

To replace all occurences, you need to set the global modifier. Use:

    var fileName = "This is a title".replace(/ /g,"_");

 


5)  MouseOut sometimes means MouseIn



When you have nested div's, the onmouseout event will fire for an outer box when you move inside the inner box.  For context menu's or hover overs, this is not the desired behavior.  My solution is to test for the mouse's location, and only take action if the mouse is actually positioned outside the outer box.

6)  ParseInt scoffs at your base ten numbering system



ParseInt is really nice, because it works with strings that are not pure digits.  I always find myself doing the following:
var height = parseInt("200px")

and get the height.

However, the default call to parseInt has a problem.

Guess what the value of monthInt will be:
  month = "09"
  var monthInt = parseInt(month )

If you guessed 9, then gotcha!  The answer is 0.

When the string begins with a zero, parseInt interprets the value in base 8.  To fix this problem, do the following:

var monthInt = parseInt(month , 10);

Now monthInt will be equal to 9.  The second argument forces parseInt to use a base ten numbering system.




7)  for loops over the kitchen sink



I once had an array as such:
var arr = [5,10,15]
var total = 1;
I iterated over the array:
for ( var x in arr) {
    total = total * arr[x];

}

This piece of code worked fine, until one day, I was getting error.  The error said, "Cannot object  by a number.  This flummuxed me since there were no strings in the array.  But, lo, when I iterated over the array and logged each value, there was an indeed a function object called "find". 

The cause was a javascript library that we had recently installed.  This library added a "find" method to the javascript array object.  Nice to have, but I the "for" loop in javascript will iterate it over all object attributes, including functions. 

But fortunately, the object was not included in the "length" attribute.  Thus to fix the problem, I used another kind of for loop:

for ( var x = 0; x < arr.length; x++) {
    total = total * arr[x];

}

That worked perfectly.



8)  Event handlers Pitfalls


Never set event handlers like the following:

window.onclick = MyOnClickMethod

1)  This will overwrite existing events.  It opens up the possibility of overwriting by some other javascript
2)  This can introduce memory leaks in Internet Explorer in certain circumstances. 

Instead, use a library that abstracts around the event handler, like YUI:

YAHOO.util.Event.addListener(window, "click", MyOnClickMethod);


9)  Focus Pocus



Often when I want to add inline editing to my app, I create a text field and then focus on it:

var newInput = document.createElement("input");
document.body.appendChild("newInput");
newInput.focus();
newInput.select();

However, the above code will create an error in IE.  The reason the even though you have added the element, it is not really available yet.  Fortunately, a split second delay is all we need:

var newInput = document.createElement("input");
newInput.id = "TheNewInput";
document.body.appendChild("newInput");

setTimeout("document.getElementById('TheNewInput').focus(); document.getElementById('TheNewInput').select();", 10);



Seven Startup Lessons from Intuit

 | Submit to Digg digg it | Submit to Reddit reddit | Add to delicious delicious | Submit to StumbleUpon StumbleUpon 
Recently I was reading Inside Intuit, a book about the rise of the company that makes Quicken and Quickbooks.  Here are the take home points.  Not all of these lessons are universal, but hopefully you will find them useful.

1)    Business skills and technical skills are equally important.  
Techies and suits can remove their hands from each other's throats and work together.  Intuit founder Scott Cook had the stereotypical business pedigree:   Harvard MBA, Proctor and Gamble Product Manager, and Bain Consultant.  Partner Tom Proulx was a 22 year old Stanford programming whiz.   Cook used his business skills to do systematic market research and create a clearly defined product plan.  While Intuit's techie-run competitors crammed in every possible feature to their product, Cook designed Quicken to make it super easy for the home user to balance a check book.  Cook also formed distribution partnerships with banks and devised innovative advertising campaigns. 

Equally important to Intuit's success were Proulx's technical achievements.  When the team realized that most people had trouble printing checks on their dot matrix computers, Proulx spent all night hacking up a way for the program to automatically alert the user if the printer paper was not installed right.  This ultimately earned Intuit  a patent.    Proulx worked long hours and programmed the first two versions of Quicken almost entirely by himself. 


2)   Learn from non-technology businesses. 
Founder Scott Cook previously worked as a brand manager for Proctor and Gamble, a big cereal maker.  He decided to imitate breakfast cereal marketing and package Quicken in a bright orange box so that it would stand apart on the shelves.  This was very different than the boring, business-like packaging of the time, and it helped Quicken sell.


3)     Your competitor is not other companies, but the way that things are done now.   Forty-six companies sold accounting packages at the time Quicken entered the market.   But Scott Cook found that Intuit's real competitor was paper and pencil.  None of the other packages could balance a checkbook faster than could be done by hand.    That was the real challenge that Quicken faced - not competitors.

4)   Talk to as many potential customers as you can, from the very beginning. 
After Scoot Cook thought of the idea for Quicken, he picked up a phone book and called a hundred people at random.  These conversations not only told Cook that he was onto something, but they also taught him to deeply understand people's check balancing habits and difficulties.  It was these calls that told him what the the three most important features of the product should be.



5)   Focus your product on the absolute essential user needs. 
Intuit's competitors crammed their products with every imaginable feature.  The resulting monsters were so complex that their own engineers could not even print a check.  By calling and talking to hundreds of people, Cook learned that there were three tasks that people that people wanted to accomplish:  paying bills, maintaining a record of checks, and reviewing expenditures.  He focused everything on making these three tasks incredibly easy.  He routinely pulled pedestrians off the streets of Palo Alto into their office and would sit with a stop watch as they tried to use the software to print a check.  The average user took 7 minutes to find the enter key on the keyboard (remember, this was the early 1980's), but they still managed to print a check within 15 minutes.

6)  Even future billion dollar companies will teeter on the brink of defeat.  
"This isn't a layoff," Cook told his employees, "I 'd like everyone to keep working.... we just can't pay you right now."  Intuit's bank account was down to a mere $385.  Cook told his employees that he would like to talk to each of them individually, but that they would have to wait because, at the moment, he had to meet with his marriage counselor.  His wife was distraught because their entire savings was disappearing into Cook's startup. 

Fortunately for Intuit, the lead developer, Tom Proulx agreed to stay on board working only for stock.  The company juggled which bills they would pay and which they would delay.  They used packing boxes as desks.   They endured and the tide began to turn.   The Apple II version was far more popular than the IBM version.  Several banks finally came through on the partnership deals.  A magazine gave the software a great review.  The cash came in, and Intuit was breathing again.


7)  Do right by your customers
Disaster struck.  Customers from across the country were calling in complaining that the latest version of Quicken was freezing when they were trying to save their data to a floppy disk.   Intuit decided that all 20,000 customers needed a new version, and needed it as soon as humanly possible.  In the days before the Internet, that meant creating 20,000 disks in three days.  That was 8,000 more than their supplier could provide.  So the entire staff got to work, gerry-rigging computers into the positions where they could copy disks using both their fingers and their toes.   After that came a massive envelope stuffing operation.  Within a week, they mailed out 20,000 new disks to all their customers.  Their customers loved the rapid response.  Their customer satisfaction was actually higher than before the bug occurred.



How to bring Internet freedom to China

 | Submit to Digg digg it | Submit to Reddit reddit | Add to delicious delicious | Submit to StumbleUpon StumbleUpon 
We commonly condemn China's draconian controls on Internet usage. But amazingly, there is a way that we in the United States can give everyone in China Internet freedom. Currently, it is fairly easy to set up a proxy server that allows a Chinese web surfers to access the Internet as if he or she was living in America. The problem with proxy servers is that if the server becomes popular, the Chinese government will block the web address of the server and punish those trying to use it.

The solution is to host the web server on the domain of a critical business site. A huge number of Chinese businesses run off of Microsoft services. When I spent time in China, most of the people I met used Microsoft Hotmail for their email - work and personal. Block Hotmail and the government cripples tens of millions of people going about their daily business. Other business critical web sites include American corporate sites, such as Microsoft Update, Google, PayPal, and Chase Manhattan Bank. The government cannot ban those services without suffering severe economic repercussions.

An of Congress should require that all major US companies doing business with China host proxy servers on their domains. A person in China would simply go to https://www.hotmail.com/FreeInternet/ and be able to access the entire web without restriction. By using the secure "https" protocol, the "FreeInternet" part of the address would be encrypted. Thus the Chinese government would have absolutely no way of detecting whether the user was using the free internet or sending a business email. Chinese citizens would be completely free to write blogs, read foreign news, and engage in political discourse all with complete security and anonymity.

Even without an act of Congress, we in free countries can create these proxy services by convincing the right organizations to host the servers on their domains. Domains such as apache.org or mozilla.org would be very difficult for China to block without doing severe damage to their software industry. We could build a movement to host proxy servers on these types of domains.

I'd love to hear your feedback about this proposal. If you think it's a good idea, please spread it around. We can start a movement to bring Internet freedom to China.

Offline Advertising Still Rules

 | Submit to Digg digg it | Submit to Reddit reddit | Add to delicious delicious | Submit to StumbleUpon StumbleUpon 
Marketing Sherpa has a fascinating report out on online versus offline advertising spending in 2006.  It turns out that old school advertising is still way ahead of this new internet thing.

Print newspapers and magazines have been taking a beating from the Internet and blogs, but they are still way ahead of all online spending in advertising revenue.  Spending on newspaper advertisements was $30 billion - 4 times the spending on paid search advertising.  Magazine ads were at $23 billion.  That's almost 6 times the spending on all online, non-search advertising.  .

One thing that might skew the numbers is that advertising costs so much less on the Internet.  Direct mail is the greatest expenditure at $59 billion.  But the online equivalent - email marketing - is virtually free. Thus even if there is nearly as much email marketing, it won't show up in the expenditure figures.  Another example of this asymmetry is Craigslist, which is eliminating the entire classifieds industry by making postings free.

While some might view this as a bucket of cold water poured on the Web 2.0 hype, I see this as a huge opportunity.   More and more content is going online, but advertising is not keeping up.  This is despite the fact that advertising online can be far more targetted and effective than offline.  Google, for example, can often get higher than $1,000 per CPM on it's more competitive search terms.  There is still a huge opportunity for companies in the space of analytics, ad targetting, and ad distribution.
Tags: 
All Posts