1. Today’s lesson: be VERY careful with programmatic use of contribute_to_class(). It doesn’t overwrite existing fields of the same name, resulting in intriguing errors when the ORM tries to do a SELECT query containing the same columns hundreds of times over…

  2. Finally solved a long-standing problem getting Icelandic characters to work properly in files being downloaded onto Windows machines for use as SPSS syntax. Turns out the solution is to explicitly set the download charset to UTF-8, and to prepend an unnecessary BOM (yuk) to the beginning of the file as so (context: Django view):

    import codecs
    
    def export_spss(request):
        response = HttpResponse(export_spss(), status=200, mimetype="application/x-spss; charset=utf-8")
        response['Content-Disposition'] = 'attachment; filename=syntax.sps'
        response.content = codecs.BOM_UTF8 + response.content
        return response

    Why is a BOM, which should be completely unnecessary in a UTF-8 file (it has no variable byte order after all) apparently required by some Windows software in order to tell it that the file is UTF-8 encoded, despite Unicode mode being on? Sigh.

  3. IE doesn’t upload csv files with text/* media type. Content-type cannot be trusted, the only way of telling if data is of a particular type is to see if it parses successfully.

  4. Today in “things I have typed instead of import”: imprto, improt, implore

    I actually quite like how implore pandas looks in my code.

  5. I’m getting too used to (puredata.info) — I just right-clicked a python class and expected a hypermedia “help” option with params, example usage etc.

    Jetbrains PyCharm does have an inline documentation feature, which (when invoked via a complex keyboard “shortcut”), produces this gem:

    Even when this feature does work, it shows code “documentation” in a monospace font, typically with no usage example or links to other relevant documentation, as is standard in puredata.

    Our tools are inadequate.

    Update: added puredata documentation for comparison:

    In case it’s not clear from the screenshot, that usage example is live code — it can be interacted with, changed, copied and pasted, played with, experimented with. We typically can’t do that with existing text-based code, let alone mere usage examples.

    More thoughts I want to add to this, but I will write them up as a full article.

  6. My first puredata patch: Canoner! A cross between a delay and a looper, this patch allows you to play canons solo.

    Hit Start/Round as you start playing, then again at a round point, and the patch will continue to play what you played with that delay until you hit Stop.

    Extending the canoner to support n>2 part canons is left as an exercise for the reader.

    Patch code:

    #N canvas 405 217 363 240 10;
    #X obj 26 34 tgl 40 0 empty empty empty 17 7 0 10 -204786 -1 -1 0 1
    ;
    #X obj 26 84 route 1 0;
    #X obj 214 201 delwrite~ round 10000;
    #X obj 214 176 adc~;
    #X obj 26 117 timer;
    #X obj 26 148 delread~ round;
    #X obj 26 198 dac~;
    #X floatatom 165 149 5 0 0 0 - - -;
    #X floatatom 129 149 5 0 0 0 - - -;
    #X obj 26 174 *~ 0;
    #X obj 101 34 bng 40 250 50 0 empty empty empty 17 7 0 10 -260097 -1
    -1;
    #X text 13 15 Start/Round;
    #X text 106 14 Stop;
    #X text 249 176 Input Stage;
    #X connect 0 0 1 0;
    #X connect 1 0 4 0;
    #X connect 1 1 4 1;
    #X connect 1 1 8 0;
    #X connect 3 0 2 0;
    #X connect 4 0 5 0;
    #X connect 5 0 9 0;
    #X connect 7 0 9 1;
    #X connect 8 0 9 1;
    #X connect 9 0 6 0;
    #X connect 9 0 6 1;
    #X connect 10 0 7 0;
    

  7. There’s something incredibly satisfying, if a little masochistic, about poring over PIC datasheets and manpages, and tinkering with low-level code you only half understand, when it all actually works and you get two devices to talk to each other (in this case a PIC16F886 and a Raspberry Pi, via I2C)

  8. Javascript has no real Set or Dictionary implementation, which for someone spoiled by python’s set and dicts is rather frustrating. However, in leiu of the poorly supported js Set type, plain old objects can be massaged into acting as both sets and dicts:

    
    // Python: d = dict()
    var d = {};
    
    // d['key'] = 'value'
    d['key'] = 'value';
    
    // d.get('nonexistent', 'fallback')
    d.hasOwnProperty('nonexistent') ? d['nonexistent'] : 'fallback';
    
    // d.keys()
    Object.keys(d);
    
    // s = set()
    var s = {};
    
    // s.add(1)
    s[1] = true;
    
    // 1 in s
    s.hasOwnProperty(1);
    
    // Accessing all values in set:
    Object.keys(s);
    

    Notes: the in operator can be used to test membership, but will incorrectly return true for __proto__, as well as all properties up the prototype chain, i.e. all properties and methods of Object. hasOwnProperty is much safer to use.

    Similarly, the use of the ternary operator for get-item-with-fallback could in theory be replaced with d['item'] || 'fallback', unless of course the value stored was falsey, in which case the or will incorrectly return a truthier fallback.

  9. Slowly getting a PuSH subscription service working. It should be fairly easy to turn it, once finished, into a layered library so people can either bolt it onto a Silex/Symfony app and have it all just work, or use the lower level client and logic in other frameworks.

  10. Considering the possibility that preferring to use spaces over tabs for code indentation is indicative of excess complacency with the status quo of using complex text formats to express behaviour, and of the viewpoint that code is a static, inflexible material (think raster images vs vector)

  11. When using to send content-disposition: attachment responses, you MUST explicitly set the response encoding (charset) otherwise windows will assume the response is in whatever-weird-encoding-windows-uses, rather than UTF-8 (you are using UTF-8, aren’t you?).

    CSV example code:

    response = HttpResponse(utf_8_encoded_csv_text, status=200, mimetype="text/csv; charset=utf-8")
    response['Content-Disposition'] = 'attachment; filename=data.csv'
    

    It seems that some weird old applications like SPSS need a BOM in there as well, even though UTF-8 doesn’t have a BOM. Add that like this

    response.content = '\xef\xbb\xbf' + response.content
    

    before sending the response

    return response
    
  12. Emil Björklund: #PHP folks: when fetching from an API, would it be wise to use function_exists to check for cURL, and else fall back to file_get_contents()?

    @thatEmil that should work fine — one thing to bear in mind is that by default they both treat redirects differently. IIRC, cURL doesn’t follow redirects by default whereas file_get_contents will.

  13. New in this version of :

    • Improved styling (still WIP, as always)
    • stream on homepage, currently just notes but will add other things too
    • content creation/editing UIs publicly viewable (take a peek!)
    • profile photo as the icon
    • complete code restructure, now using silex for HTTP routing
    • removed tonnes of nonsense framework code, replaced with small number of ≈200 line functional libraries. Clearer, easier to navigate and much more fun to work with
    • no more SQL databases — content is indexed using a custom built 209 LOC CSV index which is surprisingly speedy, and suits my needs perfectly
    • no more support for rendering content in many forms using content negotiation (HTML, JSON, ATOM etc.) — now only HTML+microformats2 representations of content are given
    • ATOM feed shimmed with microformats2 to ATOM converter
    • Pingbacks no longer natively accepted (though they are sent), using webmention.io to shim them into webmentions for easier handling

    The local maximum has been overcome, for now. There is still much to do.