Integral Trees by Larry Niven

Don’t you hate when you find a book built around a set of very intriguing ideas only to be disappointed by its underwhelming plot and bland characters? Disappointment was exactly what I felt after reading Lary Niven’s Integral Trees and it’s sequel The Smoke Ring which in my case came bundled as a single bound volume. The setting of the novels is fantastic, imaginative and scientifically plausible even if far fetched and unusual. Actual story? Not so much…

Integral Trees Book Cover

Integral Trees Book Cover

When I review hard SF, I often loathe to give away juicy details about the setting, because discovering them is part of the joy of reading such books. I don’t really have such reservations with Integral Trees because Niven front-loads most of the hard science into a gigantic expository dump in the first few dozen pages. Everything you need to know about the setting is condensed at the beginning of the book, accompanied by helpful diagrams that help you understand it. So I don’t really feel bad for spoiling it here.

Imagine a binary solar system composed of a neutron star and a regular main phase yellow star. The neutron star has a single captured satellite, which happens to be a gas giant in an unusually low orbit just beyond it’s Roche limit. Because of the tidal forces acting on the planet in such a low orbit most of the lighter gasses from it’s atmosphere have been siphoned out into a vast gas torus surrounding the neutron star. The torus is about a million kilometers thick, and it’s dense core (known as the “Smoke Ring”) is composed almost entirely from nitrogen, oxygen and hydrogen forming a breathable atmosphere. The companion yellow star provides ample sunlight allowing life to flourish and evolve within the narrow gas ring.

The Smoke Ring is essentially a world of endless sky. There is no solid ground anywhere within the ring, but water is plentiful. Of course since everything is in free-fall, it does not form lakes or rivers but rather coalesces into spherical floating globules. Most of plants and animals that inhabit the ring are free fall adapted, capable of limited flight and possess trilateral symmetry allowing them to see in all directions without repositioning. Plants, on average are fragile, spindly and tend to form dense clumps, using foliage and web-like branches for both photosynthesis and capturing and sieving up organic matter from the air, as it floats by.

Smoke Ring Jungles

Picture of the spherical plant life clumps within the smoke ring.

The one exception to this rule are the titular integral trees, which are absolutely massive. The largest of the trees grow up to about a hundred kilometers in length, and are tidally locked with respect to the neutron star. Their center of mass is located at the mid point of the trunk, and both ends terminate in a tuft of foliage. The tuft ends are typically subject to gale force winds which causes them to bend in opposite directions, giving the plants the characteristic, integral-sign shape after which they were named.

The tufts collect water and floating debris to and provide natural shelter for all kinds of smaller animals, and parasitic plants. The tidal forces create a gravity like effect, that pulls nearby objects toward the trunk. Any water that collects on the trunk is pushed towards the tufts, creating little streams and rivulets across the bark. As a result each tree is it’s own, tiny, self contained ecosystem.

This is probably why they were chosen by human colonists who discovered the torus roughly five hundred years before the events described in the books. The original settlers were mutineers who have rebelled against the oppressive totalitarian state, and escaped into the the smoke ring, and established a new civilization there. Most build communities within the tree tufts, or in the radial jungles. Because resources required to build industry (such as heavy metals) are scarce in the Smoke Ring they live simple rural lives, holding on to the few old technological gadgets they were able to preserve and keep in working condition. In most communities the post of a “Scientist” is akin to that of a shaman: a community healer and spiritual leader, who consults ancient records to get insights into the true nature of things.

Expanded Cover

The picture from the expanded cover, featuring the bending trunk of an Integral Tree.

This is a fantastic, and incredibly imaginative setting. But once you read through the first chapter, you basically know all there is to know about it, at which point you might as well just close the book and do something else. The rest of the book is just boring people, having boring adventures. The few revelations about the setting that have not been jam-packed into the introduction, are delivered in the laziest way possible. In most cases the characters simply read a paragraph of notes left behind the original settlers, and then complain that they don’t understand what it means. It is obvious that these exposition dumps are intended for the readers, since not even the tribal “Scientists” remember enough of the old science to decipher them fully.

