sha.nnoncarey.com/blog

sin(Θ)

Speak & Spell!

Those of you who remember the Speak & Spell will probably love my first attempt at a website redesign based around it.

So far, you can type letters using the keys, and it has sounds I recorded from my actual Speak & Spell. The text is much bigger than the real thing, so it can be read, but it is limited to 8 characters like the real thing. The sounds are somewhat delayed on Firefox, and the text is in the wrong place in IE… but you can see the potential!

The image is from a patent application made by Texas Instruments. Hopefully they don’t mind if I use it!

Edit: it’s now my home page

No comments

Rails inconsistency

I like Ruby on Rails, but the design is sometimes inconsistent.

For example, consider the “text_method” parameter to the collection_select helper method. The argument forces you to call a method on the model object which returns the text which is used in the select list. That’s ok when you only want to display a single field from that object, for example “name”. It’s not ok if you want to display something more complicated, because then you’re putting display logic into the model. You’re supposed to use helpers for that! Since doing it right would make it ugly and more complicated, I end up giving in and doing it the wrong way by adding a method to the model. It frustrates me.

No comments

Fareed Haque

It’s nice to have a girlfriend who works for the Skokie Theater. I’m getting free admittance to see Fareed Haque tonight. Awesome.

1 comment

Duo Melis

This blog is notably lacking in the subjects of music and art, so to help remedy that here is a video of the classical guitar duo I had the delight of hanging out with this weekend. http://www.youtube.com/watch?v=gXMOB1BvpwY

They are amazing musicians, not to mention hilariously funny and smart. Besides hearing a totally INTENSE and inspirational performance, I got to hear really funny and endearing stories about their adventures. Susana is from Spain, while Alexis is from Greece, so they’re doubly interesting to talk to.

Unfortunately, writing about it tends to deflate the experience. But I will update if they are in Chicago again. Until then, check out their website http://www.duomelis.com/

No comments

Brain dump

Delicious firefox extension – intelligent tag grouping to cut down on size of menu
Sage – load feeds by opening an rss of rss feeds
Particle system research. Bird for website redesign.
Embattle – write gtd to identify unresolved issues

No comments

Javascript Mergesort

A while ago, I couldn’t find any Javascript mergesort implementations, so I wrote one. The nice thing about mergesort is that it is “stable”, id est it retains the previous order of elements with equal value. Therefore it is great for sorting rows in a table on different columns sequentially. Also, the merge() function is handy for merging two sorted arrays into one big sorted array.

Check out Wikipedia for more info on mergesort and other sorting algorithms.

Here it is:

var MergeSorter = function(comparator) {
	var merge = function(a, b)
	{
		var aLen = a.length;
		var bLen = b.length;

		if(aLen == 0)
			return b;

		if(bLen == 0)
			return a;

		var i, j, k;
		i = j = k = 0;
		var result = Array();
		while(i < aLen && j < bLen)
		{
			if(comparator.compare(b[j], a[i]))
				result.push(a[i++]);
			else
				result.push(b[j++]);
		}
		while(i < aLen)
			result.push(a[i++]);

		while(j < bLen)
			result.push(b[j++]);

		return result;
	};
	return {
		sort: function(a)
		{
			var aLen = a.length;
			if(aLen <= 1)
			{
				return a;
			} else {
				var middle = Math.round(aLen / 2);
				var left = a.slice(0, middle);
				var right = a.slice(middle);
				left = this.sort(left);
				right = this.sort(right);
				var result = merge(left, right);
				return result;
			}

		}
	}
};

var normalComparator = {
	compare: function(n1, n2)
	{
		return n1 >= n2;
	}
};

Here is sample code that makes use of the MergeSorter and does some sanity checks. It could easily be turned into a set of unit tests.

var mockComparator = {
		calls: 0,
		compare: function(n1, n2)
		{
			this.calls++;
			return n1.num >= n2.num;
		}
};

function writeError(str)
{
	document.write('<span style="color: red;">' + str + '</span><br>');
}

var size = 100000;
var ary = new Array(size);
for(var i = 0; i < size; i++)
{
	var num = Math.round(Math.random() * size);
	ary[i] = {num: num, id: i};
}
document.write('<br>');

var start = new Date().getTime();
var myMergeSorter = new MergeSorter(mockComparator);
ary = myMergeSorter.sort(ary);
var stop = new Date().getTime();
var executionTime = stop - start;

document.write('Merge sorting an array with ' + ary.length + ' random integers in it...<br>');
document.write('Execution time: ' + executionTime / 1000 + 's<br>');
document.write('Result length: ' + ary.length + '<br>');
document.write('Comparisons: ' + mockComparator.calls + '<br>');

