How to Start a Software Company 2.0

by Richard Rodger

       
 
Creating Wealth

I have changed the price of our first product, CSV Manager from $97 to $47, for the entry level license. This was not an easy decision. No pricing decision ever is.

CSV Manager was launched in September 04, so I do have a lot of data on sales at the $97 price point. Enough to generate a reasonable estimate of the value of the demand curve at that point. But it really is a black art. I have decided that the information obtained by changing the price is more valuable than the possible loss of revenue.

But there is another factor. One of the drivers for starting a business is to solve problems for people. To "create value", to put it in marketroid-speak. So what is value? What is wealth, in fact? People are wealthier when they get more for less. In this century, we have indoor plumbing. Two hundred years ago, you had to be Queen Victoria if you wanted enamel. Another example: Virgin Galatic. Pretty soonish you'll be able to view the final frontier for less than the price of nice house. Space is quite a bit more accessible than it was in 1969. So providing value is just the same as creating wealth. More for less makes you money. The true purpose of a good business is to make its customers wealthier. That's what Henry Ford did with the Model T, that's what Skype is doing today. A good business makes money for its customers.

And the purpose of technology is to make stuff cheaper. A true technology company keeps lowering its prices. Year-in, Year-out. That's why Ricebridge prices will get lower each year.

So why is XML Manager priced at $97, the old, high price? Because it's a new product. It has to prove itself in the market. Once that happens, and sales ramp up, we turn on the wealth tap and make it cheaper.

You may be thinking, "this guy is nuts! He's throwing money away!" Maybe, but our code is there to be used. The more it is used, the more valuable it becomes. More users mean more squashed bugs, more FAQs, more feedback, more features, and so on. By the way, that's what makes Open Source work so well – many eyeballs. Well, we have to earn a living, so we can't Open Source our products, but we can approach Open Source, asymptotically. And in doing so, we end up with products that people want to use, not products that they are forced to use.

These ideas are similar to Jonathan Schwarz's thoughts on "Volume". Now he does go on a bit, but he's basically right. Giving people more power to get stuff done is the purpose of a tech company. (hey, Jonathan, where's my server? hope you're not just keeping them for the big boys. I have benchmarks too you know!)

So this is all nice and warm and fuzzy, especially for new customers – cheaper stuff, Yay! It's not so nice for existing loyal customers though. They get a wee bit annoyed, and rightly so, when stuff they just bought gets cheaper overnight. So here's a pledge: If you are an existing Ricebridge customer you will always get a nice big fat discount on new stuff. And even then, if you think you've been treated unfairly, just let us know, and we'll find even more free stuff for you.

Well, what do you think? Am I about to run my company into the ground?

@ 10:15 PM GMT+00:00 [ comments [3] ]   email this   links to this
 
 
To Tell, Or Not To Tell, That Is The Question

One of the beta reviewers for our new product, XML Manager, asked me why I had not documented the development process on this blog. She suggested that it would be very interesting and useful for potential clients to see the development unfolding.

Well, it is a valid point. In fact, Eric Sink has some good thoughts on this very question. On the plus side, you give your customers a clear idea of where you're going, they know what products are coming along downstream, they can plan more effectively. On the other hand, you give your competitors a head start.

Seems like it comes to down to a question of, "do you love your customers more than you hate your competitors?" When you put it that way, it's a no-brainer. So I will be discussing the development of the next Ricebridge product. Why did I not do it for XML Manager or CSV Manager? Well the first mistake was not having a blog. The second mistake was not having a blog. And the third mistake was writing a business plan.

Yeah. I spent so much time writing a bloody business plan in the first half of this year I nearly bankrupted myself. More about that later.

