Categories
Random observations

The Landing Pilot is the Non-Handling Pilot

The Landing Pilot is the Non-Handling Pilot until the “decision altitude” call, when the Handling Non-Landing Pilot hands the handling to the Non-Handling Landing Pilot, unless the latter calls “go-around”, in which case the Handling Non-Landing Pilot, continues Handling and the Non-Handling Landing Pilot continues non-handling until the next call of “land” or “go-around”, as appropriate.

In view of the recent confusion over these rules, it was deemed necessary to restate them clearly.

— British Airways memorandum, quoted in Pilot Magazine, December 1996 (and in The Pragmatic Programmer, which is where I read it).

Categories
Innovation

Thanks for your help

To those who responded to my plea for help by leaving a comment or responding out-of-band, thank you very much. We’ve settled on a name for our application, purchased the corresponding domain names and filed a trade mark application.

Will keep you posted as things evolve further. But just to give you an idea, we’ve already iterated through several “alpha” versions and expect to have a public beta ready by the end of February. Stay tuned for an explanation of what the service actually does.

Categories
Random observations

The SVNMate plugin for Textmate

For anyone who’s using Subversion through Textmate, you might be interest in Ciarán Walsh’s SVNMate plugin. It changes the icons for files and folders in the project drawer depending upon their SVN status. Very handy.

Categories
Random observations

Installing the mysql rubygem on Leopard

There are so many sites offering suggestions on how to get the mysql rubygem working on Mac OS X Leopard. None of them worked for me. Here’s how I got the gem installed.

After attempting to install the gem normally, with sudo gem install mysql (which bombs out), go into /Library/Ruby/Gems/1.8/gems/mysql-2.7 or wherever it tried to install the gem. Add the line

#define ulong unsigned long

near the top of the file mysql.c.in.

Repackage the gem by issuing sudo gem build mysql.gemspec

Then install with

sudo env ARCHFLAGS="-arch i386" gem install --local mysql-2.7.gem -- --with-mysql-config=/usr/local/mysql/bin/mysql_config

You’re done. You may not need to wrap the gem install command with the env command.

Categories
Random observations

TextMate

TextMate seems to be recommended by just about every Mac-oriented programming site out there. So I bought it a few weeks ago. For 33.15 EUR. It rocks. Oh, and this post was made from within TextMate.

Categories
Innovation

Startup: an explanation

It’s probably time to come clean about my recent spate of posts on startups, Ruby, Python and so on. Well, there are a few things about peer review and publishing in the realm of academia that I think could be better, so I tried to figure out an alternative process that retains the benefits and overcomes some of the problems of the current system. We think we’ve done that, and it turns out that I wasn’t the only one who thought that things could be a lot better.

NICTA has provided pre-seed funding in the form of a couple of commercialisation grants to implement this new way of doing things. I’ve hired a top notch graduate software engineer (who’s been working with me as a student for the past year and a half on unrelated things) to help me deliver alpha and beta versions of this system over the next six months or so. For this project, we’ll be working in startup mode; I’ll be making every effort to provide a small company atmosphere for the engineer and others who join the project.

It turns out the solution to the problem can also be applied to (web) search, since it is essentially a nice way of ranking documents within communities. I can’t go into the details of the solution here, but I can list some of the things that I (and other researchers, as it happens) think could be better.

  • Traditional peer review requires that authors trust reviewers to act in good faith – reviewers are not required to “put their money where their mouth is”, so to speak;
  • Related to the above, traditional peer review gives no real incentive to support the good work of a group competing scientists;
  • Related to the above, traditional peer review provides no real incentive not to support the poor work of a colleague or friend;
  • Traditional peer review gives no tangible recognition to the many hours of reviewing that scientists do – reviewing is just something you’re expected to do for the good of the scientific community;
  • Traditional peer review gives no incentive to authors to self-review their work before submission, meaning reviewers get burdened with too many bad and mediocre papers;
  • Metrics such as H-index and G-index are somewhat arbitrary, do not give a direct indication of the esteem with which scientists are held by their peers, and are not indicative of the current capacity of a scientist to produce good work;
  • Citation collusion is too easy to accomplish, but difficult to filter out when calculating the above metrics;
  • Not enough cross-fertilisation between fields, largely because closed communities are too common; and
  • The publication process is too slow, often taking years for a journal paper and months for a conference paper.

