Infinite Undo: Falsehoods programmers believe about time

infiniteundo:

Over the past couple of years I have spent a lot of time debugging other engineers’ test code. This was interesting work, occasionally frustrating but always informative. One might not immediately think that test code would have bugs, but of course all code has bugs and tests are no exception.


Agile is a Sham

williamedwardscoder:

thats SCRUM and TDD and all the rest; it is all those new ways of managing development projects and being super-productive and modern and buzzword-compliant; all the sprints, scrums, playing cards nonsense.

The management pitch is that by getting programmers to follow some process rote you will get good, predictable results out.

See, the thing is, the success of the coding-part of a project is dependent on the calibre of the engineers doing that coding and not the process they follow. 

Read More


8-Queen Puzzle Solution

I saw a post over on Reddit recently about an 8-queens puzzle solution in Haskell. I thought it would be a nice way to refresh my brute force recursive solution coding skills so I decided to write it out. The code attempts to find all possible solutions for positioning 8 non-attacking queens on an 8x8 board.

I wrote out the solution in 3 languages, all which correctly find the 92 possible solutions:

Python - run time: 14 minutes Updated: run time: 24 seconds

C - run time: 0.4 seconds

Java - run time: 1.6 seconds

I first chose Python since it’s the easiest thing to write out a solution quickly. It might have been quick to write, but it took a whopping 14 minutes to run! I tried half heartedly to find a decent profiler that would show me what exactly is slowing it down so much (I suspect my cache hash function and Python’s immutable string trouble) but gave up.

Next, I wrote it in C expecting a slight improvement. The run time for this was a mind blowing 0.4 seconds. This despite a mother of a malloc(536870912) call and generally inefficient code.

Just for fun, I decided to see how far Java’s JREs have come along since I first used Java back in the Win95 days (my only recent contact with Java has been on Android and its Dalvik VM). This ran in a decent, unsurprising 1.6 seconds.

Moral of the story: if you want something done fast, do it C

Update: Thanks to a few tips from my friends on Facebook (@jibz and @atharhameed) the Python code now runs in 23 seconds with only 2 lines of code changed.

Loop a YouTube Video

So I got a song stuck in my head and I want it to repeat in a loop while I play Starcraft2. Since I’m too lazy to download a plugin/extension dedicated to something so simple, I wrote this little one-liner which you can paste into Chrome’s Javascript console (Command-Option-J on Mac) while watching a YouTube video that you want to loop:

function utteri(state) { if(state == 0) { document.getElementById('movie_player').playVideo(); } }; $('movie_player').addEventListener("onStateChange", "utteri");

Not quite sure what the Javascript API designers were thinking when they make you pass the callback function as a string containing the name of the function.. I know all those closures in Javascript usually look ugly but I think this is a rather extreme stance at the opposite end of the spectrum :)


Using Git To Manage /etc

Ideally I’d love to put the entire filesystem of the servers I manage under version control, sparing only the user-controlled content (e.g: user home directories and public_html folders), but practically it’s not required.

I use Git to manage the /etc folder on my servers so I know exactly what configuration file was changed when. There’s no particular Git feature that’s required, so any version control system should work. A distributed version control system would be better than a centralized one since you won’t need to worry about the security of storing sensitive data on a remote system (like your /etc/passwd file).

This set up is great for those oh-shit moments when something breaks and you have to track down which configuration change brought that about. With Git, viewing the diffs of the latest changes along with their timestamps is not a problem at all. This also lets you have an audit trail in case there are multiple administrators managing the system, allowing them to see what changes to the configuration are being made, by who and why.

As in programming, making nice clean commits helps a lot. One changeset should only have one change such as “added a vhost for newdomain.com”, or “gave SSH login access to user Y”, so that they can be easily rolled back.

Coupled with a HIDS that monitors system binary changes, this should let you have your system locked down and be aware of at least all non-malicious changes happening across your system, such as when installing, uninstalling and updating packages.


Keeping Tabs on Pesky VPN Users

I run a VPN server for my friends on an Ubuntu 10.04 box. Bandwidth usage went through the roof so to track down which of them was doing it I hacked up a 70 line Ruby script.

This assumes every user gets one unique IP address mentioned in the last column of /etc/ppp/chap-secrets