So, you're in for a good read. Our next product is a standalone user management engine. It has a few nifty features you won't find in the user handling of your common-or-garden web framework. And it's half written already and in production for a client. This will be a classic case of productising consulting-ware. I'll be giving you the inside scoop, all the tears and all the laughter. Hey, with a few intelligent comments you might even get an honorary mention in the docs! (and no, there won't be a nerd movie.)

A lot of the discussion will be market-focused rather than tech-focused. Hey, this is a business. If you've been thinking about setting up your own software company, or thinking of running a weekend micro-ISV, then this is your chance to get an insider's view before taking the plunge. So hop on, this could get bumpy!

@ 08:35 PM GMT+00:00 [ comments [0] ]   email this   links to this
 
 
XML Manager Soft Launch (with freebies)

Big news this Monday. Ricebridge Software has launched our second Java component: XML Manager. It turns your XML into a list of data records, ready for processing. Check out the demo (all AJAX-ified, if I do say so myself!). We're doing a soft launch on this as it's far to close to Christmas to get into a big launch scenario. But come the New Year we'll have lots of fun.

This blog is supposed to be about starting a software company so you'll be hearing a lot more about my product marketing efforts over the next few months. I was holding off a little while we were finishing XML Manager, but now that the cat's out of the bag, I can start pontificating about how to run an ISV! Now I'm no Joel, I don't always do things perfectly, and if you've been thinking of starting your own software company then you might as well follow along and watch me make all sorts of entertaining mistakes. But no fatal mistakes. Rule number one of this trade is to set things up so that you can't fail. We're talking zero overheads, and self-maintaining systems.

Anyway, back to XML Manager. To reward all my readers, I've a little Christmas treat for you. Anyone who posts a comment before Jan 1 2006 gets a free single developer license. Hey, that includes a free CSV Manager single dev license too! So why not – you never know when you'll need to get a load of XML into a database!

@ 05:05 PM GMT+00:00 [ comments [6] ]   email this   links to this
 
 
Friday Fun: Silly Skype

Possibly the daftest thing you can do with Skype: WeeMee.

@ 05:21 PM GMT+00:00 [ comments [0] ]   email this   links to this
 
 
More Entries in the Edit Sidebar

Roller shows a list of recent entries and recent drafts on the left sidebar of the weblog editor page. This is a really handy little feature and lets you access entries and drafts really quickly. The problem is that only 20 entries are shown as standard, and there's no setting to change this. Back to the code!

So the sidebar template is in weblog/WeblogEditSidebar.jsp, surprisingly. A quick scan of the code reveals that the list of recent entries is predefined by the model:

<c:forEach var="post" items="${model.recentPublishedEntries}">

Looking at the top of that page, we see that the model is org.roller.presentation.
weblog.actions.WeblogEntryPageModel
. That's kind of a deep package structure, but OK. So inside that class, we hack up the getRecentPublishedEntries method. It's actually just a parameter change:

    public List getRecentPublishedEntries() throws RollerException
    {
        return rollerRequest.getRoller().getWeblogManager()
            .getWeblogEntries(
                rollerRequest.getWebsite(), // userName
                null,              // startDate
                null,              // endDate
                null,              // catName
                WeblogManager.PUB_ONLY, // status
                new Integer(20));  // maxEntries
    }

Change the maxEntries parameter to however many you want and away you go.

Now to deploy. Just run the wonderful build.sh all command from the Roller source root folder and it does most of the work. Copy across the new rollerweb.jar file and restart tomcat. And you're done.

And yes, before you point it out, I am aware that the Roller source does not meet my exacting standards of indentation. The fallback strategy is to stick with whatever dumbass indentation standard the codebase you have to work on uses. That's just the way it is.

@ 10:20 PM GMT+00:00 [ comments [0] ]   email this   links to this
 
 
Killer Conversations

I may be a bit late to the game, but I won an MP3 player in a raffle recently. Hey, I'm cheap! Anyway, I finally got into this podcasting thing. If you're just getting into it as well, check out IT Conversations. They have all sorts of great techie stuff there. You wouldn't use your MP3 player for music now would you? Not when there's loads of nerd stuff out there. Well, actually, I'm listening to The Killers at the moment (you know, from the Champion Sports ad), and they kind of rule in a sucky way – some good morphy sounds.

@ 09:36 PM GMT+00:00 [ comments [0] ]   email this   links to this
 
 
Revenge of the Clampees

So if you've read Gladwell's Tipping Point, you'll appreciate this one.

I was taking my daughter down to the local outdoor playground on Sunday, and the car park was unusually full. As in, completely. People were even parking up on the grass, and in no-parking zones. Cars all over the place. "Feck!", says I. "Look, the Park!", says herself, with no room for excuses.

Except, the local credit union car park, right next door, is empty. I'd say it's the great big scary "we will clamp you and your children unto the seventh generation" sign. So nobody has dared disgrace this tarmac. They've parked illegally everywhere else, but not in this car park.

Anyway, I have no time for this, so I just park there anyway. You can see the car from the playground and I'm ready to storm over and have it out with any clamping truck that comes along. Plus, you can see them coming along the main road so there'll be plenty of warning.

An hour later we head back to the car. The entire car park with the scary signs is now full. Looks like I've started something. As soon as one car did it, all the rest followed. Seems like the tipping point is one car.

I suppose it makes sense too – if there are loads of illegally parked cars, the clampers will take longer to get to yours. But the main reason is probably the old "everybody's doing it so it must be OK" line. So my tip for the week is, park it, and they will follow. Want to make use of a reserved car park? Just park and you'll soon have a bunch of followers to take the heat…

@ 04:33 PM GMT+00:00 [ comments [0] ]   email this   links to this
 
 
Data Center Minutes

Here's one for all you MBAs out there. I'm trying to work out the cost of a data center minute. Huh? What's that?

OK. Imagine you have a mid-range web server in a data center. You pay an annual fee, maybe some more for bandwidth, and maybe even more for tech support. I am talking about dedicated hosting by the way, so maybe you bought the server, or you leased it. Anyway, each minute of uptime is something that you pay for. So how much does it cost? For any given server, you can work this out, but I want to get an "average" figure. What is the market price for a data center minute right now?

This sort of setup seems to be about $200-$400 a month based on some googling. Which works out as $0.005-$0.01 a minute. Does that sound right?

@ 08:49 PM GMT+00:00 [ comments [0] ]   email this   links to this
 
 
Roller's Ugly Permalinks

I'm using Roller 1.2 for this blog at the moment. Roller 2.0 is out, but I'm in the middle of a beta-testing a new product so I'm not going to risk upgrading for a few weeks yet, in case I end up yak shaving.

I'm pretty happy with Roller. It's a great piece of code and it's been really easy to customise. I run it because I was already running tomcat, and it's just easier to keep everything Java focused if you can. (more on that later - there's a big deficiency in the webmail area with Java).

So anyway, the one thing that was really annoying me was the permalinks. The standard form is:

http://www.richardrodger.com/roller/page/richard?entry=foobar

Yuck. Not only does it look ugly, but the entry is only identified in the query parameters and is thus not analysed properly in most web stats packages (including google analytics, which I was lucky enough to get an account on). This makes it hard to tell which entries are getting the most hits etc. Also, the permalink is not search-engine friendly.

So time to put the hacking hat on. After scanning through the Velocity templates in the Roller distribution I was none the wiser. But then I decided to bite the bullet and hack the code. In the end it was pretty easy to change the permalink code. First, links of the form

http://www.richardrodger.com/roller/page/richard/Weblog/foobar

are supported (why are they not standard? dunno.), so this was my target. After a bit of global searching, I discovered the getPermaLink method in org.roller.pojos.WeblogEntryData. Replace the line:

String plink = "/page/" + website.getUser().getUserName() + "?entry=" + lAnchor;

with

String plink = "/page/" + website.getUser().getUserName() + "/Weblog/" + lAnchor;

And now the permalinks are just right. By the way, the easiest way to make this kind of quick change is to download the source and tools distributions, unpack them, and run build.sh all. It all "just works". Great stuff.

Of course, as you may have noticed, mucking with your feeds is not a good idea. If you change the permalink then all the old entries get replicated, because the aggregators think they are all new. So make this change before you go live.

@ 08:39 PM GMT+00:00 [ comments [0] ]   email this   links to this
 
 
Apologies to Subscribers

Hi. You may have noticed that all my posts have replicated themselves. I changed the permalink code to a nicer format, forgetting that this would mess up all the feeds. Sorry about that.

@ 10:52 AM GMT+00:00 [ comments [0] ]   email this   links to this
 
 
Rant: The Evils of Indentation (FREE STUFF If You Prove Me Wrong!)

Do you indent your code for good or evil? Of all the horrors that afflict the pilgrim programmer, evil indentation is the most horrific. The horrifying lack thereof, the horrifying use of tabs, the horrifying concoction of tabs and spaces, the ... well, read on fellow coder, and face the horror yourself!

But first, ask yourself one question: why do we indent? why do we bother? What is it in our very nature that makes indentation the first principal of coding?

Source code is all about structured logic. When you make it easy to see the logic, then the program is easy to read. That's why we indent. The first, foremost and only reason: it makes code easier to read. All else follows.

That's why I really have to wonder when I see badly-indented code. Do these coders care nothing for the ethics of the profession? How can they so callously cast these cancerous texts upon us? Do they care nothing for themselves? Will they not have to maintain these corrugations, six months hence? Do they secretly enjoy all-nighters and death marches? Perhaps...

So, in the interests of the programmer-on-the-street, I hereby lay down the evils of indentation. A how NOT to do it guide, if you will. If you have never consciously considered these great questions before now, if you have simply followed the pathetic example of your peers, the perilous proclivities of your peripatetic tutors, or the prescriptions of your workplace, then think now, or forever hold yourself back. Indentation is a detail that has to sweat.

⋅ ⋅ ⋅      ⋅ ⋅ ⋅ 

Here then are the evils of indentation. There's a suitably evil number of them: four.

The First Evil: To Tabulate

for( fs = 0; fs < sake; fs++ ) {
        thisIsNuts();
        if( mindcapacity < nineitems ) {
                fire();
        }
}

Evil Typewriter Hey, you know what? Tabs were invented for typewriters. In the modern software development environment, the tab key stands for only one thing: move this line of code to the correct indentation. It does not mean: insert a tab character. Just because you have tabs set up to show as four spaces as a kludge, does not mean that that the rest of the programming world thinks this is a good idea.

Tab characters will show up differently all over the place. The whole point of indentation is lost if the indentation is not the same for all developers on the project. Think of the children! For goodness sake stick to spaces. Every time you hit tab your IDE should insert the correct number of spaces to bring your code to the current indentation column. And that's it. Nothing fancy. But now, guess what? It looks the same for everyone. Do you realise how many lives you just saved? How many premature heart attacks you prevented?

The Second Evil: To Make Too Much Space

public void removeContext() {
    if( spacedOut() ) {
        line >>> allthewayover;
        meaning = inview ? ok : emptyspace;
    }
}

Evil Space So you like to indent by four spaces. Sure. Are you nuts? what a waste of screen real-estate. One of the biggest aids to program comprehension is ... code on the screen. Yup, the more code you can see the better. Get a bigger monitor and see the difference. So with your IDE of choice squashing the code window from all sides, you really need to avoid pushing code off to the right. It just disappears out of sight and out of mind.

So keep it to two spaces. Always and forever. There is no other way to optimise this. One space is not clear enough. Three spaces is bizarre. Four is wasteful. Anything more, like say, eight (Some people actually do this - God help us all), and you should be fired for wasting bytes.

OK, I'll relax a bit. Sometimes you can use four spaces to indent. When there is a substantial change of context, for example, anonymous inner classes (they are freaky enough to warrant their own rule, don't you think?), then it makes sense. It's a good visual clue that something a bit different is going on.

The Third Evil: To Stray From The Path

if( logic ) {
    canbefollowed();
  } else if( logic ) {
isclear();
} else {
    runaway();
}
  crying();

Evil Path So you've changed the settings on your IDE, you use two spaces, tab inserts two spaces, and auto-indents to the correct level, and you're sitting pretty. Not so fast, flyboy.

You are indenting everywhere right? And I mean, everywhere. There is no point doing it in a few places and getting lazy when you do your usual cut-and-paste coding anti-pattern. Or you make some changes to code that was written by someone else and you just, ignore the indentation. Sure it's only here and there. Bzzzt! can you say spaghetti code?

Stick to the one true path: indent everything, and never mix tabs and spaces.

A foolish consistency may be the hobgoblin of little minds, but you're not writing poetry, you're writing code. Get a small mind. A really really teeny-weeny tiny one. Get obnoxious about consistency and the coding brethren (that's a gender-neutral term, by the way) will thank you! Come on, neat code just makes your day.

The Fourth Evil: To Break The Bond

public void myProfessor()
  {
    toldMe();
    if( makeCodeReallyReallyClear() ) 
      {
        thenIAmGood();
      }
    else
      {
        actuallyIAmWasteOfSpace();
      }
  } 

A Good Bond So this one is a bit of thrown gauntlet. Here's the question: what does each level of indentation signify? Well? It's not hard...

One level of logic. Just one. Not two. One. Each level of indentation says we've gone a one level deeper into the decision structure. There is an intrinsic bond between indent and logic. Keep to this rule and your eye can scan the code and see that it is good. You can pick out the flow of the code from 300 yards and hit the target with your back turned using a mirror.

So why, oh why, do some people find it necessary to indent two levels, wasting a line into the bargain? Not a chance you can justify this. Maybe someone took a beginners design course where they were told that whitespace was good. Sure it is. But, you know, all things in moderation...

⋅ ⋅ ⋅      ⋅ ⋅ ⋅ 

Come on people! There are no excuses. Most source editors will auto-indent for you anyway. Let's get with the program and remove this root of programmer pain. We have enough to worry about with demanding managers, impossible deadlines and long hours. Let's just do each other a favour.

In case you think I'm all talk and no action, here's the action. You can scour my code for indentation evils. I have an open source project, Jostraca, that's been around for about five years and has had plenty of time to build up a bit of cruft in the codebase. So get going! Everybody who finds a violation will get a FREE CSV Manager single developer license, worth $97. Oh yes, that's real money.

Here are the rules: you have to be the first to find and post the example of incorrect indentation in the comments to this entry. You have to state which evil is being perpetrated. If you're second fiddle, tough luck. The example has to be taken from the latest release (1.4.0). Generated code and non-Java code don't count so don't bother looking there. Oh, and I reserve the right to invent new rules if I feel like it.

So come on, are you gonna bankrupt me for mouthing off or what?

@ 04:07 PM GMT+00:00 [ comments [6] ]   email this   links to this
 
 
Interview for Entrepreneur Focus Book

I just got my copy of Entrepreneur Focus, a new book on starting-up companies by Eric Locken. He asked me to do an interview for the book about my experiences starting Ricebridge, so with an ego the size of a planet, how could I refuse?

Here's a transcript of the interview.

There are a load of other great stories in the book. Go check it out if you're into startup tales.

@ 11:00 PM GMT+00:00 [ comments [0] ]   email this   links to this
 
 
Friday Fun: Make Life!

It will kill your CPU, but here's the classic Game of Life, ... in JavaScript! It is possible, Your Honour!

@ 04:20 PM GMT+00:00 [ comments [0] ]   email this   links to this
 
 
Emacs Autocomplete Bliss

You known that IntelliSense rots your brain, right?

Well if you use Emacs, now you too can rot your brain, only better (everything is always better with Emacs).

This is the most treasured snippet from my .emacs file. All it does is store every word in all open files and when you hit tab, it autocompletes based on the text before the cursor. Sure, it doesn't show you the list of possible candidates, but all you ever need is a few tabs and you'll find what you want.

; auto completion
;;;;;;;;;;;;;;;;;
(require 'dabbrev)
(setq dabbrev-always-check-other-buffers t)
(setq dabbrev-abbrev-char-regexp "\\sw\\|\\s_")

(global-set-key "\C-i" 'my-tab)

(defun my-tab (&optional pre-arg)
  "If preceeding character is part of a word then dabbrev-expand,
else if right of non whitespace on line then tab-to-tab-stop or
indent-relative, else if last command was a tab or return then dedent
one step, else indent 'correctly'"
  (interactive "*P")
  (cond ((= (char-syntax (preceding-char)) ?w)
         (let ((case-fold-search t)) (dabbrev-expand pre-arg)))
        ((> (current-column) (current-indentation))
         (indent-relative))
        (t (indent-according-to-mode)))
  (setq this-command 'my-tab))

(add-hook 'html-mode-hook
          '(lambda () 
             (local-set-key "\C-i"     'my-tab)))
(add-hook 'sgml-mode-hook
          '(lambda () 
             (local-set-key "\C-i"     'my-tab)))
(add-hook 'perl-mode-hook
          '(lambda () 
             (local-set-key "\C-i"     'my-tab)))
(add-hook 'text-mode-hook
          '(lambda () 
             (local-set-key "\C-i"     'my-tab)))

; add more hooks here

The code isn't mine and I can't remember where I found it, but it has saved me countless hours of typing.

@ 05:56 PM GMT+00:00 [ comments [0] ]   email this   links to this
 
 
Hey, They Use TCP/IP Too!

Another good one from Bruce: SETI virii.

Reminds me of the "negotiating with host" bit in Independence Day. Strange how the virus isn't evil when we're the good guys.

@ 11:29 AM GMT+00:00 [ comments [0] ]   email this   links to this
 
 
 
YahooBloglines
NewsgatorMSN
Google Readerdel.icio.us FurlSubscribe with myFeedster
« December 2005 »
SunMonTueWedThuFriSat
    
3
5
10
11
13
17
18
24
25
26
27
28
29
30
31
       
Today

All | General | Java | Business | Fun | Perl | Rant | Ireland | Web
[This is a Roller site]
[Valid Atom 1.0] [Valid RSS]
Technology Blog Top Sites
Blogarama - The Blogs Directory

Blog Directory & Search engine

Blog Flux Directory
Irish Blogs
 View My Public Stats on MyBlogLog.com

Performancing
Enter your Email


Powered by FeedBlitz
Theme adapted from Sotto.
 
Ricebridge XML Manager
  • Convert XML to a table of data
  • Convert XML to CSV, and CSV to XML
  • High-speed, single-pass XPath
  • Memory-stable and fault-tolerant
  • Loads of documentation
  • Cut-and-paste code examples
  • Find a bug, get a gift cert
Ricebridge Java XML Manager Component


Ricebridge CSV Manager
  • Convert CSV to a table of data
  • Handle any type of delimited file
  • Memory-stable and fault-tolerant
  • Loads of documentation
  • Cut-and-paste code examples
  • Find a bug, get a gift cert
Ricebridge Java CSV Manager Component


Popular Posts

 Sign up for MyBlogLog.com
Alertra Website Monitoring Service
Get Chitika eMiniMalls
Solo Tees
BlogJet