Archive for March, 2009

Find the second (or third, or fourth) occurence in a string

PHP includes some handy functions to find the first or last occurrence of a given string token in a string: strpos and strrpos. However these functions are limited to just the first occurrence; what if I want to know the location of the second token’s position, or the third? These problems usually result in some serious coding acrobatics.

Well no need for code-jitsu anymore. Based almost completely on a post I found at another blog — which is now down, how’s that for timing? — here are two functions which allow you to search for any occurrence of a specific token in a string…

/**
 * Find position of Nth $occurrence of $needle in $haystack
 * Starts from the beginning of the string
**/
function strpos_offset($needle, $haystack, $occurrence) {
  // explode the haystack
  $arr = explode($needle, $haystack);
  // check the needle is not out of bounds
  switch( $occurrence ) {
    case $occurrence == 0:
      return false;
    case $occurrence > max(array_keys($arr)):
      return false;
    default:
      return strlen(implode($needle, array_slice($arr, 0, $occurrence)));
  }
}
 
/**
 * Find position of Nth $occurrence of $needle in $haystack
 * Starts from the end of the string
**/
function strrpos_offset($needle, $haystack, $occurrence) {
  // explode the haystack
  $arr = array_reverse(explode($needle, $haystack));
  // check the needle is not out of bounds
  switch( $occurrence ) {
    case $occurrence == 0:
      return false;
    case $occurrence > max(array_keys($arr)):
      return false;
    default:
      $inverted = strlen(implode($needle, array_slice($arr, 0, $occurrence)));
      $actual = (strlen($haystack) - 1) - $inverted;
      return $actual;
  }
}
 
// look for second occurrence of letter 'a' from the start of string
echo strpos_offset('a', 'abracadabra', 2);
// returns 3
 
// look for second occurrence of letter 'a' from the end of string
echo strrpos_offset('a', 'abracadabra', 2);
// returns 7

In terms of use, we’ve essentially added an extra argument to strpos and strrpos that specifies which occurrence you’re looking for. In other words, you can make both of these functions work like the PHP standards by setting the third $occurrence variable to 1.


Free and open source alternative to ShareThis, AddThis, AddToAny

Update: Make sure you check out the comments! My post is just a launching point for some great commentary from staff at iBegin Share and Add to Any.

Every site with timely or useful content should utilize some on-site bookmark sharing tool. I’m talking about the bar of links to social networking sites like Facebook, Digg, Reddit, Twitter, etc. that you find at the end of a post. These buttons are preset to recognize the URL of the page they appear on, allowing visitors to quickly propagate your content to their digital lifestream. Wordpress specifically offers a ton of plugins that offer such functionality.

The most popular tools use Javascript to display all the sites in a popup: Add to Any, AddThis, and ShareThis. Speaking in terms of pure function, these tools are great: they make sharing functionality readily available without cluttering up the display.

However these JS-based bookmarkers possess some significant downsides. First and foremost are the performance concerns. These tools are all stored remotely, and get loaded on your page as a javascript include. Here’s an example of the code from ShareThis:

<script src="http://w.sharethis.com/button/sharethis.js#tabs=web%2Cpost%2Cemail&amp;charset=utf-8&amp;style=default&amp;publisher=abc123" type="text/javascript"><!--mce:0--></script>

Pay attention specifically to src="http://w.sharethis.com/button/sharethis.js[...]". It’s just a normal URL, like any page you visit. This means that each time the page is loaded, the user’s browser goes off to retrieve a copy of the javascript required to display the button. Aside from the obvious bump in bandwidth usage, they can cause an obvious delay in page loading. Worse, if the service is experiencing any kind of slowdown or outage, including these services can cause your site to hang and timeout. And these services do hang on a regular basis. I’ve seen it last so long on my own blog that I’ve had to disable to the plugin until service returned. That the delay is not your fault does not matter; it slows your page down, making you the laggard in the eyes of users. Not good.

