<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description></description><title>Type Slowly</title><generator>Tumblr (3.0; @timcowlishaw)</generator><link>http://timcowlishaw.co.uk/</link><item><title>Thrift installation woes part II: Using Thrift with a kerl'd erlang.</title><description>&lt;p&gt;More notes on thrift setup, mostly for my own reference, but hopefully they’ll be useful to anyone else in the same situation.&lt;/p&gt;
&lt;p&gt;So, following my last post, you’ve got thrift set up on your local machine. However, you’re using the highly useful &lt;a href="https://github.com/spawngrid/kerl"&gt;kerl&lt;/a&gt; tool to work with different erlang versions, and you want to use both this and thrift with your project. This means you need to recompile and install the thrift erlang libraries to work with your kerl installation. &lt;/p&gt;
&lt;p&gt;Thankfully this isn’t too painful, and doesn’t involve recompiling all of thrift again, you just need to pass a few extra options to the configure script, and ensure that you only make and install the erlang bindings, rather than the whole thing:&lt;/p&gt;
&lt;p&gt;First, you need to run the configure script, setting environment variables that refer to the location of erl, erlc, and your erlang installation’s lib directory, and also explicitly disabling all the libraries apart from erlang:&lt;/p&gt;
&lt;pre class="brush: bash"&gt;ERL=$PATH_TO_YOUR_KERLD_ERLANG/bin/erl \\
ERLC=$PATH_TO_YOUR_KERLD_ERLANG/bin/erlc \\
ERLANG_INSTALL_LIB_DIR=$PATH_TO_YOUR_KERLD_ERLANG/lib/ \\
bundle exec ./configure --without-cpp --without-c_glib --without-csharp \\
--without-java --without-python --without-perl --without-php \\
--without-php_extension --without-ruby --without-haskell --without-go
&lt;/pre&gt;
&lt;p&gt;Then, cd into the lib/erlang directory in the thrift source tree, before running make and make install as normal (don’t use sudo for this if you’re installing into a directory inside your home):&lt;/p&gt;
&lt;pre class="brush: bash"&gt;cd lib/erlang
make
make install
&lt;/pre&gt;</description><link>http://timcowlishaw.co.uk/post/16759787107</link><guid>http://timcowlishaw.co.uk/post/16759787107</guid><pubDate>Mon, 30 Jan 2012 14:19:00 +0000</pubDate></item><item><title>Jruby on Elephants</title><description>&lt;p&gt;A few months ago, I gave a talk at the excellent &lt;a href="http://rubymanor.org/"&gt;Ruby Manor&lt;/a&gt; conference about using Jruby with Mahout to do machine-learning (More specifically, to detect twitter messages containing pictures of kittens). There’s now a &lt;a href="http://rubymanor.org/3/videos/jruby_on_elephants/"&gt;video&lt;/a&gt; of it online, as well as &lt;a href="http://jruby-on-elephants.heroku.com/#1"&gt;slides&lt;/a&gt; and &lt;a href="https://github.com/timcowlishaw/jruby-on-elephants"&gt;code&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;One small additional note - my explanation of Logistic Regression is a little confused, and is subtly but fundamentally incorrect. In the simple one dimensional example I show, the Y-axis corresponds to the feature to be learned, while the X-axis corresponds to the feature we’re learning from - Watching the video back, It looks like I’m describing the Y-axis as a feature,which would be silly, as then we wouldn’t actually be predicting anything. So, the logistic curve, in this 1D example gives us a means of predicting the classification (Y-high or Y-low) from the (real) value of the X axis. Sorry!&lt;/p&gt;</description><link>http://timcowlishaw.co.uk/post/16004059224</link><guid>http://timcowlishaw.co.uk/post/16004059224</guid><pubDate>Tue, 17 Jan 2012 12:22:34 +0000</pubDate></item><item><title>Installing Thrift on Ubuntu Oneiric, with Ruby 1.9.2 (via RBenv) and Haskell</title><description>&lt;p&gt;A few notes, to save my sanity if and when I run into this again.&lt;/p&gt;
&lt;p&gt;Get the thrift sources from SVN, untar the file, then add a Gemfile to the root of the source tree:&lt;/p&gt;
&lt;pre class="brush: ruby"&gt;source "http://rubygems.org"
gem "mongrel", "=1.2.0.pre2"
gem "rspec", "=1.3.2"
gem "rake", "0.9.2"
&lt;/pre&gt;
&lt;p&gt;Then run bundle install.  The Haskell bindings require the Binary library to be installed in cabal. This needs to be done globally, as cabal by default doesn’t look at packages installed per-user:&lt;/p&gt;
&lt;pre class="brush: bash"&gt; sudo cabal install binary --global
&lt;/pre&gt;
&lt;p&gt;Then you need to do the configure / make / make install dance, running each command with bundle exec:&lt;/p&gt;
&lt;pre class="brush: bash"&gt; bundle exec ./bootstrap
 bundle exec ./configure
 bundle exec make
&lt;/pre&gt;
&lt;p&gt;However, there’s one last gotcha. ‘make install’ needs to be run as root, but in order to ensure it uses the bundled rake and gems, and rbenv’s selected ruby, you need to become root first, then run make install:&lt;/p&gt;
&lt;pre class="brush: bash"&gt; sudo -s
 bundle exec make install
 exit
