Skis / Toys / Fun

Appeal to greatness not guilt

Skis / Toys / Fun

Time for Money (business 101)

March 1st, 2010

I just read a post talking about the “Does your startup pass The Sleep Test“, in principal the idea is sound it’s a little simplistic.

Fifteen years ago I worked as a consultant, the money was good but the problem I quickly realized is that fundamentally I was just trading time for money.  We can all see how a construction worker trades time for money — $15/hour here I come I’ll hammer and pour concrete all day.  Being a ski instructor is the same way, just like any trade job you’re just on the work for X hours get Y dollars, but you have to wake up and do it all again…  What’s funny is there are a lot of white collar jobs that are the same way, Lawyer is being a great example — hence why many people are slaving away on the partner path — then at least they get the benefit of their co-workers time.

Fundamentally, you need to build a business that for every hour you put in yields a % gain in a core asset.  That asset can then be realized in a few different ways.

  • A blog — you post frequently — have a regular readership that grows and advertising to support it.  This passes the sleep test, people read while you’re asleep, but at some point to grow you need to be a publisher (e.g. TechCrunch) because if you don’t and go on vacation your asset will decrease in value.
  • A piece of software — you or a small team builds a piece of software and sell it, you potentially can sell the software for many times the cost of development.  If done right you can build service contracts and upgrades that yield long term revenue on your customers post sale.
  • Software as Service — similar to above, but now you can charge on a reoccurring basis, though fundamentally this is really just shrink wrapped software with the support side built into the monthly charges.  Variants on this are advertising supported web apps. etc. etc.
  • Secondary assets — you build a widget give it away for free, but fundamentally you’re building a secondary asset that you hope to either data mine or sell directly.   When you signup for that free car at the mall, the offer is the car, but the company is now getting access to your contact information to both sell you a timeshare but also now they’ve got Name/Address/Phone/Email all in a nice neat package..  Plus as a “Are you interested in a Timeshare” phone call you can verify all of the information.

Once a business has an asset, Readers/Customers/Core Asset it now has something to grow and foster.  This is asset is then what the business should be organized around the care of.

Tags:

Twisted code review…

November 12th, 2009

If you have a few minutes and speak python & twisted, it would be useful to have an extra set of eyes on this section of code. The basic idea of this is to be a reconnecting thrift client, such that I can just write simple client.function(a,b,c) calls without having to worry about if there is or isn’t a client and it will queue reconnect as needed.

from thrift.transport import TTwisted
from thrift.protocol import TBinaryProtocol
from twisted.internet.protocol import ReconnectingClientFactory
from twisted.internet import defer, reactor
from twisted.python import failure
from collections import deque
from redback import log
 
class ClientBusy(Exception):
    pass
 
class ClientDead(Exception):
    pass
 
class InvalidThriftRequest(Exception):
    pass
 
class ManagedThriftRequest(object):
    def __init__(self, method, *args, **kw) :
        self.method = method 
        self.args   = args
        self.kw     = kw
 
class ManagedClient(object) :
    def __init__(self, factory) :
        self.__factory = factory
 
    def _is_connected(self) :
        return self.__factory.is_connected()
 
    def __getattr__(self, name) :
        if hasattr(self.__factory.client_class, name) :
            def f(*args, **kw) :
                return self.__factory.pushRequest(ManagedThriftRequest(name, *args, **kw))
            return f
        raise InvalidThriftRequest("Cant find method: %s" % name)
 
class ManagedThriftClientProtocol(TTwisted.ThriftClientProtocol):
    def __init__(self, client_class, iprot_factory, oprot_factory=None):
        TTwisted.ThriftClientProtocol.__init__(self, client_class, iprot_factory, oprot_factory)
        self.client_class = client_class
        self.deferred = None
        self.alive    = False
 
    def connectionMade(self):
        log.debug(self, "Connection made to", "%s.%s" % (self.client_class.__module__, self.client_class.__name__), "[%s]:%s" % self.transport.addr)
        self.alive = True
        TTwisted.ThriftClientProtocol.connectionMade(self)
        self.client.protocol = self
        self.factory.clientIdle(self)
 
    def connectionLost(self, reason=None):
        log.debug(self, "Connection lost to", "%s.%s" % (self.client_class.__module__, self.client_class.__name__), "[%s]:%s" % self.transport.addr)
        self.alive = False
        try :
            TTwisted.ThriftClientProtocol.connectionLost(self, reason)
            self.factory.clientGone(self)
        except Exception, e :
            log.error(self.connectionLost, e)
 
    def _complete(self, res, request, dfd):
        self.deferred = None
        if isinstance(res, failure.Failure) and dfd :
            self.factory.pushRequest(request, dfd)
        else :
            if dfd :
                dfd.callback(res)
            self.factory.clientIdle(self)
        return res
 
    def submitRequest(self, request, dfd):
        if not self.alive :
            raise ClientBusy
        if not self.deferred :
            fun = getattr(self.client, request.method, None)
            if not fun:
                raise InvalidThriftRequest("No such method as : %s" % request.method)
            else :
                try :
                    d = fun(*request.args, **request.kw)
                except Exception, e :
                    log.error(self.submitRequest, "calling : ", request.method, e)
            self.deferred = d
            d.addBoth(self._complete, request, dfd)
            return d
        else:
            raise ClientBusy
 