But while these services are not focused on reliability and uptime, they do spend an awful lot of time on data collection/aggregation, legal, and advertising. None of these are good for you, the site owner. All activity surrounding the button on your site is tracked. They can partner with ad networks, packaging in extra ad cookies when the button is served up. Aside from the privacy issues, this again increases bandwidth. Imagery — specifically the branded icons of each service — are copyrighted, making them subject to usage restrictions and leaving you open to dealing with pain-in-the-ass take-down requests. Update: Per conversation with Add to Any Founder Pat Driven in the comments, Add to Any actually avoids this type of language entirely, limiting all their legal jargon to a plain-speak Privacy Policy.

To be clear, there’s nothing inherently wrong with any of this. These are businesses, they provide a service and have to make money to stay alive. However I think the vast majority of users just want the fancy javascript popup, everything else is excess baggage.

Enter iBegin Share, a free, open source alternative for javascript-powered bookmark sharing. Instead of going offsite to retrieve code at each page load, iBegin Share runs locally on your site, saving you bandwidth and decreasing load time. iBegin Share tracks usage like its corporate counterparts, but that data is stored in your database and used for your own data tracking purposes only, saving more bandwidth (since it doesn’t have to communicate back) and your privacy. Finally, since its open source you can modify the code any way you want: change the look, layout, color scheme — the tool includes 4 preset color schemes, plus an option for text vs. button link — even add totally new share options. A Wordpress plugin version is available.

On the downside, external documentation is pretty thin at the moment, but the code is well-commented. There is also a forum, but activity there is rather limited right now — a discussion on a seemingly common issue started earlier this month has yet to receive any official word. So you’re on your own with any heavy customizing or problems, but I suppose that’s the tradeoff for eliminating any third party eyes poking around your traffic. Assuming it works as advertised, I’d argue that it’s a far better deal than the other tools, even without any customization ability.

If you decide to give iBegin Share a shot, or if you’re using it already, I’d love to hear how it’s working for you. Please share your experiences in the comments.


What not to do in a survey

I purchased Mario Kart Wii and decided to register it at Club Nintendo. It’s an interesting service and I’m playing along to see where they go with it. If you want to register your own Nintendo games, you can find it on the back of a bifold pamphlet included in the game case. Some older games refer to the service as “My Nintendo” — if you had an account there, the system will automatically send you through a transfer process when you log in.

Anyway, after entering the registration code, the system prompted to fill out a quick survey about my purchase. The final question read as follows:

Please share with us your thoughts/comments about Mario Kart Wii. (255 character max)

I didn’t have anything, so I skipped it. Nintendo didn’t like that, and kicked me back to the survey. There was no error message at the top, I had to scroll through the survey to find this message above the comments question:

Please enter your comment

I replied thoughtfully:

Don’t require comments. And if you are going to require them, don’t say “please.”

What have we learned here:

  • Don’t require users to fill in a comment block on a survey
  • Place some form of error message at the top of a submitted page
  • Frank plays Mario Kart Wii (it’s really good)


StartupNation contest popular result

Voting ended a few days ago for StartupNation’s 2009 Elevator Pitch Competition, and Fwd:Vault had a pretty good showing! Here’s a final tally on the top 10…

  1. CineCore – 1573
  2. My Sales Finder – 1264
  3. WorkingMomLifeline – 1225
  4. PublicStuff.org – 1172
  5. TBD – Michael Shipe – 879
  6. Spider Climbing – 765
  7. iSyndica USA Incorporated – 638
  8. BidWilly – 628
  9. Fwd:Vault – 525
  10. EasyEvaluations – 505

That’s out of about 110 entries, so I’m very happy with Fwd:Vault’s showing! The outcome is a result of efforts made mostly by friends, family, and colleagues. So to everyone who voted for me: you have my sincerest thanks.

Now the professional voting begins: 6 expert investors representing over $1 billion in early stage investing. Not sure how I’ll do there, but honestly I don’t care. If this contest taught me anything, it’s the power of personal networks. My final standing is a result of simply reaching out. I used my email contact list, this blog, Facebook friends, and LinkedIn contacts to let people know I was entered, and asked them to vote. 27 years of friends, family, and professional contacts combined with the internet can go a very long way.

Make sure you focus enough attention on building your own personal networks. In today’s world they are invaluable for gaining help, support, and advice.


How to price your services

During the networking hour at my last entrepreneurial networking event, I had the pleasure of meeting two fellow young starters who are starting their own identity consultancy (I’d love to link, but there’s no site yet). We had a great talk about the challenges of properly pricing your goods and services. They were nervous about over-pricing their services, driving off customers. At the same time, they didn’t want to leave significant money on the table.