&lt;/pre&gt;
&lt;p&gt;That should do it!&lt;/p&gt;</description><link>http://timcowlishaw.co.uk/post/16003740695</link><guid>http://timcowlishaw.co.uk/post/16003740695</guid><pubDate>Tue, 17 Jan 2012 12:05:20 +0000</pubDate></item><item><title>Automatically backing up a postgres database</title><description>&lt;p&gt;I’ve got a web server I’m looking after that has a postgres database with some important information in it. The server’s filesystem itself is backed up nightly, but I want to make sure that there’s a dump of the database on disk before this happens. This clearly requires a cron job, and the use of the pg_dump command. However, I’ve got a few other requirements: I need backups for the last &lt;em&gt;n&lt;/em&gt; days to be stored and automatically rotated, and the backups should be gzipped for storage. The result is this handly little bash script:&lt;/p&gt;
&lt;pre class="brush: bash"&gt;#!/usr/bin/env bash
DATABASE_NAME=somedatabase
BACKUP_PATH=/path/to/backup/dir
BACKUP_LIMIT=7
pg_dump $DATABASE_NAME | gzip -c &gt; "$BACKUP_PATH"/"$DATABASE_NAME"_`date +"%Y%m%d%H%M"`.sql.gz
BC=$(ls $BACKUP_PATH | wc -l)
if [ "$BC" -ge "$BACKUP_LIMIT" ]; then
    ls -t $BACKUP_PATH | tail -$(($BC-$BACKUP_LIMIT)) | xargs -I{} rm $BACKUP_PATH/{}
fi
&lt;/pre&gt;</description><link>http://timcowlishaw.co.uk/post/6317444844</link><guid>http://timcowlishaw.co.uk/post/6317444844</guid><pubDate>Wed, 08 Jun 2011 12:51:00 +0100</pubDate></item><item><title>What's the difference between the strict and lazy identity monads?</title><description>&lt;p&gt;I came across this question while reading  Simon Marlow et al’s paper “&lt;a href="http://research.microsoft.com/apps/pubs/default.aspx?id=138042"&gt;Seq no more: better strategies for parallel Haskell&lt;/a&gt;”, which describes the Eval monad (representing the result of a parallel computation) as being equivalent to the Strict identity monad. &lt;/p&gt;
&lt;p&gt;Now, it may seem obvious that it’s possible to have identity monads with either lazy or strict semantics, but I’d never come across them in the wild before, and it took a little bit of thinking to fully understand the difference between them.&lt;/p&gt;
&lt;p&gt;First, it’s important to note that when we describe a monad as being lazy or strict, we’re describing the semantics of the bind operation with respect to the monadic value it’s operating on. So, a strict monad when bound to a function will always evaluate its argument, whereas a lazy monad will only evaluate its argument if the bound function references it.&lt;/p&gt;
&lt;p&gt;The key to implementing this lies in the fact that pattern-matching arguments to a function forces strict evaluation - in order to carry out a pattern-match, the argument must be evaluated. Therefore, if we define our bind function to pattern-match against its first argument, we are implicitly affording strict semantics to our monad. If, on the other hand, we do not pattern match against the first argument, our monad will have lazy semantics. In code:&lt;/p&gt;
&lt;pre class="brush: haskell"&gt;import Control.Monad

data LazyID a = LazyID { runLazyID :: a }

instance Monad LazyID where
  return = LazyID
  m &gt;&gt;= f = f (runLazyID m)

data StrictID a = StrictID { runStrictID :: a }
instance Monad StrictID where
  return = StrictID
  (StrictID v) &gt;&gt;= f = f v
&lt;/pre&gt;</description><link>http://timcowlishaw.co.uk/post/4938542785</link><guid>http://timcowlishaw.co.uk/post/4938542785</guid><pubDate>Mon, 25 Apr 2011 23:26:00 +0100</pubDate></item><item><title>Making Nationwide's online banking play nicely with Freeagent</title><description>&lt;p&gt;I don’t like Barclays Bank. I don’t like their &lt;a href="http://en.wikipedia.org/wiki/Robert_Diamond"&gt;President&lt;/a&gt;, I don’t like their &lt;a href="http://www.guardian.co.uk/business/2011/feb/18/barclays-bank-113m-corporation-tax"&gt;attitude to tax payments&lt;/a&gt;, and I definitely don’t like the extent to which they &lt;a href="http://www.waronwant.org/news/press-releases/16333-banks-slated-on-arms-sales"&gt;invest in the sale and manufacture of weapons&lt;/a&gt;. As a result of this, I’ve moved my bank account to &lt;a href="http://www.nationwide.co.uk/default.htm"&gt;Nationwide&lt;/a&gt;, who so far have been most impressive, apart from one small issue. I use the wonderful &lt;a href="http://www.freeagentcentral.com/"&gt;FreeAgent&lt;/a&gt; software to handle all my accounting, tax, and the like, and one of the awesome things it can do is import your bank statements in OFX format, which saves me doing a hell of a lot of very boring data entry, and leaves me with only a small amount of slightly less boring book-balancing to do.&lt;/p&gt;
&lt;p&gt;However, Nationwide don’t support export of your banking data as an OFX file, opting instead for a rather arbitrary CSV-based format, delivered in an arcane character encoding that appears to be mostly ASCII, apart from £-signs, which are encoded as Latin-9.&lt;/p&gt;
&lt;p&gt;All’s not lost though, since Freeagent accept CSV files (in their own, rather simpler format), it’s possibile to convert between the two with this handy Ruby script. Simply&lt;a href="http://jarvis.timcowlishaw.co.uk/convertBankStatement.rb"&gt; download it&lt;/a&gt;, set the executable bit, and run it with:&lt;/p&gt;
&lt;pre class="brush: bash"&gt;convertBankStatement your_nationwide_statement.csv file_to_write_to.csv&lt;/pre&gt;
&lt;p&gt;You’ll need Ruby 1.9.2. This is how it works:&lt;/p&gt;
&lt;pre class="brush: ruby"&gt;#!/usr/bin/env ruby
# encoding: UTF-8
require 'csv'
require 'iconv'