class ManagedClientFactory(ReconnectingClientFactory):
    maxDelay        = 5
    thriftFactory   = TBinaryProtocol.TBinaryProtocolAcceleratedFactory
    protocol        = ManagedThriftClientProtocol
    submitLoopSleep = 0
    client_class    = None
 
    def __init__(self, client_class=None):
        self._stack        = deque()
        self._protos       = defer.DeferredQueue()
        self.deferred      = defer.Deferred()
        self.client_class  = client_class or self.client_class
        self.client        = ManagedClient(self)
 
    def _errback(self, reason=None):
        if self.deferred :
            self.deferred.errback(reason)
            self.deferred = None
 
    def _callback(self, value=None):
        if self.deferred :
            self.deferred.callback(value)
            self.deferred = None
 
    def clientConnectionFailed(self, connector, reason):
        ReconnectingClientFactory.clientConnectionFailed(self, connector, reason)
        self._errback(reason)
 
    def buildProtocol(self, addr) :
        self.resetDelay()
        p = self.protocol(self.client_class, self.thriftFactory())
 
        p.factory = self
        #self._protos.put(p)
        return p
 
    def clientIdle(self, proto) :
        self._callback(True)
        if proto.alive :
            self._protos.put(proto)
 
    def clientGone(self, proto):
        pass
        #if proto in self._protos :
        #    self._protos.remove(proto)
 
    def _protoErr(self, proto):
        pass
        #import traceback
        #traceback.print_stack()
        #print "IN PROTO ERR", proto
 
    def _protoReady(self, proto):
        if proto.deferred : 
            log.msg(self._protoReady, "Proto currently active!")
            return
        if not proto.alive : 
            log.msg(self._protoReady, "Proto currently dead!")
            return
 
        try:
            request, deferred = self._stack.popleft()
        except defer.QueueUnderflow :
            pass
 
        d = proto.submitRequest(request, deferred)
        return d
 
    def pushRequest(self, request, din=None) :
        d = din or defer.Deferred()
        self._stack.append((request, d))
 
        dfd = self._protos.get()
        dfd.addCallback(self._protoReady)
        dfd.addErrback(self._protoErr)
        return d
 
    def shutdown(self) :
        """Shutdown this factory"""
 
        self.stopTrying()
        for p in self._protos:
            if p.transport:
                p.transport.loseConnection()

Tags:   · ·

Good ideas, inquire within

October 15th, 2009

I’ve had lots of idea of things to build, as somebody once said ideas are a dime a dozen, it’s doing it that’s the hard work.  Between talking to companies over the years, or just random things I’ve stumbled across there has to be a good idea to put more energy into.

Things I’ve built in the last few years — in some state of “goodness” (90% complete or better).

  • totallypsp.com - Basic idea was to be a daily featured marketplace for PSP games and accessories.   It’s there it’s running, but once it was going to move from a “build” to manage step I ran out of interest… [100% done]
  • zapquiz.com - Originally came out of a need to have a way to make some review quizes for my PSIA exams.  The core idea was to have a community of people contribute questions on a subject and they have people take sample tests and work forward.   My daughter wants me to finish it, but I’m not sure what “finished” looks like.  This is a case where I’ve not figured out what the product is fully… or how to make it FUN. [95% done]
  • notewave.com - Shared drawings in the vein of sketchfu.com or other shared drawing services.  This half in my mind morphed into focusing on creative clipart on photos… Which yeilded a non-existant iPhone app which would allow you to take a photo, mark-it up and share with your friends on facebook.  The facebook side of things is working where you can create wallposts with photos from your albums and creative drawing, though the UI is crude and it’s only avalable if you have a secret AppID…  [95% done]
  • IrisWall – my Windows Flickr screen saver — it was finished, just never released… Mentioned it to a friend the other day and he was like “Cool Can I get it…” hmm.. source code is in some dusty folder… [100% done]
  • feedini.com – Yet another news agregator, I think this space is dead again…  Had some cool ideas, but not worth anything [90% done].
  • A CMS for google app engine, it allowed for uploading of zip files as template bundles…  But, the problem is that it’s a total pain to configure appengine for 3rd party applications.  The idea was that a small business could use the CMS as the base for a website — with all the CMS features (WYSIWIG, etc.) and a template collection ala wordpress to quickly get an online presence.   [90% done]