There needs to be an iptables chain called VPN_ACCT_IN and VPN_ACCT_OUT which has an entry for each of the VPN user IPs, like:

Chain VPN_ACCT_IN (1 references)
 pkts bytes target     prot opt in     out     source               destination         
 245K  258M            all  --  *      *       0.0.0.0/0            192.168.88.57       
45687   56M            all  --  *      *       0.0.0.0/0            192.168.88.50       
27175   31M            all  --  *      *       0.0.0.0/0            192.168.88.51       

and


Chain VPN_ACCT_OUT (1 references)
 pkts bytes target     prot opt in     out     source               destination         
 201K   29M            all  --  *      *       192.168.88.57        0.0.0.0/0           
34681 2721K            all  --  *      *       192.168.88.50        0.0.0.0/0           
20632 2758K            all  --  *      *       192.168.88.51        0.0.0.0/0           

all data that’s FORWARDED through the box to/from VPN IPs should go to these chains:

Chain FORWARD (policy ACCEPT 17M packets, 11G bytes)
 pkts bytes target     prot opt in     out     source               destination         
 372K  408M VPN_ACCT_IN  all  --  *      *       0.0.0.0/0            192.168.88.0/24     
 298K   38M VPN_ACCT_OUT  all  --  *      *       192.168.88.0/24      0.0.0.0/0           

Once that’s set up, make sure pptpd logs to wtmp - /etc/pptpd.conf should have the logwtmp line.

The ruby script takes the login durations through the wtmp log (by parsing the output of the “last” command), and gets the data transfer values from the iptables chains. You may have to reset the iptables counters when wtmp gets logrotated at the end of the month.

#!/usr/bin/env ruby

userip = {}
begin
  IO.readlines("/etc/ppp/chap-secrets").each do |line|
    next if /^#/ =~ line
    (user, pptpd, passwd, ip) = line.split
    userip[user] = ip
  end
rescue
  puts "Couldn't open chap-secrets file"
end

usageip_inbound = {}
IO.popen("iptables -nvL VPN_ACCT_IN").readlines.each do |line|
  next if /Chain|pkts/ =~ line
  cols = line.split
  data = cols[1]
  ip = cols[7]
  usageip_inbound[ip] = data
end

usageip_outbound = {}
IO.popen("iptables -nvL VPN_ACCT_OUT").readlines.each do |line|
  next if /Chain|pkts/ =~ line
  cols = line.split
  data = cols[1]
  ip = cols[6]
  usageip_outbound[ip] = data
end
  
totals = {}
totals.default = 0
IO.popen("last").readlines.each do |row|
  next if not /ppp/ =~ row
  
  cols = row.chomp.split
  
  (user, term, ip) = cols[0..2]
  (day, month, date, start_time) = cols[3..6]
  end_time = cols[7..cols.length]
  duration = cols[-1][1..-2]
  
  next if /still logged in/ =~ end_time*' '
  
  (start_hour, start_minute) = start_time.split(':')
  (hours, minutes) = duration.split(':')
  total = hours.to_i * 60 + minutes.to_i
  
  totals[user] += total
  
  #t = Time.local(2011, month, date, start_hour, start_minute)
end

puts "VPN Usage Summary"
puts "-----------------"
totals.sort_by { |k,v| v }.reverse.each do |user,x|
  m = x % 60
  h = x / 60
  
  print "#{user}\t --> "
  print "#{h} hours " if h > 0
  print "#{m} minutes "
  
  ip = userip[user]
  inbound = usageip_inbound[ip]
  outbound = usageip_outbound[ip]
  puts "(#{inbound} received, #{outbound} sent)"
end

Cocos2D iPhone Manually Positioning Sprites

There’s a very common situation I come across where artists being their usual lazy selves send over tonnes of artwork (with sliced images) for our games, and just a reference image showing how all the art looks when it comes together.

Since it’s against their religion to know about things like “pixels” and “coordinates”, it usually ends up being the programmer who has to painstakingly, pixel by pixel, through trial and error, align all the various images (by setting their coordinates) so they mesh together in a way that looks similar to the reference sent by the artist.

Ah, whereas laziness is a deadly sin for artists, it is a formidable weapon in the armory of a programmer. I have created an Objective-C class to be used with cocos2d-iphone which will allow you to move an image on screen around with your finger. Once it’s positioned, hold it in place for 2 seconds and it’ll become “locked” in place, and it’s coordinates will be NSLog’d onto the console so you can copy paste it into your code. To unlock, you may simply double tap on the sprite and it’ll be moveable again.