@converter = Iconv.new("ISO8859-15", "utf-8")

date = /\d\d [A-Z][a-z][a-z] \d\d\d\d/
string = /.*/
nothing = /^$/
amount = /£\d+\.\d\d/
money_in = [date, string, nothing, amount, amount]
money_out = [date, string, amount, nothing, amount]

def normalise(t)
  t.map { |s| s.to_s.gsub("\xA3".force_encoding(Encoding.aliases["ISO8859-15"]), "£").force_encoding(Encoding.default_external) }
end

def transaction_type(array, pattern)
  !array.empty? &amp;&amp; array.zip(pattern).inject(true) {|m, (string, pattern)| m &amp;&amp; string =~ pattern}
end

def date(transaction)
  Date.parse(transaction[0]).strftime("%d/%m/%Y")
end

def description(transaction)
  transaction[1].strip[0..31]
end

def outgoing(transaction)
  transaction[2].gsub("£", "-")
end

def incoming(transaction)
  transaction[3].gsub("£", "")
end

CSV.open(ARGV[1], "wb") do |o|
  CSV.foreach(ARGV[0], :encoding =&gt; Encoding.aliases["ISO8859-15"]) do |t|
    t = normalise(t)
    if transaction_type(t, money_in)
      o &lt;&lt; [date(t), incoming(t), description(t)]
    elsif transaction_type(t, money_out)
      o &lt;&lt; [date(t), outgoing(t), description(t)]
    end    
  end
end

&lt;/pre&gt;</description><link>http://timcowlishaw.co.uk/post/4065066295</link><guid>http://timcowlishaw.co.uk/post/4065066295</guid><pubDate>Thu, 24 Mar 2011 16:15:00 +0000</pubDate></item><item><title>I normally try not to wear dorky t-shirts, but this one is just...</title><description>&lt;img src="http://30.media.tumblr.com/tumblr_licynngkFf1qaspmyo1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;I normally try not to wear dorky t-shirts, but this one is just too good to pass up. The &lt;a href="http://en.wikipedia.org/wiki/Fixed_point_combinator#Y_combinator"&gt;Y-combinator&lt;/a&gt;, set in the style of the &lt;a href="http://ycombinator.com/"&gt;other Y-combinator&lt;/a&gt;’s logo. If you like the lambda calculus, and either like or want to poke fun at web-startup VC type stuff, you can get one &lt;a href="http://sigusr2.spreadshirt.com/y-combinator-in-ycombinator-logo-style-A7106613/customize/color/2#"&gt;here&lt;/a&gt;.&lt;/p&gt;</description><link>http://timcowlishaw.co.uk/post/3980539032</link><guid>http://timcowlishaw.co.uk/post/3980539032</guid><pubDate>Sun, 20 Mar 2011 13:26:11 +0000</pubDate></item><item><title>Fans of Arrested Development will doubtless already be familiar...</title><description>&lt;iframe width="400" height="243" src="http://www.youtube.com/embed/JbnjusltDHk?wmode=transparent&amp;autohide=1&amp;egm=0&amp;hd=1&amp;iv_load_policy=3&amp;modestbranding=1&amp;rel=0&amp;showinfo=0&amp;showsearch=0" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Fans of Arrested Development will doubtless already be familiar with &lt;strong&gt;Gob’s Program&lt;/strong&gt; - but who would have thought it’d make such a good bit of instructional Haskell, covering infinite lists and lazy evaluation, list comprehensions, pattern matching, as well as Monadic IO and control flow, all in only 10 lines?&lt;/p&gt;
&lt;pre class="brush: haskell"&gt;import System.Exit
import Control.Monad
main = do
  putStrLn "Gob's Program: Y/N?"
  ans &lt;- getLine
  case ans of
    "Y" -&gt; sequence_ $ map putStr penuses
    _   -&gt; exitSuccess

penuses = ["Penus " | _ &lt;- [1..]]
&lt;/pre&gt;</description><link>http://timcowlishaw.co.uk/post/3919258574</link><guid>http://timcowlishaw.co.uk/post/3919258574</guid><pubDate>Thu, 17 Mar 2011 12:10:00 +0000</pubDate></item><item><title>Tom Morris: I'm not an experience-seeking user, I'm a meaning-seeking human person</title><description>&lt;a href="http://blog.tommorris.org/post/3216687621"&gt;Tom Morris: I'm not an experience-seeking user, I'm a meaning-seeking human person&lt;/a&gt;: &lt;p&gt;&lt;a href="http://blog.tommorris.org/post/3216687621"&gt;tommorrisdotorg&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You want a design challenge? Design things people won’t regret doing when they are on their deathbed and design things people will wish they did more of when they are on their deathbed. Design things that one’s relatives will look back in fifty years and express sympathy for. Again, when you are dead, will your kids give a shit about your Foursquare badges?&lt;/p&gt;