Their mindset reminded me of my experience when I started freelancing computer support back when I was a teenager, and made me appreciate the experience that I’m carrying with me to Fwd:Vault. Here’s what I suggested to my fellow bootstrappers…

Compare rates of similar vendors
First you need a baseline. Gleaning pricing info varies from extremely easy to incredibly difficult depending on the market. For example, I can find hosting prices very quickly, but getting numbers from a web designer takes more effort. However there are basic tactics that apply across the board.

Since you’re starting your own business, it’s assumed that you’re walking in the door with a fair amount of experience, which should include knowledge of other players. Starting with previous employers, find out what others in your field charge for services similar to your new business. Most businesses make their pricing info public, so start with their website. Google searches can often turn up prices if the vendor is “hiding” their pricing (this is almost as bad as hiding phone numbers, never do it).

If that doesn’t work, try calling their office and asking for pricing from the receptionist. Most will give you some clue as to pricing, but some will immediately route you to a sales rep, account manager, etc. The key is to avoid as many phone handoffs as possible. These people won’t give you anything without extracting as much information about your project as possible — which doesn’t exist because you’re just looking for pricing, duh.

If they insist on routing to a sales rep, and the company is a direct competitor, hang up, because the jig is up. If however you’re talking with a similar company in a different market, tell them who are (make it clear that you’re not a competitor) and what you’re doing. Most people are happy will help out a colleague.

You’re worth more than you think
Once you have a picture of the overall price landscape, you have to determine where you fall in it. However a lot of freelancers and entrepreneurs make the mistake of undervaluing their own ability or product quality, myself included. I charged about $35/hr for one of my very first jobs, and standard fare was well above twice that for similar work. I was afraid that my age and limited experience would work against me, so I deeply undercut the competition.

It’s perfectly natural to cower a bit when putting yourself up for comparison against large standing players. But you (should) get into business for yourself for at least two reasons: (a) you’re good at it, and (b) you’ll make better money than working for someone else. Don’t sell yourself short on either one.

Never compete for the bargain basement
Even if a consumer is new to your market, most people have a decent nose for a good deal. A “deal” is not just about price, but what you get for that price. A higher quality product can fetch a higher price, and some people will take the better product because it’s better, in spite of the price increase.

We make this analysis ourselves all the time, but the natural feel to it goes out the window when you’re pricing your own product. Combine that with the poor self-valuation I described earlier, and you end up with pricing way under the mark.

I bring this up because there’s a real danger here. Businesses that deep-discount goods or services tend to attract a certain kind of customer: the kind only interested in saving a buck. These customers will never ever appreciate the quality of your product, or they’ll ignore it while attempting to squeeze you for a better deal. You’ll end up spending most of your time price haggling or figuring out ways to cut costs to improve your margins. Over time, the cost-cutting invariably eats away at quality, which is death knell of a small business.

It’s okay to undercut the competition, but don’t go so far that customers are focused solely on price.

Price is perception
Sometimes we pick the more expensive of equivalent products precisely because its more expensive. Why in the world would anyone buy a pair of Diesel brand jeans? They get worn like any other pair of jeans, and hold up as well. They even look the same, barring subtle stylistic differences. But they cost twice as much as a pair of Levi’s or Wranglers you pick up in a department store. You can make the same argument with sunglasses (Oakley), electronics (Sony), even food (Ben and Jerry’s), and there are hundreds of other examples.

Price helps determine customer perception to some degree in every industry, and you shouldn’t ignore its power. I worked for a non-profit for a number of years, and at one point we were discussing a price increase. In a hotly contested debate, one board member suggested that a price increase would be the equivalent of pricing a Pinto (i.e. our product) as a Cadillac. A board member compared our flagship program to one of the worst cars in history! How good of a program does that sound to you? Would you spend money on it? I retorted, saying that our program was in fact the equivalent of a Cadillac, but was priced it as if it was a Pinto. How enticing does the program sound now? Assume I wasn’t lying (I wasn’t; the program was bang-up awesome).

