Author: Matt

  • django-linkshare

    One of the ways to make money on the itunes store is to sign up for the itunes affiliate program. Linkshare runs the program in the USA and they will give you a 5% commission on all sales that you refer. It works through cookie based tracking that is valid for 72 hours… Meaning that if you follow one of my links (even to a free download) and then buy something 2 days later then I get credited for the referral and make a few cents.

    Linkshare links currently make up about 15% of the revenue in my app business. It’s an extra little bit of money that takes very little effort to add to the bottom line.

    I’m building up my back end platform for reporting on all the various numbers I get for the business and putting them in one place. This past friday I got an email about the new web services REST api for Linkshare which I can use to generate various reports. It took just a couple hours to put together a django app that can download the month to date numbers and store them in the database for reporting.

    There might be a handful of people out there interested in using this sort of thing so I put the code up on github.

    LinkShare_336x280

  • Fabric For Development

    Fabric is a pretty awesome tool for deploying projects. But it turns out that it’s also pretty awesome for lots of other stuff.

    At PyCon 2012 there was a talk given by Ricardo Kirkner (which you can watch here) that inspired me to play around with fabric in some new ways.

    It’s possible to use fabric as a wrapper around the standard django ./manage.py script, to help setting up virtualenvs and install packages. Using fabric to script around these things means that there are fewer tools that new developers will need to get set up and know how to use. Scripts that normally might have been loose bash files can now be collected, organized and documented.

    I’m currently working on a large django project with 4 other developers who are new to python and django. Getting everyone’s development environment working was a big pain since there were multiple platforms (Mac and Linux) and different configurations for base packages. If I had thought of this sooner I might have been able to create a reliable fabric script so that “easy_install fabric; fab init_project” got them from zero to running django app.

    There’s also several oneliners that I run fairly regularly which can be saved in fabfile.py and called much easier. For example:

    def clean():
        local('find . -name "*\.pyc" -exec rm -r {} \;')
    

    Now

    $ fab clean

    will clear out any .pyc files in the project.

    It’s also possible to manage the virtualenv environment through fabric:

    VIRTUALENV = '.virtualenv/'
    def setup_virtualenv():
        created = False
        virtual_env = os.environ.get('VIRTUAL_ENV', None)
        if virtual_env is None:
            if not os.path.exists(VIRTUALENV):
                _create_virtualenv()
                created = True
            virtual_env = VIRTUALENV
        env.virtualenv = os.path.abspath(virtual_env)
        _activate_virtualenv()
        return created
    
    def _activate_virtualenv():
        activate_this = os.path.abspath("%s/bin/activate_this.py" % env.virtualenv)
        execfile(activate_this, dict(__file__=activate_this))
    
    def _create_virtualenv(clear=False):
        if not os.path.exists(VIRTUALENV) or clear:
            args = '--no-site-packages --distribute --clear'
            local("%s /usr/local/bin/virtualenv %s %s" % (sys.executable, args, VIRTUALENV), capture=False)
    
    def virtualenv_local(command, capture=True):
        prefix = ''
        virtual_env = env.get('virtualenv', None)
        if virtual_env:
            prefix = ". %s/bin/activate && " % virtual_env
        command = prefix + command
        return local(command, capture=capture)
    
    def manage(command, *args):
        virtualenv_local("python manage.py {0} {1}".format(command, ' '.join(args)), capture=False,)
    
    def runserver(*args):
        manage('runserver', *args)
    

    These functions let you create the virtualenv and run commands in the virtualenv (without having manually activated it). virtualenv_local wraps the call to fabric’s “local” function and sources the activate script before launching the command specified. the manage function provides a way to call django’s manage.py script, and the runserver function gives a way to use fabric to launch the server (in the virtualenv). So now the fab command can be used to consolidate both virtualenv tools and manage.py script into one document-able fabfile.py with a consistent command-line interface.

  • Python is like a Secret Weapon

    I am continually in awe of the power of Python code. The readability of the language combined with the lack of magic, and the massive number of easily obtainable libraries out there make getting things done insanely fast. It is the only language where I consistently experience writing code that works the first time.

    Last night I added a geo-location aware link redirector with click tracking to my django web app. It took about 1 hour to code while I was listening to a panel discussion. Within that hour I had written, tested, added additional models, migrated the production database and deployed the new application.

    At my day job, we have decided to migrate our web app from grails to django. The benefits have been numerous. The Groovy to Python conversion has resulted in significantly less lines of code, unit test runtime has dropped from 15 minutes to 3 seconds. The delay in starting the dev server dropped from 10 seconds to instantaneous. The functional style of code makes it far easier to avoid copy/pasting logic between subclasses. Python’s flexible import statement allows us to structure the code so that it makes more sense.

    If you’re not using Python. You should be.

  • Peculiar Puzzle – Missing GET Parameters

    over the last week I have been seeing an odd error usually just once or twice per day out of the 10,000+ requests per day that hit my django web app backend for the iPhone apps.

    It appears as though the GET parameters get dropped and I can’t explain why. Hoping someone out there has some suggestions.

    The code in my iPhone apps check in to get data from the webserver. This is new content for the app. For each request it needs to have a parameter to determine which app is requesting the data – since there are a few using the same server.

    The app code calls a statically defined url string like “http://appserver.com/app_data?app_id=aiuwbev”

    However, about one in every 10,000 requests that come though create an exception because that app_id is not present.

    The other bits seem to be on the mark. They don’t seem to be coming from a web browser manually.

    So the most likely culprit is either that some small number of users are doing something sneaky, or there is a bug somewhere.

    I’m curious if anyone has seen this issue before, or knows what might be causing it.

    Edit:
    Solved – the problem was due to the string encoding on iOS side of things. Needed to enforce a utf8 encoding for all urls.

  • Geolocation of Client with Django

    My first thoughts yesterday when I started trying to add a lookup for a user’s country based on IP address was that this was going to be tricky. I figured I would have to create some models, fill them with data fixtures and do some manual queries against the database.

    Turns out it was fairly trivial to do.

    Django comes with some handy modules for doing it all for you. It just requires installing a C library from MaxMind and downloading their free Country data file.

    To install the GeoIP MaxMind C Lib on Mac I used homebrew

    brew install geoip

    on the server I had to do the same thing on Linux:

    sudo yum install geoip

    Then I downloaded the free country data file from MaxMind and put it in my django project’s ‘geo’ directory:

    $ curl -O http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz
    $ gunzip GeoIP.dat.gz 
    $ mv GeoIP.dat /geo/

    To finish the setup I needed to add a line to the settings.py file:

    import os
    PROJECT_ROOT = os.path.dirname(__file__)
    GEOIP_PATH = os.path.join(PROJECT_ROOT, 'geo')
    

    Getting the country of a connecting user was then rather simple.

    from django.contrib.gis.utils import GeoIP
    g = GeoIP()
    country = g.country_code(request.META['REMOTE_ADDR'])
    

    For the complete documentation on GeoIP check out the official documentation.

  • Cross Promotion Analytics

    Earlier this week I was on a webinar.

    I wasn’t expecting to get much out of it. But figured there might be one or two nuggets in there to help out with my iPhone business.

    Turns out I had a eye opening experience and got several ideas for how to take my business to the next level.

    I never slept that night.

    This weekend I’m getting heavy into development of my server infrastructure to help scale up my ability to cross promote all my apps vastly more than I do right now.

    It all comes down to dynamically generating the links to other apps and automating choice of them depending on historical performance of click throughs.  Once the entire system is finished I will be able to correlate performance on several key indicators and generate pages that should be optimal.

    The math involved will be interesting to figure out.  The stats collected will provide me with a lot of information about the performance of my apps.  It’s going to be fun to figure out how to get a good dashboard to measure the status of my user engagement in realtime.

    Super psyched to get some new apps out with these new features.

     

  • Setting up a Mac for Django Development

    I usually use Linux for doing python and django development.   However last night my Linux PC choked up yet again due to bad video drivers and I was forced to do a hard reboot.

    That was the final straw that made me switch over to using my Mac for most of my development work going forward.

    I keep my current projects in Dropbox so that they are always up to date across all the computers I use day to day.  So there was nothing to do to get those files migrated over to the Mac.

    My python and django development environment is pretty light weight. I use:

    • virtualenv
    • vim
    • textmate
    • terminal with zsh
    • mercurial

    I don’t do django stuff in an IDE.  I find them a bit too heavy for coding.  Instead I opt for using either Vim or TextMate.  Very simple, text editing with little clutter or UI to get in the way.

    I use the standard Mac Terminal app but I’ve changed the standard bash shell over to zsh using Oh My zsh. Which can be installed with this one line:

    curl -L https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh | sh
    

    Virtualenv is a necessity.  It keeps all the projects I work on isolated so that I can set versions for all the libraries and come back to a project a year later and still have it work immediately.  Setting up virtualenv and virtualenvwrapper on the Mac was fairly easy:

    $ sudo easy_install pip
    $ sudo pip install virtualenv virtualenvwrapper
    $ mkdir ~/.virtualenvs
    $ echo "export WORKON_HOME=$HOME/.virtualenvs" >> ~/.zshrc
    $ echo "source /usr/local/bin/virtualenvwrapper.sh" >> ~/.zshrc
    

    Restart the terminal after that. Now ‘workon’ and ‘mkvirtualenv’ will be available for working on and creating virtualenv python environments.

    Mercurial is what I use to version control all my projects. I just find it makes more sense than git and the command line is much simpler and cleaner.

    That’s pretty much it.

  • Creating Platforms

    Creating a really great piece of software is a lot of work.  Yet no matter how great it is it will not appeal to everyone.  Take a look at the hugely successful Tiny Tower game for iPhone.  The game mechanics are solid but the 8 bit graphics may turn some people away.

    One of the key benefits to the Freemium model is that players can pay as much or as little as they like.  I believe that same sort of flexibility needs to work it’s way into game play.

    Take a look at Angry Birds.  It was not the first game of it’s type available but it managed to be the most successful because of the delicate balance between being too easy and too difficult.  It always feels like you finish the level just as you are on the edge of giving up.  It’s not so hard that you give up, and it’s not so easy that you get bored.  That balance is what makes the game fun.  Rovio must have either been very lucky or done a lot of fine tuning to get the game play just right.

    Platforms allow me as a developer to work on the hard stuff (software) once and have it appeal to the most number of people possible.  Thinking from the start about making my software a platform means that I try to make it easy to swap out graphics or make them updatable from the web.  It also encourages me to design things in a way that makes it easy to adjust game dynamics easily.

    I’ve done a number of apps now that sit far down in the rankings.  Not because they’re bad but because they appeal to only a small niche of people.  These apps will never hit mass market appeal and will probably never make more than $2/day.  The only way to make a livable income from such apps is to develop a platform flexible enough to allow me to spin off a bunch of variants with very little extra work.

     

  • Importance of Marketing

    There are a number of vital components to any business. You need great people – which is a result of a solid HR process, you need great leadership, a solid vision, and a great product or service. But I believe that perhaps the most important component is the marketing.

    A business can have an excellent product but without the communication to connect that product to someone who wants or needs it the business will never be successful. For that reason I believe every entrepreneur needs to have first hand experience and an understanding of how the marketing and advertising works in their business. Marketing is what brings money into the business to pay the bills and salaries.

    There are a lot of specialized skills and unique experiences necessary to be good at marketing. However, once you become an expert at marketing you’ll never look back. There are two distinct approaches to marketing:

    • Branding
    • Direct-Response

    Unless your company has limitless money to spend on advertising as is the case with companies like Coke, Apple, or Budweiser then Direct response advertising is really the only thing you should concern yourself on.

    Direct-response is a measured, scientific approach to advertising where you have the ability to tell if an advertising campaign works. You can test variations of the message, over different media, at different times of the year and see the effects of those changes. It becomes easy to know if money spent on advertising results in sales and profit.

    For this reason many advertising platforms would actually prefer you didn’t use direct response marketing.

    In Yahoos hey day they made a boat load of money from banner ads. They would fly some sales guy to New York to meet with some of the biggest advertising firms and tell them how much more eyeballs would see their ad on yahoo.com compared to a billboard sign on the highway. They would sell millions of dollars in ad spaces to big companies with deep pockets to run branding campaigns. And because it wasn’t easy to measure the impact of those ads in terms of new sales Yahoo could continue to suck money out of them. Yahoo didn’t want the advertisers to be able to figure out that the value of those eyeballs was much less that what the companies were paying for. This eventually led to a small collapse in the online advertising space as many companies eventually figured out that they were not getting results.

    The Yellow Pages have been having a similar problem. For anyone who has ever tried to place a direct-response type ad in the yellow pages can tell you, they try very hard to convince you that it’s not a good idea. There’s a good reason for that. If advertisers could measure the performance of a yellow pages ad then they would probably find out that they’re overspending on it and cancel.

    There is a quote from Galileo, who said ‘Count what is countable, measure what is measurable. What is not measurable, make measurable‘. I believe that all aspects of business success revolve around measuring and counting the impact of what you do – including marketing.

    I have personally read countless marketing books. They are often the most insightful and inspiring books I read. Here’s a short reading list of my favorites which I think ALL entrepreneurs NEED to read:

    • Tested Advertising Methods – This is probably the penultimate book by John Caples which is referenced by nearly every marketer. It will convince you of the importance of the testing of advertising methods and is a great place to start.
    • My Life in Advertising and Scientific Advertising – This is another classic book by Claude Hopkins which belongs on the shelf of every marketing professional, entrepreneur or CEO.
    • Influence: The Psychology of Persuasion – This is the seminal book about the psychological triggers that make people want to buy. There are seven and each will make a dramatic impact on the effectiveness of your marketing.

    The importance of marketing to the success of your business cannot be understated. It will mean the difference between your product or service making money or failing miserably. Selling everything from iPhone games to houses benefit from good marketing. Give yourself a great head start by picking up the three books I mentioned above and continue to be a student of marketing throughout your business career.

  • One Week into Sauerkraut Diet

    It has been 7 days since I picked up 2L of sauerkraut at Costco and thought the results so far have been interesting enough to make a post about.

    I have a morning ritual. Every morning I weigh myself – after using the washroom, before eating or getting dressed for consistency. Since January I have been tracking this daily in a spreadsheet and charting it.

    Over the last week I have recorded the most consistant and dramatic weight-loss since I started tracking. Losing 6.5lbs. in 7 days and taking me to my lowest weight in about 1 year.

    To be clear though. the sauerkraut is really just the hook to make it seem interesting. The reality is that I’m keeping my daily carb intake below 25g (which is really hard to do) in order to get myself into ketosis where my calories are sourced from body fat rather than food.

    What have I been eating then?

    Breakfast: about 2/3 cup of sauerkraut

    Morning: 2 cups of coffee

    Lunch: 65g of Salted Peanuts (anything other than plain/salted/bbq peanuts has too many carbs)

    Supper: Meat + salad (very little dressing) or lower carb vegetables. ( no potato, beans, rice etc )

    If I’m feeling a bit hungry I’ll have few more peanuts, and if my carbs have been particularly low for the day I’ll allow myself one small indulgence (glass of red wine, beer, handful of chips). Note that it’s not about restricting calories or starving myself. I have been having larger portions of meat for supper and as much salad vegetables as I can eat. If I was more organized I would add a salad to lunch, but the supermarket is too far from the office and peanuts are just about the only thing at the corner store with less than 10g of carbs.

    This kind of diet is obviously not sustainable, but it is perfectly healthy for short 1-2 week duration and actually something that we’re fairly well adapted to do.