&lt;/blockquote&gt;
&lt;p&gt;Tom Morris has absolutely hit the nail on the head about why I think UX Design, Social Media, and all the other things that ad industry people lump into what they call ‘online’ or ‘digital’ are (on a good day) so much snake oil, and (on a bad day) banal idiotic bullshit that’s turning the web from something wonderful, useful and empowering into the world’s most technologically advanced and expensive &lt;a href="http://www.comparestoreprices.co.uk/images/oc/ocean-wonders-rocking-aquarium-playgym.jpg"&gt;play gym&lt;/a&gt; for the terminally lacking in concentration and intellect. Fantastic stuff.&lt;/p&gt;</description><link>http://timcowlishaw.co.uk/post/3218740599</link><guid>http://timcowlishaw.co.uk/post/3218740599</guid><pubDate>Thu, 10 Feb 2011 18:25:22 +0000</pubDate></item><item><title>Monads, Mo' Problems.</title><description>&lt;p&gt;I don’t think I’ve really got anything new to offer that existing monad tutorials don’t, so I’m going to skip the &lt;a href="http://byorgey.wordpress.com/2009/01/12/abstraction-intuition-and-the-monad-tutorial-fallacy/"&gt;seemingly compulsory step&lt;/a&gt; in the life of a fledgling Haskell programmer of writing a tutorial on monads. However, having recently started to properly ‘get’ what monads are and how they work, I thought I might write a little about how I got to that point - sort of like a literature review of the &lt;a href="http://www.haskell.org/haskellwiki/Monad_tutorials_timeline"&gt;monad tutorials that are already out there&lt;/a&gt;; a ‘meta-tutorial’ of some sort.&lt;/p&gt;
&lt;p&gt;So, in a few steps, here’s how I got to a point where I’ve started to feel like I properly understand and am comfortable using monads as an abstraction in my code:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Prerequisites: This stuff only properly started to fall into place once I had a good grasp of &lt;a href="http://en.wikipedia.org/wiki/Anonymous_function"&gt;lambda abstractions&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/List_comprehension"&gt;list comprehensions&lt;/a&gt; or their distant mathematical cousin, &lt;a href="http://en.wikipedia.org/wiki/Set-builder_notation"&gt;set-builder notation&lt;/a&gt;. (the latter for reasons that will become clear in a few steps time). Take some time to properly cover the basics first.&lt;/li&gt;
&lt;li&gt;Read a &lt;a href="http://moonbase.rydia.net/mental/writings/programming/monads-in-ruby/00introduction.html"&gt;monad tutorial&lt;/a&gt; in the language you use most day-to-day. This helped me understand the definitions of ‘bind’ and ‘return’, but how monads are actually a useful abstraction (and what on earth they have to do with state, IO, and all the other magic they do in Haskell) still eludes me.&lt;/li&gt;
&lt;li&gt;Spend a while constantly coming across &lt;a href="http://andand.rubyforge.org/"&gt;claims&lt;/a&gt; that &lt;a href="http://importantshock.wordpress.com/2009/01/18/jquery-is-a-monad/"&gt;tools&lt;/a&gt; I &lt;a href="http://matthew.yumptious.com/2009/04/javascript/dojo-deferred-is-a-monad/"&gt;use&lt;/a&gt; &lt;a href="http://www.haskell.org/ghc/docs/6.12.2/html/libraries/base-4.2.0.1/Data-List.html"&gt;everyday&lt;/a&gt; are actually Monads in disguise. Remain vaguely confused about why, but develop an intuitive sense of how to spot a Monad in the wild in any case.&lt;/li&gt;
&lt;li&gt;Read Philip Wadler’s ‘&lt;a href="http://homepages.inf.ed.ac.uk/wadler/topics/monads.html"&gt;Comprehending Monads&lt;/a&gt;’ paper (Did I mention that understanding list comprehensions will help you massively?). &lt;/li&gt;
&lt;li&gt;Attain a state of blissful Monad nirvana. Realise that Monads aren’t a technique for implementing stateful imperative programming in a pure functional language, but rather that imperative stateful programming is itself a monad.&lt;/li&gt;
&lt;li&gt;Write a monad tutorial about your discovery.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;…and if spurious real-world metaphors are your sort of thing, I found that &lt;a href="http://codetojoy.blogspot.com/2009/03/monads-are-burritos.html"&gt;Burritos&lt;/a&gt; were the most useful analogy (seriously, &lt;a href="http://blog.plover.com/prog/burritos.html"&gt;they are&lt;/a&gt;).&lt;/p&gt;</description><link>http://timcowlishaw.co.uk/post/3213984090</link><guid>http://timcowlishaw.co.uk/post/3213984090</guid><pubDate>Thu, 10 Feb 2011 08:59:00 +0000</pubDate></item><item><title>Testing Sunspot with Test::Unit</title><description>&lt;p&gt;So, after singing the praises of &lt;a href="http://cukes.info/"&gt;Cucumber&lt;/a&gt; &lt;a href="http://lrug.org/meetings/2010/07/15/august-2010-meeting/"&gt;at LRUG last year&lt;/a&gt;, I’ve actually become a bit more ascetic with my testing practices of late, and am using Test::Unit for everything, including acceptance testing (albeit with a layer of &lt;a href="https://github.com/citrusbyte/contest"&gt;contest&lt;/a&gt; and &lt;a href="https://github.com/citrusbyte/stories"&gt;stories&lt;/a&gt; sugar on top). I could write about why I chose to do this in detail, but it really comes down to one thing, which is ‘speed’. I’ve been programming in Ruby for years, and to be honest, I can spec out a bit of behaviour faster in Ruby than I can in cucumber’s DSL. However, since most of the Rail community seem to be using RSpec and Cucumber, this can make some things a bit of a chore, as with some fairly common or general tasks, you have to go it alone, rather than just grabbing someone else’s solution.&lt;/p&gt;
&lt;p&gt;A case in point: I’ve been working on getting full-text search (powered by &lt;a href="http://outoftime.github.com/sunspot/"&gt;Sunspot&lt;/a&gt; and &lt;a href="http://lucene.apache.org/solr/"&gt;Solr&lt;/a&gt;) working with a site I’m working on. I’ve been really impressed by how easy this is - except for when it came to getting my tests working nicely with it. The problem here is that the Solr service needs to be running in order for the search functionality to work,  but if it’s running for all your tests it slows everything down massively. Clearly, I need a way to only run Solr for those tests that need it, leaving the others to run without it. Since all my test cases are just plain ruby classes (this is Test::Unit), the idiomatic way of doing that seems like a mixin to me, and here it is: &lt;/p&gt;
&lt;pre class="brush: ruby"&gt; module TestSunspot
  class &lt;&lt; self
    attr_accessor :pid, :original_session, :stub_session, :server
    
    def setup
      TestSunspot.original_session = Sunspot.session
      Sunspot.session = TestSunspot.stub_session = Sunspot::Rails::StubSessionProxy.new(Sunspot.session) 
    end

  end
  def self.included(klass)
    klass.instance_eval do
      def startup
        Sunspot.session = TestSunspot.original_session
        rd, wr = IO.pipe
        pid = fork do
          STDOUT.reopen(wr)
          STDERR.reopen(wr)
          TestSunspot.server ||= Sunspot::Rails::Server.new
          begin
            TestSunspot.server.run
          ensure
            wr.close
          end
        end
        TestSunspot.pid = pid
        ready = false
        until ready do
          ready = true if rd.gets =~ /Started\ SocketConnector/ 
          sleep 0.5
        end
        rd.close
      end

      def shutdown 
        Sunspot.remove_all!
        Process.kill("HUP",TestSunspot.pid)
        Process.wait
        Sunspot.session = TestSunspot.stub_session
      end
    end
    def teardown
      Sunspot.remove_all!
    end
  end