Fake it until it’s real
I’ve given you every reason to price your product “aggressively” — don’t shoot through the stratosphere, but don’t below sea level either. But none of this means a damn thing if you don’t have confidence in your ability to deliver at that price point. To that I say, “Suck it up!” Entrepreneurship and freelancing are not easy, especially at the beginning. But if you want to make a real honest go of it, you have to approach every new client, contract, and sale as if you were a 20-year vet. The only way to fetch professional prices is to do professional work, and the only way to do professional work is to just get started.

To establish the kind of street cred you’ll need, sometimes it really means you simply have to feign confidence. When I was just starting out, I came across some very aberrant behavior while fixing a person’s computer. I had zero clue as to what the problem was or how to fix it, but I knew that I could figure it out with enough time. When the person asked me what I thought, I waved the issue off as no big deal, that I see this kind of thing all the time. A few days of work and a lot of research later, the problem was fixed, and I had another skill in my belt.

This is a fine line; you want to look like you know what you’re doing, but don’t want to overstretch yourself. If it’s way over your head or way outside your area of expertise, come right out and say so. You look good by knowing your limits too.

Add 10%
So now you’ve got price guidelines and fake confidence, more than enough to come up with a good starting figure. Unfortunately, if history is any indicator, you’ll most likely end up underpricing yourself anyway.

So, once you’ve determined your final number, add 10% to it. If you don’t cringe uncontrollably, you’re set. If you do cringe, recalculate at 9%. Repeat the whole process until cringing ceases. If you reach your original number, add 5% and walk away, you’re thinking too much.


First interview on Fwd:Vault

Fwd:Vault’s got some press, woohoo!

I was approached by Philadelphia Startup Blog for an interview on Fwd:Vault. The interview was done via email and just went live today. Check it out and let me know how I did.


Elevator pitch contest update

In case you haven’t looked at my sidebar in the last month or so, my new startup Fwd:Vault is entered in StartupNation’s 2009 Elevator Pitch Competition. Through endless harassment support of friends, family, and professional colleagues, we’ve been able to hold down a spot in the top 10 (6th as of this writing). That’s simply fantastic in and of itself.

Now we are down to the wire. The contest ends on March 20, just about 2 weeks away. If you like what you read here, you can have a direct and positive impact on the author by taking just 5 seconds and voting for Fwd:Vault. Just use the stars below the video player to rate and you’re done. No accounts to create, and it doesn’t cost a penny. I’ll be sure to post here again with the results of the contest.

Thanks for your votes!


Don’t use excerpts in your RSS feed

I’ve become a big-time RSS junkie in the last few months. Google Reader is my preferred format, but I am looking into some of the desktop-based readers. I’ve picked up on a subtle trend from these months of scouring roughly 50 feeds. The vast majority of feeds simply include the entirety of a given article, eliminating the need to visit the site at all. However a few only include small excerpts, usually the first few lines of the article, and you have to click through to the site to read the entire article. Perhaps it’s not surprising, but in all the cases I’ve seen, these sites use significant amounts real estate for advertising. Some even do those stupid shoved-in-the-middle-of-the-article ads.

I subscribe to feeds for one reason: to centralize and simplify my information digestion. Centralize is bolded for a reason; If I can get to everything from one location, I can read it faster and move onto other things. Feeds that force me to click-through disrupt this process. Worse, they annoy me, making me less likely to stick around and even glance at the precious ads.

Click-through feeds also say a lot about the content itself. Obviously the site management is focused on advertising. For web advertising to really work, you need eyeballs, and lots of them. How do you get more eyeballs? By writing more content, and lots of it. The more content you have, the more stuff you get indexed, the better your chances of getting more eyeballs. It’s a simple formula, and it’s also emotionally void. How useful (or insightful, or interesting, etc.) can the content truly be when the primary focus is on writing articles simply to make more words? Content for content’s sake will never hold a candle to information eagerly shared through genuine interest.

If you are currently using or considering the click-through feed format, I offer this alternative. Take the time to produce meaningful content, and offer it without strings attached. Then, when you have something to offer me, present it in and with your content. I promise you that you’ll have my attention. To put it more bluntly: if the crap you’re peddling isn’t relevant enough to actually be a part of your content, I don’t want to see it.

Besides, I use AdBlock Plus everywhere I go. And now, hopefully you do too.