Bland characters and less than stellar conflict and resolution are not uncommon problems in the realm of hard SF. Writers who can deliver compelling science lectures wrapped inside space adventure novels often struggle to portray believable, characters that readers can relate to. The undisputed masters of the genre however tend to be aware of this, and route around the problem. Gregg Egan for example is really good at centering his novels around some novel scientific quagmire or mystery that the characters seek to solve. Even though some of his characters may be only broad personality sketches, they become relocatable due to sharing a common goal with the readers: the need to solve and unravel the same scientific puzzle. Egan also tends to make his protagonists somewhat odd, alien or somehow exceptional and unique: they are genderless artificial intelligences, disembodied post-humans and etc.. This often tricks the readers to latch that much harder onto the few human qualities they do display.

Niven’s approach is the direct opposite of this. His characters are bland every-men, who neatly fit into a few standard archetypes they never seem to outgrow. All the interesting information in front loaded, or delivered in exposition globs, meaning he can’t trickle small revelations about the nature of the smoke ring throughout the novel. His book is constructed to rely on the strength of his characters. Unfortunately, none of them are likeable enough for one to care about their struggles.

The cultures of the Smoke Ring are also extremely rudimentary and boring. One would think that since travel is difficult, and inhabitants for different trees rarely come into contact with each other, their cultures would vary. One would think that inhabitants of a free floating spherical jungle would live a drastically different than people who inhabit the trees. But the differences between all these people are mostly superficial. They use different governing systems (some more oppressive, other more democratic) but that’s about it.

People of the Smoke Ring have no religions, no legends and no superstition. Their lives seem impossibly boring, shallow and petty. Even the one mildly interesting plot hook is completely wasted. The ancient ramjet used by the original colonists is still orbiting the gas torus. It is controlled by an AI which is still loyal to the state, and has spent the last five centuries plotting how to re-integrate the free people of the Smoke Ring back into the State. The ship and the diabolically intelligent entity that controls it are a constant threat, which never fully pays off.

The book as a whole is disappointing. A fantastic setting ruined by poor execution, bland characters and uninteresting conflict.

Posted in literature | Tagged , | 2 Comments

Unit Testing Sinatra Apps

Testing is the safety harness for your code. They are not magical, and they will not prevent you from missing bugs you did not anticipate. They do however automate the boring chore of making sure various edge cases and special conditions do not blow up your code. As such they help to catch bugs you could have totally anticipated, but did not bother checking for because of reasons.

Manually testing web apps is a nightmare because it forces you to pull up a web browser, refresh pages, make sure you clear your cache between tests, etc.. No one wants to fiddle with the browser all day, so automating basic testing tasks will not only save time, but also greatly improve your workflow.

Unfortunately testing web apps can be a bit tricky sometimes. They are designed to be accessed over the network, and to render in a web browser, and so they require your test framework to do network-like and browser-like things to emulate those conditions. While unit tests for classes can be easily mocked, pretending to be a web browser is definitely non trivial. When I work with PHP I usually use the excellent Codeception tool-set to do acceptance testing. When I work in Node or just build front end stuff, I typically use Grunt with Phantom.js.

When working with the Sinatra framework, most unit/acceptance style testing can be easily done by using the minitest and rack-test gems. Let me show you how.

Let’s set up a simple Sinatra app. Our folder structure ought to be something like this:

myapp/
├── app.rb
├── Gemfile
├── public/
│   └── style.css
├── Rakefile
├── tests/
│   └── app_test.rb
└── views/
    ├── layout.erb
    └── main.erb

When setting up your dependencies in your Gemfile it is a good idea to isolate the test related gems from the actual run time dependencies. You can do this by using the group keyword:

1
2
3
4
5
6
7
source 'https://rubygems.org'
gem 'sinatra'
 
group :test do
  gem 'minitest'
  gem 'rack-test'
end

