Topological sort of a DOT Graph

Today I needed to get a sequential execution order for a system that I already had a DOT dependency graph of, which I knew contained no cycles.

Currently I don’t officially have access to.. well, anything resembling a development environment at all really, so I was faced with the prospect of doing this in vba. As my masochism is underdeveloped I haven’t actually tried this yet, but given I can barely read vba I’d estimate this task at at least a few hours, with a worst-case blowout of a day.

Obviously I didn’t do that, so below is the code to do it in perl, research time 15 minutes, development time 5 minutes. Let me say that again: 20 minutes, versus a few hours. Multiply that out by the amount of time you hire programmers for and how much you pay them and see how well your “risk of getting a virus mitigated by locking down all IT resources” strategy is stacking up.

use Graph::Reader::Dot;
use Graph;

my $reader = Graph::Reader::Dot->new();
my $graph = $reader->read_graph($ARGV[0]);

my @sorted_nodes = $graph->topological_sort;

foreach(@sorted_nodes) {
  print $_,"\n";
}

Tl;dr Let the people doing the work decide on the tools.

(I used perl instead of ruby because I couldn’t find a gem to read DOT files)

The idea that I can be presented with a problem, set out to logically solve it with the tools at hand, and wind up with a program that could not be legally used because someone else followed the same logical steps some years ago and filed for a patent on it is horrifying.
John Carmack

There are two novels that can change a bookish fourteen-year old’s life: The Lord of the Rings and Atlas Shrugged.

One is a childish fantasy that often engenders a lifelong obsession with its unbelievable heroes leading to an emotionally stunted, socially crippled adulthood, unable to deal with the real world.

The other, of course, involves orcs.

@jeremydmiller who doesn’t know the original source

DRX - ruby object inspection

This is so freaking cool source

Steps to get running on ubuntu:

sudo apt-get install libtcltk-ruby tk-tile
sudo gem install drx
irb
irb(main):001:0> require 'rubygems'
=> true
irb(main):002:0> require 'drx'
=> true
irb(main):003:0> 123.see
=> nil
irb(main):004:0> 

Anyone who ever saw me use ‘ddd’ will understand why I love this.

Weird history

Ada Lovelace - Commonly known as the first programmer

chiefly known for her work on Charles Babbage’s early mechanical general-purpose computer, the analytical engine. Her notes on the engine include what is recognized as the first algorithm intended to be processed by a machine;

fathered by

Lord Byron - Famous poet, “mad, bad and dangerous to know” who used his place in the house of lords to support the Luddites

His first speech before the Lords was loaded with sarcastic references to the “benefits” of automation, which he saw as producing inferior material as well as putting people out of work.

I wonder if daddy was proud? :-)

Behaviour of next in collect

Basically, anyone got a better way to do this? :

irb(main):003:0> [1,2,3,4,5,6].collect { |v| next if v == 3; v * 7 }.compact
=> [7, 14, 28, 35, 42]

Let me know on twitter if you have a better way.

I oversimplified my example, it’s actually more like:

objects.collect do |obj|
  begin
    QueryPredicate.new(obj.parser.parse_internal)
  rescue ParsingException => e
    next
  end
end.compact

Which prevents me using the suggestion of

[1,2,3,4,5,6].reject{|v| v == 3}.map{|v| v * 7}

as I don’t have any way of telling what can be rejected from the set. Still, I learnt the “reject” keyword, which makes me happy.

Suggested improvement from colleague:

objects.collect do |obj|
  begin
    QueryPredicate.new(obj.parser.parse_internal)
  rescue ParsingException => e
    nil
  end
end
objects.compact!

Yeah that’s a bit better