Now things I’ve been thinking about:

  • a CRM for job seekers — though I’ve now found about three others, not sure if it’s a worthwhile space.
  • Combining the idea of short status updates and 360′ reviews into a tool that allows you to have a shared vision of how you’re performing and what you’re working on.   Image if a tool periodically pinged you or your co-workers about what you were doing and your performance/perception…
  • Simple portal pages – think kosmix.com, but with the baggage of a search engine.  Focus in on domain name parking and companies like that where potentially providing a more delightful experience around a subject area might increase the parked domain experience.
  • Tools to extract structured information from webpages in a way similar to Yahoo!s Search Monkey but utilzing some better document techniques to provid automated infrastructure.  I keep on having vauge visions of a meeting a quack.com from 10 years ago.  They probably had the best system I’ve seen to date, but yet there are still some huge things to do.

Fundamentally, I want to build things to delight users.   It’s not too hard to get passionate about a problem, but fundamentally I want to really know who I’m building for…  Heck, it doesn’t even have to be “hard” — just has to be something that people find annoying and want improved.

What are your pain points – or where should I spend my energy?

Tags:

Tax Your Calories

August 1st, 2009

Just a random idea that came out of a strange hallway conversation on the cost of health care. Here’s the idea of the week.

One of the current big problems in America is the over consumption of food yielding both health problems and just waste. Since we’re currently trying to figure out how to pay for our healthcare system the quick idea is to tax calories in the style of other sin taxes. Think of it this way, a typical person consumes 2000 calories a day, if there was a sin tax of $0.20 (e.g 1 cent per 100 calories) it would be a small price to pay. The quick observation is that if you’re eating a Bacon Double Cheeseburger with fries and a large coke you’re probably just at a 2000 calorie lunch. So now when you eat breakfast and dinner you’re clearly contributing to your long term health care plan… that emergency room visit for a coronary bypass.

The quick modification is that there really should be no tax on any fresh or frozen produce. If you really were eating half of your calories in produce clearly your health care costs are going to be lower, than Mr. Bacon Dbl Cheeseburger.

Tags:   ·

Small changes in UI have big impact

July 30th, 2009

By allowing selection in a UI can lead to a huge impact in what you expect — not really rocket science… In an app that only allows for the addition (+undo for removal) your mental model is fairly simple. The moment you add the concept of selection all of a sudden your expectations jump exponentially. Think of the differences between Paint and Draw. In a paint app you don’t really think about a whole class of operations, but in your draw app all of a sudden you feel like you could move where a brush stroke is.

It’s really funny how drawing a little blue box around something to indicate selection, has such an enormous change.

Tags:

Facebook vs. Google

June 8th, 2009

Had a great discussion this morning with a co-worker.  The crux of the conversation is Google vs. Facebook — who is going to win. Is Google Wave the game changer that will kill facebook?

Nope.  We’ve really created three different product spaces in these organizations.  We’ve got Google which is “defined” as an applications company (gmail, docs, apps, etc.) and facebook which is social.

Can Google beat Facebook or Facebook beat Google — probably not — I don’t quite see how my “who’s got prettier eyes”  news feed item has any meaning on my “apps” page on iGoogle.  Sure, in a tab, etc, etc.  But, at the same time should facebook be a news feed, platform, or ???  Fundamentally, I don’t see why facebook isn’t pushing it’s platform harder and harder than Google.   It would be nice to see every site offer a login with facebook, let me move my data my personality around the web.  Make my friends part of my web experience, cut down on the “do you want to give permission” gunk.  Go for two-tier access — anonymous FB vs. logged in FB.

That way when I click on the “who’s eyes are these” trivial quiz, I can participate without sharing all of my data, but then they can impose the “join” functionality when I feel like it.

Side note — the funny part is that facebook is great for accepted bi-directional friendship, but twitter proves there’s a solid marketplace for uni-directional friendship.  Which is handled — weakly — by “fan” pages on Facebook.   It’s probably a topic unto itself to discuss how business can utilize Twitter/Facebook to market their “fan” tendancies to deliver new customers.

Tags:   · ·