var ceilLgN = Math.ceil(Math.log(size) / Math.log(2));
var maxExpectedCompares = (size * ceilLgN - Math.pow(2, ceilLgN) + 1);
document.write('Worst case (for this size): ' + maxExpectedCompares + '<br>');
document.write('Theoretical average (for this size): ' + (maxExpectedCompares - 0.2645 * size) + '<br>');

if(ary.length != size)
{
	writeError('Result is not the right size: ' + ary.length);
}

for(var i = 0; i < ary.length; i++)
{
	if(ary[i + 1])
	{
		if(ary[i].num > ary[i + 1].num)
		{
			writeError('Sorting error at index ' + i + '! ' + ary[i].num + ' greater than ' +
				ary[i + 1].num);
			break;
		}
		if(ary[i].num == ary[i + 1].num && ary[i].id > ary[i + 1].id)
		{
			writeError('Stability error at index ' + i + '! ' + ary[i].id + ' greater than ' +
				ary[i + 1].id);
			break;
		}
	}
}

if(mockComparator.calls > maxExpectedCompares)
{
	writeError('Too many comparisons executed!');
}

Edit on December 1, 2010: I modernized the code a bit by making use of object literals, closures, etc. The comparator no longer has to be passed down the recursion. In order to do that with merge() and sort() as top-level functions, the comparator would have to be assigned to a global variable. Also, I added a more thorough example of the usage, with sanity checks.

It is worthwhile to mention that some Javascript implementations, array.sort() is already stable. See, for example, the documentation on sort at the MDC. Since native implementations of sort() have the potential to be much faster, it may be worthwhile to check whether this is the case and if so implement user agent testing to determine whether to use Javascript’s sort, or your own implementation.

No comments

origin of heredoc?

I’m curious. Who knows the origin of the word “heredoc” or “here document” to refer to a way of representing string literals? It seems like such a strange name.

No comments

braindump – html 5

As pointed out on slashdot, the first public material on HTML 5 is now available from the W3C. http://www.w3.org/TR/2008/WD-html5-diff-20080122/

It’s a major victory that frames have been completely removed from the language. They have always been horrible for the UI, security, bookmarkability, etc.

However, I take major issue with their choice to standardize innerHTML into the DOM. The only reason I’ve ever used innerHTML is because sometimes it’s impossible to get IE to behave any other way. IE’s poor lack of support for DOM is no reason to standardize a workaround though! Not only does innerHTML promote bad programming practices, it can all-too-easily lead to injection attacks.

No comments

Circuit Maker v1.0 Released

I would like to announce that the afore-mentioned Circuit Maker program has been released. Bon voyage!

Working on Circuit Maker has made it clear how much work must go into preparing a program before it’s ready to be released to the public. I was using the tool over a year ago at ISU to make a new web app, and it cut development time in half. However, the same things that worked for me might not work for others, and so I had a lot of things to fix and add. I think I’ve accomplished what I set out to accomplish though. Thanks to Roy for his help and great ideas, and also to the rest of my old coworkers at the Dev team of Campus Life Tech Support at ISU.

No comments

Circuit Maker

Circuit Maker is about to become an active project again, instead of a mere passing reference. What is Circuit Maker? It makes Fusebox circuits automatically. Given some simple settings, it creates Model, View, and Controller for a given entity in your Fusebox program. The concept is similar to Ruby’s scaffolding, except for two things. First, it wasn’t developed by Ruby developers so it’s not the same. Second, it doesn’t (yet!) model itself based on the contents of the database. One of the great things about it, though, is that it abides by a very organized structure and set of best practices which help application developers develop faster and better.

So tonight, I loaded up the svn dump to a new repository. It wasn’t easy though, because Circuit Maker used to be in a repository along with a bunch of other projects. As I found out, SVN does not have a feature which allows the user to split, or separate, a repository into more than one repository. Instead, the SVN dump file has to be run through svndumpfilter to remove irrelevant paths, and then it must be hand-edited to correct unwanted paths or changes in path structure (moves or renames to the directory containing the code). It turned out to be easier than I expected, but that was partly because CircuitMaker does not yet contain any octet-encoded files. This guy had worse luck.

Now that we have a workable repository, it is on! Roy and I are pretty excited to finally get this thing out there in the Fusebox community where it belongs. In a way, we’ll hopefully beat Fusebox to the punch when it comes to this kind of thing. There has never been a free/open source tool which is as sexy as this, and all Fusebox has is an inactive Trac page and some ColdFusion code. But if they do get something together, it might lead to some interesting fusion of concepts between Circuit Maker and it.

That’s all. Have a good weekend.

No comments

« Previous PageNext Page »