These are some of the problems that researchers say they can see with the current way of doing things. We think we can claim that our idea solves many of these problems. For example, under our system, which we are calling PubRes for the moment, citation collusion is futile. Under PubRes, you’d also be silly to lend support to a paper that you know isn’t very good (even if it is written by a colleague), and you’d be silly not to lend support to a good paper (even if it is written by a competing group of scientists or your worst enemy). There are some things we haven’t solved, like honorary authorship and ghost authorship, but these are problems I’d like to investigate in the future. Although I can’t reveal the details here, I can say that the underlying mechanics of PubRes are no more complicated than traditional peer review procedures (and probably much less complicated), but it is a major departure from how things are done now. I can also say that the feedback we’ve got from people we’ve explained it to has been overwhelmingly positive, which is the main reason I’m still pursuing this.

NICTA are making sure we do this properly, so some of the grant money is being spent on figuring out the structure of the academic publishing market. We already know that the top three academic publishers had combined 2007 revenues in excess of $US3 billion, but that doesn’t say much. We’re currently doing some much deeper market research to get a better understanding of the domain.

It’s important to note that what we’re doing is completely different to all known attempts to bring science to the web. PubRes is not another CiteULike or Connotea. It’s not another arXiv.org. It’s not like PLoS One or PubMed Central. It’s different to ResearchGATE and Science Commons. While our implementation may contain elements of these existing tools, PubRes is a fundamentally new way of getting your research published, and it’s a new, much fairer (we think), more direct way of rating scientists and the papers that they write. One of our aims is also to make the whole reviewing, publishing and reading cycle a lot more fun.

With any luck, a public beta will be available early next year. Oh, we think we’ve settled on Ruby and Ruby on Rails for the web tier, and no doubt there’ll be some AJAX stuff in there to pull off a few nifty browser side features we have in mind. Stay tuned.

Categories
Innovation

Ricky, Ruby and Rails (hypothetically speaking)

In the bits of spare time I get here and there, I’ve been continuing my hypothetical hunt for a language and web framework in which to implement my hypothetical "web 2.0" idea. It occurs to me that if all these little bits of spare time were clumped together so that I could, hypothetically, do some actual coding as opposed to “investigating”, hypothetically I’d be well on my way to having a hypothetical working system by now. But, alas, little bits of time here and there is all I’ve got at the moment.

chunky bacon

Anyway, after having checked out Python and Django and deciding that I’d be happy enough with that set of tools, I thought I’d better check out Ruby and Ruby on Rails to see what all the fuss is about. Well, I have to say, so far I really like the Ruby language. I’ve been helped along by what has to be the weirdest, but coolest, guide to programming that has ever been written for any language (what other programming guide comes with cartoon foxes and its own soundtrack?). I’m still learning the ins and outs of Rails, but there are some very helpful tutorials online for this, too. The fact that Ruby, like Python, comes pre-installed in Leopard was a pleasant surprise. Ruby comes with a command shell environment called irb (Interactive Ruby), which enables you type Ruby code at the command prompt (again, just like Python’s python command line tool). This makes it very easy to experiment with the language.

One of the things I like about Python is list comprehensions. They’re a very neat and convenient way of mapping a list to a new list by applying a function to each element of the original. It kind of works like the map function in many other languages, except you can include conditional statements. The heavy use of list comprehensions in Programming Collective Intelligence tells me that there’s a good chance they’ll come in handy for me later on. Here’s a trivial example:


>>> list1=[1,2,3]
>>> list2=[x**2 for x in list1 if x%2==1]
>>> list2
[1, 9]

In Ruby there’s no syntactic sugar for list comprehensions, but it turns out you can pretty easily implement the required behaviour:


>> list1=[1,2,3]
=> [1, 2, 3]
>> list2=list1.map {|x| x**2 if x%2==1}.compact
=> [1, 9]

Furthermore, since classes are never “sealed” or “final” in Ruby, it means that you can do something like this:


>> class Array
>>   def comprehend( &block )
>>     block ? map( &block ).compact : self
>>   end
>> end

We’ve just added another method to the (existing) Array class which works very much like a list comprehension:


>> list1.comprehend {|x| x**2 if x%2==1}
=> [1, 9]

That’s a little of what I’ve learned about Ruby in the past week or so. Anyway, I can say that I’ve narrowed down my search to two candidates. Python has the lead in terms of being a mature technology. But Ruby really is fun to program in, and I like its syntax better than Python’s. Furthermore, I spent a while faffing around with Django and mod_python for my Mac. But getting Rails up and running was a breeze using the Mongrel web server – a production quality web server for Ruby applications, used by many web sites including Twitter. Ultimately, my (hypothetical) first hire gets the final say. :-)

Categories
Random observations

Rediscovering closures and nested functions

When you’ve spent years coding pretty much everything in Java, it’s hard to break out of the Java way of doing things. It means that you tend to forget that other languages might have things called closures, for example. Here’s how a closure looks in Python:


lambda x:dosomethingto(x,anothervariable)

The neat thing is that this closure can be passed around like a first class object. Also, anothervariable, bound in the outer scope, is accessible to the lambda expression when it is invoked later. You can do stuff like:


if isinstance(somevalue, int) or isinstance(somevalue, float):
  isfunny=lambda x:log(x)>somevalue
else:
  isfunny=lambda x:isalpha(x) and islower(x)

funnyitems=[item for item in mylist if isfunny(item)]
seriousitems=[item for item in mylist if not isfunny(item)]

Sure there are other ways to do the same thing. But this is arguably more elegant.

There’s also nested functions, which are kind of like closures. Rather than contriving an example, I’ll give one from the book I’m reading, Programming Collective Intelligence. In chapter 8, a crossvalidation function is defined. Forgetting the specifics and purpose of this function, just know that the crossvalidate function returns low numbers for good solutions and high numbers for bad solutions. Earlier in the book, we’d already been introduced to optimisation problems and cost functions. The cost functions take a single argument, which is a potential solution to be costed. The crossvalidate function takes a bunch of parameters, so for this and other reasons it can’t be used directly. But you can do something like this:


def createcostfunction(algf, data):
  def costf(scale):
    sdata=rescale(data,scale)
    return crossvalidate(algf,sdata,trials=10)
  return costf

So now your costf function knows about algf and data, despite not having them as parameters. That is, the bound variables to algf and data are available to costf when it is called at some later time:


costf=createcostfunction(knearest,mydata)
annealingoptimise(wdomain,costf,step=2)

So when annealingoptimise eventually invokes costf, costf has access to knearest and data. That is the bindings of algf to knearest and data to mydata live on after the execution of createcostfunction completes. Cool.

Categories
Random observations

Mod_wsgi

Forget my previous entry about mod_python. Just use mod_wsgi. It compiles without issues on the Mac (unlike mod_python, which is why I made a binary available for it), and seems to be the future for Apache/Python integration. See Graham’s comment on my last entry.

Categories
Random observations

Mod_python for the Mac

In case anyone’s interested, I’m making available a pre-built universal binary of mod_python 3.3.1 for Apache 2.2.8. I’m running Mac OS X Leopard 10.5.2 and Python 2.5.1. The DMG contains an installer package, and it will try to install mod_python to /usr/libexec/apache2, which is where the other apache modules are usually located. Use at your own risk.

You can download it here.