When deploying to production you can exclude any group using the –without argument:

bundle install --without test

If you are deploying to Heroku, they exclude test and development groups by default, so you don’t even have to worry yourself about it.

Here is a simple Sinatra app:

1
2
3
4
5
6
7
require 'bundler'
require 'bundler/setup'
require 'sinatra'
 
get '/' do
  erb :main
end

You know how this works right? The above will render the contents of main.erb and envelop them in layout.erb which is the auto-magical default template. For the time being lets assume that the contents of the former are simply the words “Hello World” and that the later provides a basic html structure.

To test this application we need to create a test file somewhere (I put them in the test/ directory) and inside create a class derived from Minitest::Test and include the Rack::Test::Methods mixin.

Mixins are a wonderful Ruby feature that let you declare a module and then use the include keyword to inject it’s methods into a class. These methods become “mixed in” and act as if they were regular instance methods. It’s a little bit like multiple inheritance, but not really.

In the example below, this gives us access to standard Rack/Sinatra mock request methods such as get, post and etc…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
ENV['RACK_ENV'] = 'test'
 
require 'minitest/autorun'
require 'rack/test'
require_relative '../app'
 
class MainAppTest < Minitest::Test
  include Rack::Test::Methods 
 
  def app
    Sinatra::Application
  end
 
  def test_displays_main_page
    get '/'
    assert last_response.ok?
    assert last_response.body.include?('Hello World')
  end
end

Once you invoke the mock request method (see line 15 above) the last_request and last_response objects become available for making assertions. The last_response object is an instance of Rack::MockResponse which inherits from Rack::Response and contains all the members and methods you could expect. For example, to check whether or not my app actually displayed “Hello World” I simply had to test if that string was somewhere inside last_response.body (see line 17).

To run this test you simply do:

ruby tests/app_test.rb

The minitest gem takes care of all the boring details. We just run the test and see the results.

Let me give you another example. Here is a bunch of tests I written when working on the Minion Academy web service. My goal here was to make sure my routing rules worked correctly, that the requested pages returned valid JSON objects, with the right number of nodes, and that no JSON would be generated if the URL was formatted wrong:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
  def test_json_with_1
    get '/json/1'
    assert last_response.ok?
    response = JSON.parse(last_response.body)
    assert_equal 1, response.count
  end
 
  def test_json_with_1_trailing_slash
    get '/json/1/'
    assert last_response.ok?
    response = JSON.parse(last_response.body)
    assert_equal 1, response.count
  end
 
  def test_json_with_0
    get '/json/0'
    assert last_response.ok?
    response = JSON.parse(last_response.body)
    assert_equal 0, response.count
  end
 
  def test_json_with_100
    get '/json/100'
    assert last_response.ok?
    response = JSON.parse(last_response.body)
    assert_equal 50, response.count
  end
 
  def test_json_with_alphanumeric
    get '/json/abcd'
    assert_equal 404, last_response.status
  end

Note that those are not all of the tests I have written for this particular bit, but merely a representative sample.

The neat thing is that these tests will seamlessly integrate with other unit tests you write against regular, non-Sinatra, non-Rack related classes. You can simply dump all the test files in the tests/ directory and then add the following to your Rakefile:

1
2
3
4
5
require 'rake/testtask'
 
Rake::TestTask.new do |t|
  t.pattern = 'tests/*_test.rb'
end

This will add a test task you can run at any time that will iterate through all the files matching t.pattern and run them in a sequence.

If you’re like me and you don’t feel content unless successful tests are rendered in green, and errors in bright red, I recommend using the purdytest gem which colorizes the minitest output. There are many test report filters out there that make the output prettier, but Purdytest probably the simplest and least obtrusive. You simply require it at the top of your test files and then forget all about it.

Posted in programming | Tagged | Leave a comment

Zero Effort Link Minification with WordPress

If you have ever linked to my blog, you might have noticed that my URL’s are absolutely monstrous in size. Not only is my long domain name rather long, but I also happen to use the “pretty” style of permalinks which includes full date and abbreviated post title.

