Ian Lewis
Ian Lewis is a web developer living in Tokyo Japan. His current interests are in Django, python, alternative databases and rapid web application development. About Me...
  • How to be a 10x programmer

    I recently read a blog post that is a satirical look at how to gain a reputation as a guru programmer by converting code to your own code and making it hard for other programmers to get their work done. It's called 3 Simple Rules That Will Make You a ‘Superstar’ Developer and it's very tongue in cheek.

    It outlines 3 simple rules to be a superstar programmer.

    Rule 1: Write lots of code. i.e. Rewrite large amounts of the codebase to your own code since you will be more productive fixing bugs and others will have a harder time.

    Rule 2: Write your code quickly. Get things done fast. Don't worry about introducing bugs that are hard to find, but don't introduce trivial ones.

    Rule 3: Don’t take time to document your code. It takes time and others will be able to understand your code better.

    This might actually work well in medium/large companies with closed systems. This strategy would work great at my first job out of college. If no one could touch my code but me, I would be king.

    This kind of thing is exactly why open source is so great. In open source this strategy doesn't work because the success of the project depends on how many other developers you can get to work on it. And your reputation depends on the cleanliness of the code base.

    So I'd like to propose how to actually make yourself a 10x developer.

    1. Get out of your current job. If you have a job anything like the above. Get out and get out as fast as possible. You are wasting time spending most of your day in an environment that will not allow you to grow. Get out. I can't stress this enough. Environment is VERY important.
    2. Read lots of code. Preferably other people's code of good reputation. You need to read lots of good code to understand how to write good code. It's that simple. Understand why a particular implementation is convenient or fast and why other's are slow or not as convenient for the problem that is being solved.
    3. Read lots of documentation, blogs, articles and stay on top of emerging trends. Understand what other developers are talking about and why. Your options are so much broader when you know what other projects to look at and what to research when presented with a hard problem.
    4. Write lots of code and work hard. Everything takes practice and writing code is no exception. Knowing in your brain how to write code is not the same as doing it. I know how to hit a baseball but that doesn't mean I CAN ACTUALLY hit it, for real, let alone hit a homerun. Write a lot and preferably public code. You won't get much of a reputation with closed products unless you did most of the work on a product that is widely used and that is publicly known.
    5. Don't complain when things don't work. If something doesn't work it's likely your code that's causing it. Even if you think it's not and complain when something's not working it's very embarrassing when it turns out that it was your code that was the problem that you have been complaining about all day. You won't make friends by complaining.
    6. Go to programming events and conferences. Events with other programmers is very rewarding. A big problem with working hard is it's hard to stay motivated. Other programmers commenting on work you did can be very motivational and give you lots of ideas. Also, other programmers can be introduced to you and your work and you can get a feel for what other people are using to solve problems. Don't assume someone doesn't know what they are doing. Many times they surprise you with something you didn't know about.

    Ok, that's 6 things. Notice that only one is writing code though you'll need to do that a lot. On a typical day I probably spend about 40% writing and 60% reading. Knowing a lot about other projects, ways of writing code, algorithms, and programming methodology will help you a lot (though not right away). Learning programming is a lot like learning another language (which I also have some experience with), there is a large sunk cost and it takes a lot of time to get to a level of fluency.

    That's it. Let me know if you have any comments!

    Send feedback   このエントリーを含むはてなブックマーク はてなブックマーク - How to be a 10x programmer
  • Unreadable

    What is it about some C programmers that makes them write code that looks like this:

    if(len<16) {
      for(k=start;k<start+len;k+=j) {
        j=1;x=V[I[k]+h];
        for(i=1;k+i<start+len;i++) {
          if(V[I[k+i]+h]<x) {
            x=V[I[k+i]+h];
            j=0;
          };
          if(V[I[k+i]+h]==x) {
            tmp=I[k+j];I[k+j]=I[k+i];I[k+i]=tmp;
            j++;
          };
        };
        for(i=0;i<j;i++) V[I[k+i]]=k+j-1;
        if(j==1) I[k]=-1;
      };
      return;
    };
    Send feedback   このエントリーを含むはてなブックマーク はてなブックマーク - Unreadable
  • Introduction to Algorithms

    Today my copy of Introduction to Algorithms came in the mail (a gift from the family). I've decided, mostly inspired by Peteris Krumins to revisit classic algorithms as it's been a while since I've taken a look at them.

    I have decided to also take a look at the MIT Intro to Algorithms course in order to revisit algorithms and concepts. I won't provide any lecture notes or anything since Peteris did a much better job of of writing lecture notes that I ever could but I did go ahead and create some python implementations of the sorting algorithms covered in the first lecture. These haven't been tested extensively so there might be bugs but I'm pretty sure they're working. I'd be interested to see how well these work with large input data, particularly the merge sort.

    insertion-sort.py

    #!/usr/bin/env python

    def sort(array):
      for j in xrange(1, len(array)):
        i = j - 1
        key = array[j]
        while i >= 0 and key < array[i]:
          array[i+1] = array[i]
          i = i - 1
        array[i+1] = key
      return array

    merge-sort.py

    #!/usr/bin/env python

    def sort(array):
      mergesort(array, 0, len(array))
     
    def mergesort(array, start, end):
      if end > start + 1:
        pivot = (start + end) / 2
        mergesort(array, start, pivot)
        mergesort(array, pivot, end)
        merge(array, start, pivot, end)
     
    def merge(array, start, pivot, end):
      l = array[start:pivot]
      lenl = pivot - start
      r = array[pivot:end]
      lenr = end - pivot
      i = j = 0
      for k in xrange(start,end):
        if j >= lenr or (i < lenl and l[i] <= r[j]):
          array[k] = l[i]
          i += 1
        else:
          array[k] = r[j]
          j += 1
    Send feedback   このエントリーを含むはてなブックマーク はてなブックマーク - Introduction to Algorithms
  • Google Analytics for Mobile Sites

    I implemented tracking using Google Analytics for my company's mobile sites using a technique described by Peter van der Graff on his site. The technique involves performing a GET to to an image on Google's server and passing it a bunch of options. Incidentally this is because Javascript can perform gets of images but not gets for any other kinds of content (as an aside, this kind of protection seems usless since the server could return any kind of content in wants to the javascript even though the GET has an image in the url. Maybe someone could enlighten me).

    Peter originally came up with the idea because he wanted to track hits to a RSS xml url (which also seemed strange to me since the rss aggregator could read it as many times as it wants and doesn't give much insight into the number of readers, but I digress), or to another type of file download (image, pdf, etc) which wouldn't trigger the javascript that Google uses for Analytics.

    One important difference between his motives and mine were that I'm tracking hits to a mobile site. Doing analytics on the server side are important since most phones (in Japan at least) don't support javascript. I also, because of the differences in what I was doing, needed to make some changes to how his script worked. Since I'm not tracking downloads or rss hits, I care about things like sessions, language, and user agent (why Peter didn't also care about this I'm not sure).

    So I modified his code as follows. I forward the language and user agent of the client to Google Analytics so that I can track these things properly. I also pass my own cookie number so that Google Analytics can aggregate page hits from the same user into a session. I also make use of the user var to track hits to different customer's web pages. The example is in PHP but it could be easily translated into another language.

    Note that, because of the use of stream contexts, this code will require a version of PHP >= 4.3.0.

    $var_utmac=MOBILE_GOOGLE_ANALYTICS_CODE; //enter the new urchin code
    $var_utmhn=WEB_DOMAIN; //enter your domain
    $var_utmn=rand(1000000000,9999999999);//random request number
    $var_cookie=$session; //cookie number
    $var_random=rand(1000000000,2147483647); //number under 2147483647
    $var_today=time(); //today
    $var_referer=$_SERVER['HTTP_REFERER']; //referer url
    $var_uservar=$storeinfo['storeid']; //enter your own user defined variable
    $var_utmp=$_SERVER['REQUEST_URI']; // request uri

    $urchinUrl='http://www.google-analytics.com/__utm.gif?utmwv=1&utmn='.$var_utmn.'&utmsr=-&utmsc=-&utmul=-&utmje=0&utmfl=-&utmdt=-&utmhn='.$var_utmhn.'&utmr='.$var_referer.'&utmp='.$var_utmp.'&utmac='.$var_utmac.'&utmcc=__utma%3D'.$var_cookie.'.'.$var_random.'.'.$var_today.'.'.$var_today.'.'.$var_today.'.2%3B%2B__utmb%3D'.$var_cookie.'%3B%2B__utmc%3D'.$var_cookie.'%3B%2B__utmz%3D'.$var_cookie.'.'.$var_today.'.2.2.utmccn%3D(direct)%7Cutmcsr%3D(direct)%7Cutmcmd%3D(none)%3B%2B__utmv%3D'.$var_cookie.'.'.$var_uservar.'%3B';

    $header = '';

    //Set the language to that of the client so analytics can track it.
    if (!empty($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
      $header = 'Accept-language: '.$_SERVER['HTTP_ACCEPT_LANGUAGE'].'\r\n';
    }
    //Set the user agent to that of the client so analytics can track it.
    if (!empty($_SERVER['HTTP_USER_AGENT'])) {
      $header = 'User-Agent: '.$_SERVER['HTTP_USER_AGENT'].'\r\n';
    }

    $opts = array(
      'http'=>array(
        'method'=>'GET',
        'header'=>$header
      )
    );

    $handle = fopen($urchinUrl, 'r', false, stream_context_create($opts));
    $test = fgets($handle);
    fclose($handle);
    Send feedback   このエントリーを含むはてなブックマーク はてなブックマーク - Google Analytics for Mobile Sites
  • Gnucash 2.2.3

    Gnucash 2.2.3 was released the other day and contains my first contribution to the project. Albiet, a pretty small and lame patch for a small bugfix, but a patch nonetheless!! I hope to do some more work particularly on the QIF import, eventually making it work with the generic importer, and then expand my contributions to include improvements for multi-currency and reporting.
    Send feedback   このエントリーを含むはてなブックマーク はてなブックマーク - Gnucash 2.2.3
  • MochiKit does makes java suck less

    So the last few days I've been playing around with MochiKit and working with Javascript. Until now I have done some Javascript here and there but not too much. MochiKit seems to make it a lot easier by providing you with lots of useful functions for things you do often. In fact it's so popular that I have a hard time explaining to myself why I hadn't tried to use it up until now. I'm certainly not on the bleeding edge here.

    Anyway, like I said, MochiKit makes JavaScript less painful. I have a little mockup for a page that defers going to the server until the user has stopped entering data for 3 seconds. That cuts down on a lot of back and forth between the server and client. It's easy in MochiKit. Just use the callLater function.

    update: function() {
      if (this.deferred) {
        this.deferred.cancel();
        log('Previous deferred cancelled.');
      }
     
      if (this.request) {
        this.request.cancel();
       log('Previous request cancelled.');
      }
     
      log('updated');
      this.deferred = callLater(3.0, bind(this.deferredupdate, this));
    }

    In this example the callLater is used to call another function, deferredupdate, after 3 seconds. However, if the user enters data a second time before the three seconds are up then the deferred object will be cancelled and a new deferred object will be created. This has the effect of not calling the update function until a user is really done entering data.

    The request object is created in the deferredupdate function.

    deferredupdate: function() {
      log('Loading document');
      this.deferred = null;
     
      this.request = loadJSONDoc('domains.json');
      this.request.addCallback(bind(this.pageupdate, this));
    }

    The deferredupdate function calls loadJSONDoc which creates a deferred object as well however this deferred object doesn't wait for any time it simply does it's work in a separate thread and executes a callback when it's done. In this case I set the callback to be the pageupdate function. The pageupdate function does the work of putting the resulting data into a table and adding that table to the html DOM.

    If you are wondering what the bind function does, it always ensures that the 'this' reference works. I'll leave the full explanation for another post.

    Most people who program in JavaScript already know about MochiKit but if you are interested in it check out the screencast at http://www.mochikit.com/

    Send feedback   このエントリーを含むはてなブックマーク はてなブックマーク - MochiKit does makes java suck less
  • Internet Explorer is CRAP!! [CSS Edition]

    In the same vein as my first post bashing Internet Explorer I wanted to point out a few CSS bugs/unsupported features that are notable in Internet Explorer. For those who are not familiar, CSS is a stylesheet language which helps you to layout your forms. It's used on basically every major website on the internet. But Internet Explorer, even though it is the most widely used browser, does not support many of the features of CSS and when it does, sometimes the layout appears differently than in other browsers because Internet Explorer doesn't follow the rules for how the CSS should work. This post will cover those issues where Internet Explorer simply doesn't work at all.

    PNG Transparency

    The first issue affects this website and actually causes the CSS used by this site at the time of this writing to be non-standard (shh!! don't tell anyone! I'll fix it sooner or later). That issue is that Internet Explorer doesn't support PNG transparency. PNG files have in them a transparency level which allows translucent images. When you click on an image on this site like below it pops up an image and the background is darkened by another translucent png image. This doesn't normally work in Internet Explorer.

    Thumbnail

    Normally you should be able to just set the background image like the following and the png will be displayed with it's inherent transparency.

    #overlay{ background-image: url(overlay.png); }

    But Internet Explorer displays it as completely opaque.

    Internet Explorer CSS Bug

    Instead, for Internet Explorer's sake you have to do some wierd hack that is Internet Explorer friendly.

    * html #overlay{
      background-color: #333;<;br />;  back\ground-color: transparent;
      background-image: url(blank.gif);
      filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='plugins/lightbox_plugin/overlay.png', sizingMethod='scale');
    }

    Notice the wierd call to some Microsoft method for displaying images with alpha. This is totally non-standard and broken but necessary in Internet Explorer to display a png with transparency (there are other ways to achieve the desired effect in javascript however).

    Button Hover

    The second issue is that Internet Explorer doesn't support the button:hover attribute in CSS. Normally you can make a particular piece of a page such as a link or button behave differently if you add the "hover" attribute to it in CSS. This has been used a lot with normal links. Indeed this site uses a:hover to show different color links when you hover over them. Try it. The link goes nowhere but you can see that it changes when you hover over it. The same should be true for buttons. You should be able to change a buttons properties when the user hovers over it using only CSS.

    button:hover {
    /*Your CSS here */
    }

    In fact you can use this hover effect with pretty much anything, such as table cells and rows. However IE only recognises the hover for links so it requires javascript. Check out this test page. Hovering over the button does nothing in IE. In order replicate this functionality in Internet Explorer you have to write some wierd javascript that sets the behavior of the button when the page is loaded. There are a number of ways to do this but the most straitforward is to use the whatever:hover script so you can make use of the hover attribute in css. It has some important limitations however so be sure to read the limitations section. Essentially the scripts adds a onMouseOver and onMouseOut events to the button which change it's stylesheet class.

    Both of these problems have added difficulty to my life. The first stemming from this website and the second stemming from work. While web browsers have become a quite complicated piece of software, time spent fixing bugs because of broken implementations of standards is a huge waste of time. This is somewhat true for Safari and Firefox but especially true for Internet Explorer. No argument could counter that it is a steaming pile of dung and that you shouldn't use it. PLEASE STOP. The world will be a better place if you do.

    Send feedback   このエントリーを含むはてなブックマーク はてなブックマーク - Internet Explorer is CRAP!! [CSS Edition]
  • MDB2 transaction bug

    There is currently a bug in the current stable release of MDB2 (2.4.1) that breaks transaction support with MySQL databases. It seems to occur anytime the server cababilities are checked twice (This basically means that it occurs when creating multiple connections to the database).

    After running into this bug I took a dive into the code for MDB2 and found that was caused by the use of a static variable that is used to determine if the capabilites were already checked or not, including whether transactions are supported or not. Basically you make one connection to the database and everything is fine, it checks the capabilities and finds that transactions are supported and sets a class member variable indicating this. However, when making the second connection, the server capabilities are checked in the new object. The member variable of the new object that specifies if transactions are supported defaults to false, but the function that actually checks the capabilities checks the static variable to see if they were already checked and skips checking again leaving the new connection object with transaction support set to false.

    Seems like a silly oversight to me, but one that caused me a headache for a couple hours. I looked to see if I needed to submit a bug report and/or patch but it seems that someone has already done so. The change should be in the next stable version but I need to patch my currently running servers so that transaction support is enabled in the mean time.

    Send feedback   このエントリーを含むはてなブックマーク はてなブックマーク - MDB2 transaction bug
  • Internet Explorer is CRAP!!

    Basically the title says it all. Since I started doing web development I've lost count of the number of bugs that I've found in Internet Explorer but I want to highlight a couple that were especially annoying to me.

    1.) The <button> tag doesn't work. The button tag has a value attribute which is supposed to be sent as the value of the post when I submit a form but it's not. The display value of the button is sent instead. So if you have a form like so:

    <button name='time' value='1030'>Click here</button>

    and you submit the form that the button is contained in, the post value of time is set to "Click here" instead of "1030" like it's supposed to. Basically in IE you can't have a button submit a form and post a value different from the displayed value. This makes it very hard to have an array of buttons and post a different value based on what button you push.

    2.) For e-mail links that contain Japanese characters you have to change the characters to the %0000; equivalent value. So if you have a mailto with a subject line in Japanese you can't write:

    <a href='mailto:myperson@mymail.com?subject=おはようございます'>e-mail me</a>

    and expect it to work. Internet Explorer simply does nothing. No error message. No e-mail client. You have to url encode the link to something look something like:

    <a href='mailto:myperson@mymail.com?subject=%E3%81%8A%E3%81%AF%E3%82%88%E3%81%86%E3%81%94%E3%81%96%E3%81%84%E3%81%BE%E3%81%99%26'>e-mail me</a>

    which if you are using php is not so bad since you just call urlencode() but it's just plain annoying to get stuff like this to work when there isn't really a good reason why you need to encode it (at least I haven't heard one so far).

    That's just the 2 most annoying bugs/issues. I can't imagine how the button bug got though the testing phase for IE but probably there are too many applications that depend on the bug working as is for Microsoft to ever change it to work the way it's supposed to. :sigh:

    I realize I shouldn't hold my breath, but the sooner everyone stops using IE the better.

    Send feedback   このエントリーを含むはてなブックマーク はてなブックマーク - Internet Explorer is CRAP!!
  • Returning Arrays in WSDL

    This week I've been working on setting up several web service for a project I'm working on for work. Because we are creating these web services from scratch we had to start by creating a WSDL file to describe the web service and it's functions.

    WSDL is a type of xml document that describes the inputs and outputs from a web service. This can be done using a number of ways but in my case I'm using SOAP so I described my inputs and outputs using XML Schema.

    In learning about WSDL I found a number of documents helpful. Forthought Inc.'s Uche Ogbuji always seems to write good articles and Using WSDL in SOAP applications no exception. Also, examining existing documents that are publicly available was also a big help. Such as this example Stock Quote web service. Or the Google SOAP web service definition.

    Though after reading all of those, while returning base types like int or string or even custom objects was easy to define, I had a hard time figuring out how to define how to return arrays of objects (Actually, Google's WSDL shows an example of what I'm about to describe).

    I originally thought that returning a list of objects would simply involve returning more than one of the object. Like if I defined this in my types section:

    <types>
      <xsd:complexType name='StaffList'>
        <xsd:element
          minOccurs='0'
          maxOccurs='unbounded'
          name='staffname'
          type='Staff'/>
      </xsd:complexType>
      <xsd:complexType name='Staff'>
        <xsd:all>
          <xsd:element
            minOccurs='0'
            maxOccurs='1'
            name='staffname'
            type='xsd:string'/>
          <xsd:element
            minOccurs='0'
            maxOccurs='1'
            name='staffposition'
            type='xsd:string'/>
          <xsd:element
            minOccurs='0'
            maxOccurs='1'
            name='salary'
            type='xsd:int'/>
        </xsd:all>
      </xsd:complexType>
    </types>

    for reference this is my message definition:

    <message name='GetStaffRequest'>
      <part name='sessionid' type='xsd:string'/>
      <part name='staffid' type='xsd:int'/>
    </message>
    <message name='GetStaffResponse'>
      <part name='Result' type='StaffList'/>
    </message>

    That's a perfectly fine piece of XML Schema but unfortunately web services clients and servers won't recognize it. Instead you need to put a restriction on your returned type to define the array you are returning as a http://schemas.xmlsoap.org/soap/encoding/:Array. Sounds hard but it is really just a matter of following the pattern below instead of what I did above.

    <xsd:complexType name='StaffList'>
      <xsd:complexContent mixed='false'>
        <xsd:restriction base='soapenc:Array'>
          <xsd:attribute wsdl:arrayType='Staff[]' ref='soapenc:arrayType' />
        </xsd:restriction>
      </xsd:complexContent>
    </xsd:complexType>
    <xsd:complexType name='Staff'>
      <xsd:all>
        <xsd:element
          minOccurs='0'
          maxOccurs='1'
          name='staffname'
          type='xsd:string'/>
        <xsd:element
          minOccurs='0'
          maxOccurs='1'
          name='staffposition'
          type='xsd:string'/>
        <xsd:element
          minOccurs='0'
          maxOccurs='1'
          name='salary'
          type='xsd:int'/>
      </xsd:all>
    </xsd:complexType>

    The message definition doesn't need to change from above. After doing that your favorite web services client or server that supports WSDL should recognise that what you are returning is an array type properly.

    Send feedback   このエントリーを含むはてなブックマーク はてなブックマーク - Returning Arrays in WSDL