The code is very simple to use, just include “SpritePositioning.h” and replace your CCSprite class name with SpritePositioning. So for example if you were doing:

CCSprite *s = [CCSprite spriteWithFile:@"zomg.png"];
[self addChild:s];
s.position = ccp(314,53);

All you need to do is replace the first line with this:

CCSprite *s = [SpritePositioning spriteWithFile:@"zomg.png"];

And that’s it! Compile & Run the program and the sprite should show up on screen. You can move it around, and if you hold it in place for 2 seconds it will “lock” into place (you’ll notice it gray out a bit) and the coordinates for where it was locked will be printed onto the console. You can use those coordinates to set the CCSprite’s positioning and then change it back from SpritePositioning to CCSprite.

Programmers 1, Artists 0.

Here’s a link to SpritePositioning.h and SpritePositioning.m:

https://gist.github.com/1099876


Reverse Bits Of An Arbitrarily Sized Integer in C

This one’s not by me, but is the most beautiful piece of C code I have ever seen.

I’ve actually lost the original source, if anyone knows where this is from, please leave a note.


#include <stdio.h>
b(n) {return n?b(n<<1)<<1|n<0:0;}
main()
{
	unsigned long int n = 0x8b4cd21;
	printf("%X\n%X\n%X\n", n, b(n), b(b(n)));
	return 0;
}


Memcache Multiple Google App Engine Entities

There’s a pretty common use case in GAE when you want to db.put() a whole bunch of entities in one go, and you want to update their corresponding memcache entries as well.

The following snippet is my favourite way of doing it, certainly the most pythonic I could make it:

This assumes you have an array “arr” full of GAE Model instances that are waiting to be put into the DB using db.put(arr). It would be useful to adopt a memcache convention for having the keys in the format EntityType-KeyName. Then before (or after) you do your db.put, you can run this command to update all the relevant memcache entries:


memcache.set_multi(dict([("%s-%s" % (x.kind(), x.key().name()), x) for x in arr]))

Note that this method will return a list of keys that were not set in memcache successfully, so you could put it in a little loop that keeps trying until all items are memcached.

Facebook XMPP Chat Example Using X-FACEBOOK-PLATFORM in JAXL

JAXL took ridiculously long to get working.

Make sure the JAXL directory is present at the path given in the first line (require_once …) relative to the php script.

This script sometimes doesn’t work when you run it through a webserver, but will run fine over cli. (hardcoding JAXL’s SAPI check for cgi/cli is a duct tape fix for it)

Someone really needs to write better XMPP libraries with X-FACEBOOK-PLATFORM auth support. Facebook’s own example is not very helpful.


<?php
	require_once 'JAXL/core/jaxl.class.php';

	$chat_to = '12345';		// who you want to send a message to (their Facebook ID)
	$chat_content = 'The message';		// content of your message
	$chat_session = 'Session_ID';	// the user's session ID should have xmpp_login and offline access permissions
	
	$app_secret = ''; // your FB app's secret
	$app_api_key = ''; // your FB app's api key
	

	$jaxl = new JAXL(array(
		'user'=>'',
		'pass'=>'',
		'host'=>'chat.facebook.com',
		'domain'=>'chat.facebook.com',
		'logLevel' => 4
	));

	function postAuth($payload, $jaxl) {
		global $chat_to, $chat_content;
		$jaxl->sendMessage('-'.$chat_to.'@chat.facebook.com', $chat_content);
		$jaxl->shutdown();
	}

	function getFacebookKey() {
		global $chat_session, $app_secret, $app_api_key;
		return array(
			$app_secret,
			$app_api_key,
			$chat_session	// user session
		);
	}

	function doAuth($mechanism) {
		global $jaxl;  
		$jaxl->auth("X-FACEBOOK-PLATFORM");	 
	}  
	
	$jaxl->addPlugin('jaxl_post_auth', 'postAuth');
	$jaxl->addPlugin('jaxl_get_facebook_key', 'getFacebookKey');
	$jaxl->addPlugin('jaxl_get_auth_mech', 'doAuth');

	$jaxl->startCore("stream");
?>