end

&lt;/pre&gt;
&lt;p&gt;We use this by calling TestSunspot.setup at the time our testsuite starts running, then including TestSunspot into any test cases that require Sunspot’s functionality.&lt;/p&gt;
&lt;p&gt;Let’s have a closer look at what’s going on.&lt;/p&gt;
&lt;p&gt;TestSunspot.setup saves the original sunspot session, and replaces it with a new stubbed session - this ensures that when CRUD operations on models that are indexed are called, they don’t fail as the server isn’t running. We could of course run the server for every test case, but this’ll slow down our test suite due to all the unnecessary updating of the index that’s going on. It’s not terrifically good practice either. The whole point of Unit tests is that they test Units of your codebase in isolation, and having all these tests depend on this massive cross-cutting concerns is both inelegant and almost certain to cause you headaches.&lt;/p&gt;
&lt;p&gt;With that done, we don’t need to worry about sunspot interfering in our other tests, but we still haven’t solved the problem of how to get our tests that are actually concerned with searching to run Sunspot properly.&lt;/p&gt;
&lt;p&gt;This is where the self.included method definition comes in. This allows us to execute an arbitrary block of code when the module is mixed into a class, and in our case, we’re using instance_eval to define two new class methods, startup and shutdown, which, as the Test::Unit documentation will tell you, are run once at the beginning of the set of tests defined in that class, and once at the end, respectively. This gives us our hooks to startup and shutdown the sunspot server, which is where things get a bit tricky.&lt;/p&gt;
&lt;p&gt;First of all, we need to replace the current sunspot session with the ‘real’ one we stubbed out earlier. In addition, we need to start Sunspot in a different thread or process, as we obviously don’t want it to block our tests from executing. However, it takes a while to start up, and we need to delay executing our tests until it’s ready. So, we fork a new process to run Sunspot (storing the PID so that we can shut it down later), but we redirect it’s STDOUT and STDERR into a pipe. Then, the other end of the process polls the other end of this pipe, waiting for the message “Started SocketConnector” (which is helpfully  output by Sunspot when it’s ready) to appear, at which point it stops blocking and we can run the tests. In our shutdown callback we clear the index, terminate the sunspot process (waiting for it to close), and switch back to our stubbed session, so that any successive tests will run as normal.&lt;/p&gt;
&lt;p&gt;This is a bit of a hack (in particular the STDERR redirecting business), but it’s working reliably for me, and offers a clean simple interface to testing search functionality in my application. &lt;/p&gt;</description><link>http://timcowlishaw.co.uk/post/3179661158</link><guid>http://timcowlishaw.co.uk/post/3179661158</guid><pubDate>Tue, 08 Feb 2011 11:05:00 +0000</pubDate></item><item><title>Making happs-tutorial stop whinging about encodings</title><description>&lt;p&gt;&lt;em&gt;(I’m reposting this little tip, first posted back in May because I’ve somehow managed to delete it since then, and it appears to have been useful to a few other people. I’m afraid I never did submit that patch.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;So, as of last week, all of us at &lt;a href="http://harmonypark.net/"&gt;Harmonypark&lt;/a&gt; have &lt;a href="http://blog.harmonypark.net/2010/05/were-starting-a-new-internal-initiative-called-sandpark.html"&gt;started taking 10% time every Friday afternoon&lt;/a&gt; to work on our own projects, learn new things, and generally do interesting stuff that will make us better at our work.&lt;/p&gt;
&lt;p&gt;This afternoon was my first ten percent time session, and my plan was to work my way through the &lt;a href="http://happstack.com/index.html"&gt;Happstack&lt;/a&gt; &lt;a href="http://tutorial.happstack.com/tutorial/home"&gt;tutorial&lt;/a&gt;, then to make something interesting for the web in Haskell (I’ve got some idea of what, but want to see how I get on before talking about it). However, for reasons that are unclear to me, my OS (Ubuntu 10.04 Lucid AMD64), version of GHC (6.12.1) and locale settings (en_GB.utf8) all conspired to stop the tutorial server from running, failing with the message:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre&gt;./introductiontomacid.st: hGetContents: invalid argument (Invalid or incomplete multibyte or wide character)&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;The way to get around this is to batch convert all the template files to UTF-8 using iconv. As iconv won’t edit in place, this is a three-step operation. First convert all the files, creating new files with the extension ‘.utf8’, then delete all the old ones, then move the new ones into their place. To accomplish this, run these three commands from inside your checked-out happs-tutorial darcs repository:&lt;/p&gt;
&lt;pre&gt;find .  -name '*.st' -exec sh -c 'iconv -f ISO-8859-1 -t UTF-8 "$1" &gt; "$1.utf8"' -- {} \;&lt;br/&gt;&lt;br/&gt;find . -name '*.st' -exec rm {} \;&lt;br/&gt;&lt;br/&gt;find . -name '*.utf8' -exec sh -c 'echo "$1" | sed s/\.utf8// | xargs mv "$1"' -- {} \;&lt;br/&gt;&lt;br/&gt;&lt;/pre&gt;
&lt;p&gt;This wasn’t all wasted time though, while I haven’t learnt much about Haskell and Happstack, I’ve got to grips with ‘find’ and learnt about some interesting bits of the shell I didn’t know about before. I’m gonna make a patch and submit it back to the maintainers shortly (I’m getting back to actually doing the tutorial for the rest of the afternoon instead), but hopefully this will help out anyone in the meantime.&lt;/p&gt;</description><link>http://timcowlishaw.co.uk/post/2944159870</link><guid>http://timcowlishaw.co.uk/post/2944159870</guid><pubDate>Wed, 26 Jan 2011 19:42:33 +0000</pubDate></item><item><title>Epic win: why surjective Set-functions are Epimorphisms.</title><description>&lt;p&gt;I’ve been (slowly) working my way through &lt;a href="http://www.cis.upenn.edu/~bcpierce/"&gt;Benjamin Pierce&lt;/a&gt;’s &lt;em&gt;&lt;a href="http://www.amazon.co.uk/Category-Computer-Scientists-Foundations-Computing/dp/toc/0262660717"&gt;Basic Category Theory for Computer Scientists&lt;/a&gt;&lt;/em&gt; recently, with the imediate aim of understanding enough category theory to get to grips with &lt;a href="http://math.mit.edu/~dspivak/"&gt;David Spivak&lt;/a&gt;’s &lt;em&gt;&lt;a href="http://arxiv.org/abs/0904.2012"&gt;Simplical Databases&lt;/a&gt;&lt;/em&gt; paper, as well as for my general edification. It’s a really good, clear introduction to the subject, and is structured in such a way that it’s possible to pick it up for fifteen minutes and get to grips with a single concept (defined, explained and proved in a few paragraphs) at a time. However, I came a bit unstuck when I got to the assertion that the Epimorphic arrows in &lt;strong&gt;Set&lt;/strong&gt; are the surjective total functions. It’s actually very simple to prove this, using the same &lt;em&gt;reductio ad absurdum &lt;/em&gt;strategy as Pierce uses to prove that the Monomorphic &lt;strong&gt;Set&lt;/strong&gt;-arrows are the injective total functions, however the proof is left out of the book:&lt;/p&gt;
&lt;p&gt;By definition, an arrow $ f: A \longmapsto B $ is &lt;em&gt;Epimorphic&lt;/em&gt; if, for any pair of arrows $ g:B \longmapsto C $ and $ h: B \longmapsto C $: $ g \circ f = h \circ f $ implies that $ g = h $:&lt;/p&gt;
&lt;p&gt;$$ \exists f: \forall g, h: g \circ f = h \circ f \Longrightarrow g = h $$&lt;/p&gt;
&lt;p&gt;So, let’s assume the opposite. Let $ f: A \longmapsto B $ be a surjective function, but let g and h be functions $ g: B \longmapsto C $ and $ h: B \longmapsto C $, such that $ g \circ f = h \circ f $ &lt;em&gt;but&lt;/em&gt; $ g \neq h $:&lt;/p&gt;
&lt;p&gt;$$ \exists f: \forall g, h: g \circ f = h \circ f \Longrightarrow g \neq h $$&lt;/p&gt;
&lt;p&gt;What the last clause here stipulates is:&lt;/p&gt;
&lt;p&gt;$$ \exists b \in B: g(b) \neq h(b) $$&lt;/p&gt;
&lt;p&gt;Now, by the definition of surjectivity, there must be an element of A that f maps to this b, because f completely covers its codomain:&lt;/p&gt;
&lt;p&gt;$$ \exists a \in A: f(a) = b $$&lt;/p&gt;
&lt;p&gt;Putting these two together, we have the following:&lt;/p&gt;
&lt;p&gt;$$ \exists a \in A: g(f(a)) \neq h(f(a)) $$&lt;/p&gt;
&lt;p&gt;or alternatively:&lt;/p&gt;
&lt;p&gt;$$ \exists a \in A: g \circ f(a) \neq h \circ f(a) $$&lt;/p&gt;
&lt;p&gt;…which directly contradicts our original implication:&lt;/p&gt;
&lt;p&gt;$$ \exists f: \forall g, h: g \circ f = h \circ f \Longrightarrow g \neq h $$&lt;/p&gt;
&lt;p&gt;… Therefore, the surjective functions must form the Epimorphisms within &lt;strong&gt;Set&lt;/strong&gt;!&lt;/p&gt;</description><link>http://timcowlishaw.co.uk/post/2566694580</link><guid>http://timcowlishaw.co.uk/post/2566694580</guid><pubDate>Sun, 02 Jan 2011 12:18:00 +0000</pubDate></item><item><title>A paradox: To reduce my to-read list, I read a paper. Reading yields &gt;2 citations to add to the...</title><description>&lt;p&gt;A paradox: To reduce my to-read list, I read a paper. Reading yields &gt;2 citations to add to the list, which therefore grows longer. Repeat.&lt;/p&gt;</description><link>http://timcowlishaw.co.uk/post/1545198385</link><guid>http://timcowlishaw.co.uk/post/1545198385</guid><pubDate>Thu, 11 Nov 2010 19:52:28 +0000</pubDate></item><item><title>I think this must be why people spend their entire lives in academia.</title><description>&lt;p&gt;I think this must be why people spend their entire lives in academia.&lt;/p&gt;</description><link>http://timcowlishaw.co.uk/post/1545198356</link><guid>http://timcowlishaw.co.uk/post/1545198356</guid><pubDate>Thu, 11 Nov 2010 19:52:28 +0000</pubDate></item><item><title>Generation Why? by Zadie Smith | The New York Review of Books</title><description>&lt;a href="http://www.nybooks.com/articles/archives/2010/nov/25/generation-why/?pagination=false"&gt;Generation Why? by Zadie Smith | The New York Review of Books&lt;/a&gt;: &lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“Watching this movie, even though you know Sorkin wants your disapproval, you can’t help feel a little swell of pride in this 2.0 generation. They’ve spent a decade being berated for not making the right sorts of paintings or novels or music or politics. Turns out the brightest 2.0 kids have been doing something else extraordinary. They’ve been making a world.”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description><link>http://timcowlishaw.co.uk/post/1514906060</link><guid>http://timcowlishaw.co.uk/post/1514906060</guid><pubDate>Mon, 08 Nov 2010 10:00:23 +0000</pubDate></item><item><title>Today, I am immersed in Category Theory, a.k.a. ‘Abstract Nonsense’</title><description>&lt;p&gt;Today, I am immersed in Category Theory, a.k.a. ‘Abstract Nonsense’&lt;/p&gt;</description><link>http://timcowlishaw.co.uk/post/1497884657</link><guid>http://timcowlishaw.co.uk/post/1497884657</guid><pubDate>Sat, 06 Nov 2010 17:50:38 +0000</pubDate></item><item><title>A detail from my Mandelbrot set visualisation.</title><description>&lt;img src="http://24.media.tumblr.com/tumblr_lbbyn44AlH1qaspmyo1_500.png"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;A detail from my &lt;a href="https://github.com/timcowlishaw/UCL-MSc-Computer-Science---COMPGC01-Introduction-to-Programming-with-Java/tree/master/exercises/sheet_4/4.11/"&gt;Mandelbrot set visualisation&lt;/a&gt;.&lt;/p&gt;</description><link>http://timcowlishaw.co.uk/post/1473830255</link><guid>http://timcowlishaw.co.uk/post/1473830255</guid><pubDate>Wed, 03 Nov 2010 22:33:04 +0000</pubDate></item><item><title>Day log, 3rd November 2010</title><description>&lt;p&gt;I didn’t bother with a day log yesterday, as I was at my &lt;a href="http://www.microbreweryvinopolis.com/"&gt;other job&lt;/a&gt;, washing casks and carrying sacks of malt. Today, however, I was back in front of the computer today, with a surprising amout to show for it; I’ve &lt;a href="https://github.com/timcowlishaw/UCL-MSc-Computer-Science---COMPGC01-Introduction-to-Programming-with-Java/tree/master/exercises/sheet_4/4.11/"&gt;completed my final programming assignment&lt;/a&gt;, to create a visualisation of the Mandelbrot set, and have added a few extra features to it - the ability to scroll around the plane and zoom in on areas of interest, for instance. With that wrapped up I’ve started looking seriously at my systems infrastructure coursework - it’s a pretty broad ranging course, starting with a few lectures on databases, followed with a load of stuff on operating systems, concurrency, memory management and networking, and finishing up with compilers, parsers and language design. &lt;/p&gt;
&lt;p&gt;We’re currently looking at how concurrency and multiprogramming are implemented in operating systems - I’ve read through our lecture notes today as well as looking at a couple of papers: Firstly, &lt;a href="http://www.sciencedirect.com/science?_ob=PublicationURL&amp;_tockey=%23TOC%235645%231981%23999879996%23298147%23FLP%23&amp;_cdi=5645&amp;_pubType=J&amp;_auth=y&amp;_acct=C000050221&amp;_version=1&amp;_urlVersion=0&amp;_userid=10&amp;md5=4fdae2bb6460282587c6f5753acec6fc"&gt;Gary Peterson’s brief lette&lt;/a&gt;r on his mutual exclusion algorithm, which is wonderfully concise and informative - it sets out the context of the problem and existing solutions, describes his algorithm, and gives a proof of its correctness in just two pages, while still being incredibly accessible to a newcomer to the field. Secondly, I read through&lt;a href="http://www.eecs.berkeley.edu/Pubs/TechRpts/1993/6022.html"&gt; Christopher, Procter and Anderson’s paper on their Nachos operating system&lt;/a&gt;, developed for teaching undergraduates at Berkley, which was a valuable overview of the field, and what I can expect from the course. I also did a fair bit of reading around the subject elsewhere, and I think I’m starting to get my head around various concurrency primatives in a way that I hadn’t managed before. &lt;/p&gt;
&lt;p&gt;I’ve also been pressing on with learning some stats - I’ve just started the section on conditional probability in my &lt;a href="http://books.google.co.uk/books?id=-pZX2KS2KqMC&amp;printsec=frontcover&amp;dq=probability+and+statistics+for+computer+science&amp;source=bl&amp;ots=_RqwElUrGk&amp;sig=yW_zn353_OC010uizzWfYnZErL4&amp;hl=en&amp;ei=UOLRTMbjAZa8jAe8gsToDQ&amp;sa=X&amp;oi=book_result&amp;ct=result&amp;resnum=1&amp;ved=0CBgQ6AEwAA#v=onepage&amp;q&amp;f=false"&gt;book&lt;/a&gt;, and it treats a subject I’ve previously found quite tricky in a way that’s both rigarous and straightforward - in particular, it contains a derivation of Bayes theorem that follows very naturally from the formulas for joint and conditional probability.  I’m planning to write about this in more detail soon.&lt;/p&gt;</description><link>http://timcowlishaw.co.uk/post/1473805241</link><guid>http://timcowlishaw.co.uk/post/1473805241</guid><pubDate>Wed, 03 Nov 2010 22:30:10 +0000</pubDate></item><item><title>Setting up a Python development environment on Ubuntu</title><description>&lt;p&gt;I’ve got to do a few assignments in Python for university, and wanted to set up my laptop (running Ubuntu Maveric) to do this. When I’m doing any Ruby development I use the excellent &lt;a href="http://rvm.beginrescueend.com/"&gt;RVM&lt;/a&gt; to create a personal (or even project-specific) development environment for my work, and wanted to do the same with Python, not least so that my tentative first experiments in it were sandboxed in some way (I have bad memories of messing up my &lt;a href="http://www.haskell.org/cabal/"&gt;Cabal&lt;/a&gt; install when hacking on some Haskell, causing &lt;a href="http://xmonad.org/"&gt;XMonad&lt;/a&gt; to fail to launch next time I rebooted.&lt;/p&gt;
&lt;p&gt;Happily, the &lt;a href="http://virtualenv.openplans.org/"&gt;virtualenv&lt;/a&gt; package provides a useful python equivalent to RVM. Simply:&lt;/p&gt;
&lt;pre class="brush: bash"&gt;sudo apt-get install python-pip python-virtualenv&lt;/pre&gt;
&lt;p&gt;As it sounds, python-virtualenv is the apt package that installs virtualenv - python-pip is a python equivalent of soemthing like &lt;a href="http://rubygems.org/"&gt;RubyGems&lt;/a&gt; which might come in useful later when I need to install libraries. Now set up a new virtual python environment:&lt;/p&gt;
&lt;pre class="brush: bash"&gt;virtualenv --no-site-packages ~/.python-local&lt;/pre&gt;
&lt;p&gt;This creates a fresh python install in the folder ~/.python-local - the no-site-packages option makes sure your local environment doesn’t import packages from elsewhere on the system- it’s totally stand-alone.&lt;/p&gt;
&lt;p&gt;Then, just make sure that the bin directory in your local python directory is on your path, before the system bin directories (so your local one takes precedence) - I use zsh, so that involved adding ~/.python_local/bin to this line in .zshrc, like so:&lt;/p&gt;
&lt;pre class="brush: bash"&gt;export PATH=/home/tim/.cabal/bin:/home/tim/bin:/home/tim/.python_local/bin:$PATH&lt;/pre&gt;
&lt;p&gt;Then close your terminal window, open a new one to allow the PATH changes to take effect, and marvel at your new sandboxed python install! (try ‘which python’, ‘which pip’ or ‘which easy_install’ if you don’t believe me!).&lt;/p&gt;
&lt;p&gt;There’s one gotcha however - you’ll notice that if you run virtualenv again (if you can’t get enough stand-alone python installations and just have to have MORE!), you’ll get an error:&lt;/p&gt;
&lt;pre class="brush: plain"&gt;Traceback (most recent call last):   File "/usr/bin/virtualenv", line 2, in      import virtualenv ImportError: No module named virtualenv &lt;/pre&gt;
&lt;p&gt;It’s pretty easily explained - the virtualenv command you called (in /usr/bin) called out to the python interpreter (now in ~/.python_local/bin, which obviously couldn’t find the virtualenv libraries that are installed in the system python installation. Simply install virtualenv into your new development sandbox and all is fine again:&lt;/p&gt;
&lt;pre class="brush: bash"&gt;easy_install virtualenv&lt;/pre&gt;</description><link>http://timcowlishaw.co.uk/post/1471639865</link><guid>http://timcowlishaw.co.uk/post/1471639865</guid><pubDate>Wed, 03 Nov 2010 17:13:00 +0000</pubDate></item></channel></rss>

