Co[de]mmunications

Programming and ramblings on software engineering.

Python Functors

The task is to multiply items in some iterable by three.

multipled = [3 * s for s in series]

One list comprehension later, the task is complete.

Next, we find out that we need to count how many multiplications are performed. len() is forbidden, because we are dealing with iterators (and inevitably the itertools module). One solution is to create a CallCounting class that wraps callables.

class CallCounting(object):

    def __init__(self, func):
        self.count = 0
        self.func = func

    def __call__(self, *args, **kwargs):
        self.count += 1
        return self.func(*args, **kwargs)

timesthree = CallCounting(lambda x: 3 * x)
multipled = [timesthree(n) for n in series]

print "%d calls" % timesthree.count

This is efficient as well as readable. The main action is to multiply items. We keep a call count just for bookkeeping. Compare with

calls = 0
multipled = []
for n in series:
    calls += 1
    multipled.append(3 * n)

print "%d calls" % calls

that is both ugly and inefficient.

Readable Logic

Compare

if (!device || !this.launched) {
    abort();
}
else {
    run();
}

with

if (device && this.launched) {
    run();
}
else {
    abort();
}

Chances are, you are wired to parse the second version faster. Make it a habit to see if your code’s readability can be improved by avoiding negations.

Nesting can also improve readability.

if (a) {
    doFirstThing();
}
if (a && b) {
    doSecondThing();
}
if (!a && b) {
    doThirdThing();
}

versus

if (a) {
    doFirstThing();
    if (b) {
        doSecondThing();
    }
}
else {
    if (b) {
        doThirdThing();
    }
}

The best logic of all is no logic. Compare

if (person.isChild) {
    run();
}
else if (person.isBaby) {
    crawl();
}
else if (person.isSenior) {
    sit();
}
else {
    walk();
}

with a data-driven approach

var groupAction = {
    children: run,
    babies: crawl,
    seniors: sit
}

var action = groupAction[person.group] || walk;
action();

It’s a Time Zone Change in Shanghai

See this page for details of 1927 in Shanghai. Basically at midnight at the end of 1927, the clocks went back 5 minutes and 52 seconds. So “1927-12-31 23:54:08” actually happened twice, and it looks like Java is parsing it as the later possibly instant for that local date/time - hence the difference.

Just another episode in the often weird and wonderful world of time zones.

Besides illustrating how difficult dealing with time is, this is a textbook example of why estimations really are guesstimations. I am certain that Freewind spent a good deal of time trying to solve this problem before submitting it to Stack Overflow. In any project of considerable size, you run into these road bumps. Even though you know how of a workaround, it is worthwhile to find the root cause and solve problems in a clean manner instead of polluting systems with ad-hoc fixes. Given enough time, any quick-fix will come back to haunt the maintenance programmer.

Incorporating Jammit With Django

Jammit is an asset packaging library for Rails written by the hackers at DocumentCloud (they also brought us Backbone).

It works pretty much out of the box in Django, but a little configuration is needed.

Software Readability

Programs must be written for people to read, and only incidentally for machines to execute.

Abelson & Sussman SICP

Multiple JSONP Requests

Multiple JSONP requests and a single callback can be problematic. I did

window['callback'+idx] = callback;

and then ?jsonp=callback0, ?jsonp=callback1, …

Softwarization

The advantages of doing things in software on a single device are so great that everything that can get turned into software will. So for the next couple years, a good recipe for startups will be to look around you for things that people haven’t realized yet can be made unnecessary by a tablet app.

Development Environment Tips

Other companies may indeed force 45-50 hour work weeks plus weekends, cram them in elbow-to-elbow and give them health plans with a $3,500/year deductible, but it doesn’t mean you can sit pretty with your lead developer grinning and taking it. There’s four things a developer, like any other human being, wants from a job: competitive salary, comfortable environment, challenging work, and a future. If you keep filling vacancies at the top from outside the company, then the bright kids at the bottom will seek work elsewhere even if it pays the same but gives them a sense of having a career path. If you make them work in a closet with 4 other programmers and inadequate ventilation, they’ll bolt for the first place that gives them an office with a window. If you hire a whiz-kid and make him edit Microsoft Access forms in Visual Basic, you won’t see him after a few months. If they find another job that pays more but has longer hours and commute, they will take it because it’ll make them feel like they’re getting paid what they’re worth.

Of course, you could just hire H1B workers exclusively. That’ll last until they get citizenship, or the other country’s economy rises above ours.