There is of course nothing wrong with either of these things. Long domains may not easy to type but they can be memorable. Most people don’t even use the address box in their web browser (which used to drive me nuts until I learned to just accept it). These days it is all about on fuzzy search in Google so as long as someone can manage to type in something close to termanotely incaharet somewhere, they will find my blog.

Similarly, long permalinks are actually useful due to their descriptive nature. I like to be able to glance at a link and not only know what it is about, but also how long ago it might have been posted. I would not want to get rid of an useful feature like that.

That said, my links are just super long. Take this one for example:

http://www.terminally-incoherent.com/blog/2015/01/19/utility-spells-in-video-games/

It is an absolute beast, and I would love to have the option to shorten it when I post it on social media for example. Yes, Twitter does minify links by default but the truncated URL still looks quite ugly in your tweets.

I could use a third party minifier such as bit.ly or goo.gl but that is never a good idea. Not only does it obfuscate the links, but it also sets them up for possible breakage in the future when said 3rd party services shut down which is not uncommon. I have seen quite a few of them appear and go under in just last few years, and being backed by a big company does not seem to help. Google might not be going anywhere anytime soon, but they shut down their services all the time. Personally, I got burned twice with them. First time with Google Notebook (an Evernote precursor), and the second time with Google Reader. URL’s are supposed to be forever so I wouldn’t feel comfortable using any service that is not under my control. Ideally I would want to use my own domain for minification of links.

I noticed that WordPress already does support shortened links in a way. If you have permalinks enabled (and you should), WordPress calls your standard, long and “pretty” links the cannonical URL’s. However it also provides a so called shortlink for each post. You can see it shown in the post header on most themes:

<link rel='canonical' href='http://www.terminally-incoherent.com/blog/2015/01/19/utility-spells-in-video-games/' />
<link rel='shortlink' href='http://www.terminally-incoherent.com/blog/?p=18242' />

The shortlink format is actually the default style of WordPress URL’s you get if you can’t be bothered (or you are unable) to set up permalinks. It acts as a fallback, and allows you to access blog posts by their internal database ID even if the permalinks are not working correctly.

So if I wanted to, I could link to my posts using the shortlink format like this:

http://www.terminally-incoherent.com/blog/?p=18242

If you have a short domain name, this might be enough for you. Mine is still too long, and I absolutely hate parameters in the URL. IMHO, it looks unprofessional. However, knowing that this format exists allows you to shorten and prettify it using Apache redirects. For example, I could put the following line in my .htaccess file:

RedirectMatch ^/(\b\d+\b)/?$ /blog/?p=$1

This matches any URL that contains only numerical digits followed by an optional trailing slash, and seamlessly redirects them to the shortlink style URL format. This rule allows me to use something like:

terminally-incoherent.com/18242

Because of the way WordPress handles shortlinks, users who follow the link above won’t actually see it in the address box when the page loads. Instead WordPress will automatically unfold it to the “pretty” permalink format, which is exactly what I want.

This is a huge improvement. Still to long though.

To compress my addresses even further I purchased a brand domain: tein.co Unfortunately ti.co and in.co were already taken so this is the next best thing I could think of. It’s not pronounceable, but it is short, and visually similar to my long domain.

All that was left was to set the new domain to “web forward” to my actual blog URL and I was all set. I use iwantmyname as my registrar and it took literally 60 seconds to set it up:

Web Forwarding

Web Forwarding

From there it worked pretty seamlessly. If you are feeling lazy and you don’t want to type in my full web address you can now simply use tein.co. Similarly, every post now has a genuine short link (displayed under post title) in the format:

tein.co/18242

Because the entire thing is implemented via 301 redirects, if you post one of these short links on Twitter you will still get that sweet Twitter Card action.

So there you have it. Zero effort link minification using built in WordPress addressing scheme and a single Apache redirect statement.

Posted in sysadmin notes | Tagged , | 3 Comments