my recent reads..

Atomic Accidents: A History of Nuclear Meltdowns and Disasters; From the Ozark Mountains to Fukushima
Power Sources and Supplies: World Class Designs
Red Storm Rising
Locked On
Analog Circuits Cookbook
The Teeth Of The Tiger
Sharpe's Gold
Without Remorse
Practical Oscillator Handbook
Red Rabbit

Sunday, December 07, 2008

Code formatting and line continuations with Javascript and CSS

I've had a question up on stackoverflow recently in an attempt to get a nice solution for adding a glyph with CSS to indicate a wrapped line (e.g. in a command line sample).

With a few good suggestions, I had a reasonable solution but it still required a bit of manual markup to prepare the example. Then I saw Pranav Prakash's post about syntaxhighlighter by Alex Gorbatchev.

With a few tweaks (see the stackoverflow question for the details), I'm now able to combine the best of both worlds: great formatting and syntax highlighting with syntaxhighlighter and also line continuation glyphs. Here's an example of the result:

public class HelloWorld {

public static void main (String[] args)

{

System.out.println("Hello World! But that's not all I have to say. This line is going to go on for a very long time and I'd like to see it wrapped in the display. Note that the line styling clearly indicates a continuation.");

}

}


NB: if you have javascript disabled, or reading this through a newsfeed (or if I hit a bug) you may not see the full effect. Here's a screenshot of what should be appearing above:


Now I just need to go back and update the code formatting in all my old posts. Basket!

Sunday, November 30, 2008

Oracle Shell Scripting


I remember seeing Jon Emmons' announcement on the Oracle News Aggregator and I've had it in my "wanted" list on bookjetty for ages.

This week I discovered Jon's Oracle Shell Scripting: Linux and UNIX Programming for Oracle (Oracle In-Focus series) at the NLB and have just enjoyed a good read of it.

I wish more DBAs had read this book. In fact it should be mandatory to get an OCP certification!

Let's face it, most Oracle installations are running on a *nix variant, and you can't be a DBA if you are not comfortable at both the SQL*Plus and shell prompt. To be a good and efficient DBA in my book, I want to see evidence of thinking smart, and repetitive task automation. When I see so-called DBAs who are happy to type the same "select .. from v$.." query every day of their working life, I doubt their brain is switched on, and I find it really, really scary to think they have the sys/system passwords!

They say tool usage is a sure sign of advanced intelligence in birds. And the same applies to all of us in IT. The three examples I look for at an Oracle Database installation are:
  • RMAN
  • Grid Control
  • Shell scripts


If none of these are present, then I tend to presume the real DBA has long left the building. Even if you are using third-party alternatives, do you continue to re-evaluate the Oracle capabilities with each new release?

Jon Emmons' book is of course more focused than this. It perfectly fills a niche, with an approachable, practical and comprehensive coverage of shell scripting from a DBA's perspective.

I can see the ideal audience for this book is people who are reasonable familiar with Oracle administration but are new to shell scripting. This book will rapidly teach you all you need to know on the scripting side (and let you skip alot of stuff you can learn later).

In other words, if you are a DBA who has just been assigned to manage a Unix-based system for the first time in your career: get this book. Forget all the (great) general Linux/Unix/shell scripting books for now. Don't even think the Oracle docs will teach you what you need to know. Oracle Shell Scripting: Linux and UNIX Programming for Oracle (Oracle In-Focus series) is what you need!

If you are coming the other way though - an experienced Linux admin being told that from Monday you also need to manage an Oracle database - I'd say this book probably doesn't have much to teach you. There's much more you'd need to learn about Oracle first (after telling your manager he's crazy), and there are really no scripting tricks in the book that you shouldn't already know. The main benefit you get would probably be a few pages in chapter 6 that cover the tricks of using sqlplus in a shell script - all in one place rather than having to tease it out of the Oracle docs (or see this related question on stackoverflow).

Originally posted on It's a Prata Life.

Monday, October 27, 2008

Synchronising two directory trees - tree-sync 2.4

tree-sync.pl has had a little update thanks to a contribution from Dave Stafford.
  • Added option 'diff' to view only changes

  • Added option 'ignore' to exclude certain extensions

  • Added option 'brief' to remove src/dest directories in report view to make cleaner output

In the 2.4 release I've also added the 'force' option to control read-only file handling.

tree-sync.pl is a bit of a geeky tool, suitable for cases where you want detailed control over a file-based copy/mirror/backup process from the command-line. There are many flashier solutions available these days, but if tree-sync scratches your itch - go for it!

tree-sync.pl continues to be available on CPAN, but from the 2.4 release I have moved the source to github. If you have changes to suggest or bugs to fix, please go ahead and join this project.

Tuesday, October 21, 2008

Rolling Project Euler on Ruby

I first heard about Project Euler last week on the stackoverflow podcast. Michael Pryor (fogcreek co-founder) makes a quick side reference in discussion with Joel Spolsky, Jeff Atwood and the rest of the SO team.

Well I checked it out last week, got hooked and spent most of the weekend earning my "level 1" badge;-)

Aside from dusting off some long-forgotten and arcane knowledge from my youth, I found it a fantastic opportunity to stretch my fundamental ruby chops. In fact, I'd recommend a few questions at Project Euler as a right-of-passage whenever you are learning a new programming language.

I've only been using ruby for a year or so, and in that time thought I had picked up a fair bit. But I was still able to amaze myself at just how many of the problems were knocked over in just 1 or 2 lines with a bit of duck punching and liberal use of blocks with Enumerables.

I'm late to the Project Euler craze, so you will already find many people posting hints for specific questions if you just google. I thought I'd share some of the "common code" I've been building up as I go through the questions.

I put a recent copy of the source up on github for anyone who is interested (MyMath.rb), but what follows a sampling of some of the more interesting pieces.

First thing you will note is that I have written all these "common" routines as extensions to some of the fundamental classes in the ruby library: Integer, Array, String.

It doesn't have to be this way, and for less trivial activities you might be right to be concerned about messing with the behaviour of the standard classes. Maybe I'm still enjoying my ruby honeymoon period, but I do get a thrill out of being able to write things like
1551.palindrome?
=> true


Integer Extensions


It's just so easy to code up simple calculation and introspection routines..

class Integer
# @see project euler #15,20,34
def factorial
(2..self).inject(1) { |prod, n| prod * n }
end

# sum of digits in the number, expressed as a decimal
# @see project euler #16, 20
def sum_digits
self.to_s.split('').inject(0) { |memo, c| memo + c.to_i }
end

# num of digits in the number, expressed as a decimal
# @see project euler #25
def num_digits
self.to_s.length
end

# tests if all the base10 digits in the number are odd
# @see project euler #35
def all_digits_odd?
self.to_s.split('').inject(0) { |memo, s| memo + ( s.to_i%2==0 ? 1 : 0 ) } == 0
end

# generates triangle number for this integer
# http://en.wikipedia.org/wiki/Triangle_number
# @see project euler #42
def triangle
self * ( self + 1 ) / 2
end
end


Prime numbers feature heavily on Project Euler, and I think calculating a prime series was my first lesson on why you can't brute-force everything;-) Enter the Sieve of Eratosthenes and related goodness..
class Integer 
# http://en.wikipedia.org/wiki/Prime_factor
# @see project euler #12
def prime_factors
primes = Array.new
d = 2
n = self
while n > 1
if n%d==0
primes << d
n/=d
else
d+=1
end
end
primes
end

# http://en.wikipedia.org/wiki/Divisor_function
# @see project euler #12
def divisor_count
primes = self.prime_factors
primes.uniq.inject(1) { |memo, p| memo * ( ( primes.find_all {|i| i == p} ).length + 1) }
end

#
# @see project euler #12, 21, 23
def divisors
d = Array.new
(1..self-1).each { |n| d << n if self % n == 0 }
d
end

# @see project euler #
def prime?
divisors.length == 1 # this is a brute force check
end

# prime series up to this limit, using Sieve of Eratosthenes method
# http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
# @see project euler #7, 10, 35
def prime_series
t = self
limit = Math.sqrt(t)
a = (2..t).to_a
n = 2
while (n < limit) do
x = n*2
begin
a[x-2]=2
x+=n
end until (x > t )
begin
n+=1
end until ( a[n-2] != 2 )
end
a.uniq!
end

# @see project euler #23
def perfect?
self == divisors.sum
end

# @see project euler #23
def deficient?
self > divisors.sum
end

# @see project euler #23
def abundant?
self < divisors.sum
end
end


Next we visit the Collatz conjecture and an interesting routine to make numbers "speak english"..
class Integer     
# http://en.wikipedia.org/wiki/Collatz_conjecture
# @see project euler #14
def collatz_series
a = Array.new
a << n = self
while n > 1
if n % 2 == 0
n /= 2
else
n = 3*n + 1
end
a << n
end
a
end

# express integer as an english phrase
# @see project euler #17
def speak
case
when self <20
["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten",
"eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen" ][self]
when self > 19 && self < 100
a = ["twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"][self / 10 - 2]
r = self % 10
if r == 0
a
else
a + "-" + r.speak
end
when self > 99 && self < 1000
a = (self / 100).speak + " hundred"
r = self % 100
if r == 0
a
else
a + " and " + r.speak
end
when self > 999 && self < 10000
a = (self / 1000).speak + " thousand"
r = self % 1000
if r == 0
a
else
a + ( r <100 ? " and " : " " ) + r.speak
end
else
self
end
end
end


Calculating integer partitions is one of my favourites ... a nice, super-fast recursive algorithm. For problems like "how many ways to make $2 in change?"
class Integer 

# calculates integer partitions for given number using array of elements
# http://en.wikipedia.org/wiki/Integer_partition
# @see project euler #31
def integer_partitions(pArray, p=0)
if p==pArray.length-1
1
else
self >= 0 ? (self - pArray[p]).integer_partitions(pArray ,p) + self.integer_partitions(pArray,p+1) : 0
end
end
end


Finally, rotations and palindromes (base 2 or 10): methods that rely on some underlying String routines that come later...
class Integer 
# returns an array of all the base10 digit rotations of the number
# @see project euler #35
def rotations
self.to_s.rotations.collect { |s| s.to_i }
end

# @see project euler #4, 36, 91
def palindrome?(base = 10)
case base
when 2
sprintf("%0b",self).palindrome?
else
self.to_s.palindrome?
end
end
end


Array Manipulations


Array handling is particularly important. Start with some simple helpers, then move onto greatest common factor and a couple of least-common multiple implementations. My favourite here - lexicographic permutations.
class Array

# sum elements in the array
def sum
self.inject(0) { |sum, n| sum + n }
end

# sum of squares for elements in the array
# @see project euler #6
def sum_of_squares
self.inject(0) { |sos, n| sos + n**2 }
end

# @see project euler #17
def square_of_sum
( self.inject(0) { |sum, n| sum + n } ) ** 2
end

# index of the smallest item in the array
def index_of_smallest
value, index = self.first, 0
self.each_with_index {| obj, i | value, index = obj, i if obj<value }
index
end

# removes numbers from the array that are factors of other elements in the array
# @see project euler #5
def remove_factors
a=Array.new
self.each do | x |
a << x if 0 == ( self.inject(0) { | memo, y | memo + (x!=y && y%x==0 ? 1 : 0) } )
end
a
end

# http://utilitymill.com/edit/GCF_and_LCM_Calculator
# @see project euler #5
def GCF
t_val = self[0]
for cnt in 0...self.length-1
num1 = t_val
num2 = self[cnt+1]
num1,num2=num2,num1 if num1 < num2
while num1 - num2 > 0
num3 = num1 - num2
num1 = [num2,num3].max
num2 = [num2,num3].min
end
t_val = num1
end
t_val
end

# http://utilitymill.com/edit/GCF_and_LCM_Calculator
# @see project euler #5
def LCM
a=self.remove_factors
t_val = a[0]
for cnt in 0...a.length-1
num1 = t_val
num2 = a[cnt+1]
tmp = [num1,num2].GCF
t_val = tmp * num1/tmp * num2/tmp
end
t_val
end

# brute force method:
# http://www.cut-the-knot.org/Curriculum/Arithmetic/LCM.shtml
# @see project euler #5
def lcm2
a=self.remove_factors
c=a.dup
while c.uniq.length>1
index = c.index_of_smallest
c[index]+=a[index]
end
c.first
end

# returns the kth Lexicographical permutation of the elements in the array
# http://en.wikipedia.org/wiki/Permutation#Lexicographical_order_generation
# @see project euler #24
def lexicographic_permutation(k)
k -= 1
s = self.dup
n = s.length
n_less_1_factorial = (n - 1).factorial # compute (n - 1)!

(1..n-1).each do |j|
tempj = (k / n_less_1_factorial) % (n + 1 - j)

s[j-1..j+tempj-1]=s[j+tempj-1,1]+s[j-1..j+tempj-2] unless tempj==0
n_less_1_factorial = n_less_1_factorial / (n- j)
end
s
end

# returns ordered array of all the lexicographic permutations of the elements in the array
# http://en.wikipedia.org/wiki/Permutation#Lexicographical_order_generation
# @see project euler #24
def lexicographic_permutations
a=Array.new
(1..self.length.factorial).each { |i| a << self.lexicographic_permutation(i) }
a
end

end


String Helpers


Last but not least, some String methods that just make things so much easier...
class String

# sum of digits in the number
# @see project euler #16, 20
def sum_digits
self.split('').inject(0) { |memo, c| memo + c.to_i }
end

# product of digits in the number
# @see project euler #8
def product_digits
self.split('').inject(1) { |memo, c| memo * c.to_i }
end

#
# @see project euler #4, 36, 91
def palindrome?
self==self.reverse
end

# returns an array of all the character rotations of the string
# @see project euler #35
def rotations
s = self
rots = Array[s]
(1..s.length-1).each do |i|
s=s[1..s.length-1]+s[0,1]
rots << s
end
rots
end

end


With all the above in place - and with the aid of a few brain cells - some deceptively complicated questions (like "How many different ways can £2 be made using any number of coins?") are essentially one-liners:
require 'benchmark'
require 'MyMath'

Benchmark.bm do |r|
r.report {
answer = 200.integer_partitions([200,100,50,20,10,5,2,1])
}
end

Love it;-)

Tuesday, October 07, 2008

Best Oracle OpenWorld 2008 quote so far..

WSJ blogger Ben Worthen on the HP Oracle Exadata Storage Server:
Oracle now has a device that is kind of like an iPod except that it is a lot bigger and a lot more expensive and not as cool.


"... priced at US$4,000 per terabyte of storage, plus the database license costs" Oh my.

Sunday, October 05, 2008

On context paths in Java EE

I was recently involved (tangentially) in an exercise to migrate a tomcat-based JSP application to Java EE packaging, which had me taking a fresh look at the concept of context paths and considering best practices for handling them.

When you package and deploy a Java EE web application, it has a context-root which effectively becomes the path on your application server that the application is available under. For example, the following module definition would setup MyApp to be available under http://server.domain/myapp/
<module>
<web>
<web-uri>MyApp.war</web-uri>
<context-root>myapp</context-root>
</web>
</module>

Context paths make it possible to host many applications on the one server as long as you keep the paths unique. As advised in Build to Spec! Part II:
Always specify a unique context root for every Web application you deploy to avoid naming collisions with applications already deployed.

It is possible to install an application with a context root of "/" but there are two considerations to bear in mind:

  1. Applications servers will usually have a default application already installed under "/" which would need to be removed first.

  2. The reason why the default application exists is to host resources that are not packaged as a web application (which may or may not be a concern, depending on what you are serving).


Problems arise when applications are coded with implicit assumption or explicit reference to the context path they will run under.

This is often the case - as I discovered - when migrating simple JSP applications to Jave EE packaging. Either the app assumes it will run from "/", or it has hard-coded paths under the root.

It can also occur in applications designed to be packaged as a .war or .ear file, if the developer assumes that the context-path will remain the same and does some hard-coded shortcuts. This breaks the Java EE separation of duties design, and prevents the system administrator from chosing to deploy the application on another context path (if, for example, there is a conflict with another application).

What the Specs Say


The JSR 53: JavaTM Servlet 2.3 and JavaServer PagesTM 1.2 Specifications define the context path concept, and some relevant API features.

Firstly there is getContextPath() which allows you to obtain the context path.

There's always been some doubt as to how sendRedirect() should behave though, but now that is cleared up in the 2.3 spec. From Servlet 2.3: New features exposed
And finally, after a lengthy debate by a group of experts, Servlet API 2.3 has clarified once and for all exactly what happens on a res.sendRedirect("/index.html") call for a servlet executing within a non-root context. The issue is that Servlet API 2.2 requires an incomplete path like "/index.html" to be translated by the servlet container into a complete path, but doesn't say how context paths are handled. If the servlet making the call is in a context at the path "/contextpath," should the redirect URI translate relative to the container root (http://server:port/index.html) or the context root (http://server:port/contextpath/index.html)? For maximum portability, it's imperative to define the behavior; after lengthy debate, the experts chose to translate relative to the container root. For those who want context relative, you can prepend the output from getContextPath() to your URI.


How to Retrofit Correct Context Path Handling


Migrating an application to Java EE packaging can be a it of a nightmare if url references are not nicely relative, and avoid any assumptions about the full path to the application.

Obviously, in this situation you probably can't avoid going in to clean up the code at some point.

But there are some tricks that can be used to delay that activity.

I've experimented with using servlet filters to do rewrites on the oubound HTML, and that seems to work fine. The filter intercepts all the output of the application, and can be used to fixup text/html or css using regex replacements, and even change the sendRedirect behaviour if desired. But it does introduce some overhead, and I wouldn't see it as a permanent solution. (see EnforceContextRootFilter-1.0-src.zip for all the lowdown on the servlet filter approach, including code you can use and adapt if it meets your needs)

Saturday, October 04, 2008

restful_authentication and OpenID with Rails 2

Note to self: Yes! managed to navigate the various OpenID resources for rails and managed to successfully setup OpenID with restful_authentication on Rails 2.1.

There are a few tricks to be aware of. Prompted by a question on stackoverflow.com, I thought I would post my notes here.

Installing restful_authentication


Usually, you will be plugging open_id_authentication into your app's identity management framework. One of the most popular - and the one I've been using of late - is restful_authentication.

Getting restful_authentication working seems to require a few tweaks however - at least for the latest version found up on github.

Firstly, I've had no success directly installing it using the plugin script like this:
ruby script/plugin install git://github.com/technoweenie/restful-authentication.git

Rather, I've had to manually clone the github repository and manually setup the plugin directory:
$ git clone git://github.com/technoweenie/restful-authentication.git
$ mv restful-authentication/ myapp/vendor/plugins/restful_authentication
$ rm vendor/plugins/restful_authentication/.gitignore
$ rm -fR vendor/plugins/restful_authentication/.git

Note that I'm cleaning up some of the git bits, and also changing the plugin directory name to use an underscore rather than a hyphen (Rails usually complains to me otherwise).

Setting up restful_authentication is then pretty straight-forward:
$ mkdir lib
$ ruby script/generate authenticated user sessions
$ rake db:migrate

Note: if you don't already have the 'lib' directory in your application, it must be created first, otherwise the generator will fail.

Installing open_id_authentication


Ryan Bates' Railscast on Openid is the best thing I've found to follow. Even though it was recorded with Rails 1.2.3, I've been able to successfully follow the tutorial with Rails 2.1.0. The only point to note is that for:
gem install ruby-openid

I installed 2.1.2, rather than the 1.1.4 used in railscast.

Installing open_id_authentication is then a doddle.
$ ruby script/plugin install open_id_authentication

Follow the Railscast from this point to integrate OpenID with restful_authentication.

Using restful_authentication on heroku


The plugin installation problems mentioned above also mean that you need to use a few tricks to get it working in a heroku-hosted application. I've found it best to clone your heroku app and add the restful_authentication plugin locally, and then git push it back to heroku when done.

Saturday, September 20, 2008

Show the Whale!

Adam Keys and Geoffrey Grosenbach introduced the term for 2008 on the rails podcast: show the whale.

I think it's perfect (meaning site down/build broke etc), and in my lexicon already!

==> No, this is not the official fail whale logo! The real one was done by Yiying Lu, a talented young designer from China/Sydney, who is now world famous thanks to twitter's stability problems.

Thursday, September 18, 2008

Code Like a Rocket Scientist


Do. Or do not. There is no try. -- Jedi Master Yoda

The Seven Secrets of How to Think Like a Rocket Scientistby Jim Longuski is a great book. It's almost a pattern language for innovation and getting things done. (I reviewed it in a little more detail here)

Longuski's intent is clearly to crystallize some useful patterns from the life of a "rocket scientist" and recommend them for general use. He successfully pulls it off and in a way that doesn't come over as elitist or sycophantic.

As a little thought experiment, I was interested to see how one might apply his ideas to the arena of coding or software development.

The "seven secrets" actually encompass 50 lessons in all, so this post soon got a bit out of hand!

Anyway, this is what I came up with ... so enjoy, and let me know your own thoughts!



1. Dream


Imagine It


You'll never achieve what you can't even imagine. That's good general advice for life. When it comes to our software efforts though, how much time do we really spend letting our imaginations run wild before shifting to a convergent thinking mode and start drilling down on the solution?

Work on the Big Picture


Every journey begins with the first step; a cathedral gets built brick by brick. But without the big picture, we are lost with a pile of bricks.

Arguably the technology world is too obsessed with the big picture. Think frameworks to end all frameworks, and our constant reinvention of the perfect computing paradigm: client-server to network-computer to EAI and SOA.

But perhaps that is a sign that we don't spend enough time deeply thinking out the big picture and thus we are stuck leapfrogging from one 80% solution to the next. Who is the programming equivalent of Einstein with his general theory of relativity and lifelong search for a unified theory of everything? Or are we still waiting for that person to be born?

Aim High


It goes without saying that you must aim high in order to achieve great things.

In software, I think it's actually rather common to have high goals in terms of functionality. Often our problem is that the goals are found to be too high at the end of the day. Massive scope slash, pulled features and death-marches result. But remember this is the "Dream" stage. If there is a failure, it is not in the dream, it is skipping straight to "Stage 7. Do"!

One area where our dreams tend to lack ambition is quality. Peopleware has a lot to say on this subject!

BS!


Encouraging a bit of BS is a good way of knocking the stiffness and formality out of the process. Which is what you need if you are looking for creativity, even if your code is "serious stuff".

There's also good logic here. When you invent the most outrageous porkers, you are probably using the technique of inversion - you are purposely searching for inspiration outside the nominal constraints of your problem. In other words, the bullshit artist naturally lives outside the box. Which is where you would expect to find the breakthrough idea of course, right? Make sense, or is that just a prime example of good BS itself!?

Brainstorm



Create Desire



Tell a Story



Sleep on It


Literally. As in: work on a problem. Go to bed. Wake up in the morning and find the solution is within your grasp.

"Sleep on It" is common folklore, but Longuski's own experience lead him to believe it held some truth.

In Brain Rules, John Medina presents more fascinating research that demonstrates the effect. Not only are problems more easily solved, but having slept on a problem, you are more likely to make a creative leap to a better solution.

Interestingly, Medina's work also demonstrated proved the truth another bit of folklore: the natural orientation of some people to be early birds, and others to be night owls.

So in a software development setting, we would be wise to take advantage of this knowledge:
  • If you are trying to crack a hard problem, pulling an all-nighter is a dumb thing to do. Work it, get some sleep, then come back to it in the morning.

  • Know who your night owls and early birds are. If you want the worst productivity possible, making night owls struggle in at 7am and early birds work late into the night.


Think JFK


Who is the JFK, the visionary, for your software project? The one person you all turn to, who helps you believe the impossible might actually be possible, and more importantly nurtures the desire to go for it?

Not all projects merit "man on the moon" scale leadership of course. But personally, I'm not interested in working on a project that doesn't have a clear goal. And all goals require at least a little vision to be tangible.

So whatever the project, its worth thinking about whether you need a 2 foot, 5 foot or 6 foot JFK. And who will that be?

Is it you? Are others waiting for you to stoke up the courage to play that role? Carpe diem!

2. Judge


Get Real


DeMarco & Lister coined the brilliant term "Management By Hyperbole" in Peopleware. Which I think hits too close to home in many software development shops. Everyone is going to be the next Google, right?

But sometimes you just need to get real, toss the crackpot ideas, and get on with it.

Play Games


.. and then get back to work please. You are not Matt Broderick.

Simulate It


The tooling in IT is getting to the stage where simulation is a realistic possibility in routine development. Take Oracle's Real Application Testing for example.

Run a Thought Experiment


The cheapest prototype of all.

Know Your Limits


I'm an optimist without illusions -- JFK


Postscript: Michael clued into the fact that this quote is wrong; it should be "I'm an idealist without illusions". Either I mis-typed or the book is wrong. The sentiment remains however, or we could now quote Obama with "I'm An Optimist, Not A Sap" ;-)


Weigh Ideas



3. Ask



Ask Dumb Questions



Ask Big Questions



Ask "What If?"



Ask "Animal, Vegetable or Mineral?"



Ask Just One More Question



4. Check


Prove Yourself Wrong


This immediately brings testing to mind. Make sure you put on the black hat (in both the hacker and deBono sense) when unit testing. Don't just write tests that prove things work, write tests for the failure modes and boundary conditions too.

But we know that already, and usually try for some level of rigorous testing.

Where we probably need to take this advice more to heart is at the front-end of the process: requirements, architecture and design.

Have you ever seen a new architecture, specification or design get approved with only cursory review? And perhaps reviewed by people who were not really motivated or perhaps even qualified to do a thorough job?

I have. And you know who will suffer for it: the brave team charged with implementing and supporting the system.

As we play the role of analyst, architect or designer we should make time to do a thorough critique. Try and break what you have conceived. Admittedly, that can be a hard thing to do. So invite a colleague to help you to try and break the design - an invitation not many would refuse! Do it, even if it's not in the project plan.

Inspect for Defects


The IT industry has adopted the quality mantra from manufacturing, but unfortunately our adoption is still highly selective.

The typical software testing method is akin to classical "quality by inspection".
Poke it, prod it, and raise a ticket if it breaks.

That's about as advanced as weaving textiles with steam-driven looms.

We are seeing more practices that emphasise "quality by design" however, and that's a good thing. For example, the test-first and test driven development movements try to help us to assure quality right at the first gate.

A big area for improvement seems to be a general focus on addressing systemmic factors in quality. Fix a bug? What about getting to the root cause of why that bug existed in the first place? Simple techniques like 5 whys can help get us out of a rut.

Have a Backup Plan


I learned this lesson good while doing IT support. Desperate users, desperate situations. You soon discover the importance of always knowing how to retrace your steps, and always having a contingency when you are about to do something that could smoke the users' data (or the hardware).

When the walls are buring, there's nothing like the confidence that comes from having backup plans well-ingrained as your standard practice. It can mean the difference between cool, calm success and landing a bloated fail whale.

It is the same idea I adopt when using source code control. I'm no fan of the school of thought that says only commit at the end of the job. Commits are my breadcrumbs that mark every step, and prevent bad changes from invalidating a whole coding session.

Do a Sanity Test


A good technique to apply to the next social-network-crowdsourcing-prosumer-2.0 business plan you see.

But equally valuable for more technical work. Prime candidates for a shrewd eye are server sizing, that convoluted custom framework design, and integration architecture.

Check your Arithmetic



Know the Risks


Most projects have some form of risk analysis process. Unfortunately, in my experience, most are cursory point-in-time assessments, with a half-hearted consideration of mitigations. You might do just as well getting a tarot reading.

Risks are like enemies ... hold them close, and know them well.

Thinking back over the recent projects I've managed, I realise that they all have some aspect of the plan that has been specifically arranged because of the understanding of the risks we faced. My three favourites:

  • Scheduling specific proof-of-concept activities at the very front of the project to eliminate risks or put mitigations to the test.

  • Including a performance test, whether the client required it or not. (every well-run performance test I have been involved with has identified at least one issue worth fixing. An issue that would otherwise have gone undetected prior to launch)

  • Re-sequence project activities to address high risk activities as soon as possible.



Question Your Assumptions



5. Simplify


Keep It Simple, Stupid


Get agile.

Draw a Picture



Make a Mock-up


Rapid prototypes are good. Probably the single biggest reason why Visual Basic 3 rocked the world. Suddenly, anyone could mock-up a working GUI app in no time at all.

Now we're seeing some fantastic examples of this same capability for the new internetworked world. WaveMaker may be the new PowerBuilder for the web. And heroku is making Ruby on Rails a hosted no-brainer.

It's an interesting co-incidence that the original Visual Basic was derived from a programmable form system, code name Ruby.

Name the Beasts



Look at the Little Picture



Do the Math



Apply Ockam's Razor



6. Optimize


Minimize the Cost



Minimize the Time



Be Mr Spock



Make it Faster, better, Cheaper (but not all three)


Isn't the paradox that almost defines the software industry and the bane of the fixed price contract?

In fact, classical project management long held that projects are defined by the triple constraints of scope, cost, and schedule. What was unsaid of course is that a fourth variable - quality - was assumed to be constant.

Which is of course a great joke.

But the even bigger joke is that most organizations still tend to behave as if all four variables can be dictated at will.

Kent Beck delivered the seminal piece (in the software context) addressing this issue with his rather radical proposal for Optional Scope Contracts. This is eminently sensible and usually the best reflection of the real objectives on the ground ("we only have this much money to spend on the project; must deliver something within 3 months; and can't compromise on this level of quality. So what we can adjust along the way is: scope!")

This is a key topic covered in the excellent book, Extreme Programming Explained.

Know When Bigger is Better


We have Moore's Law to blame for making this a perennial issue in IT.

Our systems comprise hardware and software. In crude terms, we seek the optimal balance between throwing hardware at the problem and choosing the most productive development tools.

The most exciting trend we are seeing now of course is the mainstream adoption of dynamic scripting languages (python, ruby and php) in problem domains that were once the exclusive province of "proper" (compiled) languages.

Let Form Follow Function


I'll resist making a joke on designers with their iMacs, photoshop and flash.

In truth, the leading ideas in graphic/web/interaction design are spot on. Check out Robert Hoekman's Designing the Moment for example (highly recommended).

But let's talk about coding for a sec. Have you ever spent time polishing code, refactoring, or building a really cool bell or whistle ... before you've got even the most basic features working properly?

Test-driven development, and an agile planning method like scrum are good anti-dotes for this!

Pick the Best People


Fred Brooks highlighted the huge variation in individual programmer productivity in the classic The Mythical Man-Month: Essays on Software Engineering, Anniversary Edition (2nd Edition).

For one of the best treatments of how to work with this reality, Peopleware is the canonical read:
The final outcome of any effort is more a function of who does the work than of how the work is done.
..
  • get the right people

  • make them happy so they don't want to leave

  • turn them loose

Make Small Improvements



7. Do


Learn by Doing


Real programmers know that what the docs say can be a universe away from how things actually work.

The only way you get to find this out (and hopefully make it all work) is to roll up your sleeves and do stuff.

Similarly, I believe that the only good architect is a practicing architect. If you are not taking every opportunity to work on your craft and keep current, you are ossifying.

The non-practicing architect is typically engaging in what I call "retrospective architecture": looking back at what worked in the past, codifying it as an "architecture" and promulgating it as a "standard". That's putting innovation in the deep freeze, and needs to be shunned!

Sharpen Your Axe


The best, smartest and most creative developers I know are really lazy. In a good way: work smart, not hard.

So while your "good" developer may spend 3 hours cutting and pasting SQL statements around to generate a test date set, the "lazy" developer has whipped up some sql/perl/awk script of Excel sheet that does the same in 5 minutes.

They love their tools, keep them good and sharp, and always on the lookout for a new one. Sharp tools make quick work of repetitive grunt work.

Correct It on the Way


It is salutary to learn that for the first US planetary mission to Venus, the rocket scientists actually argued about whether course corrections would be needed on the way. Thankfully, to avoid missing Venus by a million miles, trajectory correction maneuvers (TCM) became standard practice. It is of course how "smart" bombs work too.

And the same applies to software development. No matter how perfectly you have things planned out, there will always be some unpredictable external influences along the way. If you are not able to respond, then the outcome is no longer under your control.

This is a core belief of the agile movement, and enshrined in the agile manifesto.

Do Something


JFDI aka NIKE!

Doing software is a natural procrastinator's heaven on earth (or hell, depending on how firm those deadlines are).

As a well-practiced procrastinator and perfectionist myself, I've learned that "Do Something" is best advice ever.

The strange thing is ... it doesn't matter so much what you do (even to the extent of temporarily switching to another project or task). [this technique is discussed in another book I've read, but I forget the reference for now]

The important thing is you build some momentum and get moving. The more you do, the more opportunity you will have to explore alternatives and backtrack if necessary.

Don't Ignore Trends



Work on Your Average Performance


Software development is well known for its reliance on crash schedules and bucketloads of overtime to get things done.

For short periods of time, it may be a necessary and effective course of action to get you out of a desperate hole.

But over the course of a year, how does the productivity of such a shop compare with one that is operating at a more steady, controlled pace?

More than likely, the shop that just focuses on the bursts of peak performance, has a terrible long term average performance. Not only is average performance out of control because no-one is looking, but it's taking a pummeling from the burnout, turnover and very deep troughs in performance between peaks.

In software development, we should be much more concerned with improving our average performance than maximising our peak. "Situation nominal" as Houston would say.

Look Behind You


In software we conventionally think of using project postmortems and knowledge sharing initiatives to capitalise on our history. Everyone pays lip service to this idea, but in my experience few companies effectively practice it.

This is especially true in organisations driven by the quarterly numbers. It is easy to understand why: there's an inherent disincentive built into the system. The project is delivered and the value is captured, so a postmortem is just a cost that may not have a return for who knows how long (and you are not even sure who the beneficiary may be).

But even if the organisation doesn't see the value, as professionals you would expect we would take the initiative, right? Unfortunately not, because these project-level retrospectives tend not to make a great deal of intuitive sense. Have you ever delivered the same project twice? Isn't technology changing so rapidly that there's more value in learning the new, than tilling the soil of the old?

All these factors conspire to work against our ability to learn from the past at the organisational and individual level. Which is really bizarre when you think about it, given that being successful in the software industry almost demands a focus on continuous learning.

Personally, I think we have two powerful weapons at hand to battle this tendency:
  1. The patterns movement, which allows us to understand generic concepts and package them for reuse. We may never do the same project twice, but we will use the same approaches many times.

  2. The agile movement, which emphasises incremental effort, and an ever-increasing range of collaborative tools (all that "Web 2.0" stuff). Do your learning and sharing all the time. If you leave it to the end of the project, you already know when it will get done ... never!


Learn From Your Mistakes


Never! Or get the book and you might have a chance.

Wednesday, September 17, 2008

Oracle Community on Stackoverflow?

Stackoverflow quietly moved into public beta last week, and I'm stunned by how active it is already.

I'm looking at pages of really funky technical questions here that I haven't a clue how to answer ... and they all have at least one answer in response already.

There are even 106 questions in the "oracle" category.

If you haven't checked it out yet, Stack Overflow is simply a "programming Q & A site". As they say in the FAQ:
What's so special about this? Well, nothing, really. It’s a programming Q&A website. The only unusual thing we do is synthesize aspects of Wikis, Blogs, Forums, and Digg/Reddit in a way that is somewhat original. Or at least we think so.

I have big hopes for this site. The best developer communities I ever participated in were on the old network news/nntp, until it started getting overtaken by the web in the late nineties. Ever since then I've never really found an "optimal" community. It's either everyone (aka google), very specialist mailing lists, or web forums that tend to be too fragmented or low volume to be really useful.

I think this site has great promise to be a well-known meeting place for the world-wide developer community to collect and share knowledge. And I hope we see a huge "Oracle Community" presence (Open Metalink+Forums+Wiki 2.0).

There are two things that have really interested me about this site:

Firstly, it was started by Joel Spolsky and Jeff Atwood (Coding Horror). Nuff said.

Second has been the community engagement during the development process. They've had a podcast which I've been listening to for the past 21 weeks. It's a great fly-on-the-wall kind of experience, having the chance to listen to the developers discuss the site while they are still building it. I hope we hear more development done this way.

Do you have a question or maybe some answers? I really recommend everyone should take the plunge and test it out.

Any site that spawned a parody site even before it was launched can't be all bad!

Wednesday, August 27, 2008

Reflections on a learning model

The conscious competence learning model has uncertain origins, but is probably the best known model for learning. Maybe that's because it is so simple and intuitive - I suspect making it exactly the right kind of 'model' to be picked up by the business book and management consulting fraternity.

It seems to me best applied to the development of "skills" (like riding a bike or programming in python), and less so to changing bahaviour or habits (like giving up smoking).

But for skills it works really well, and the simple 2x2 matrix of conscious-competence yields lots of interesting observations to ponder.


That's my version of the matrix. I re-label the "conscious" axis as either "self-conscious" (as in you are painfully aware that you can't do something), or "automatic" (where you have reached the stage where performance is reflexive).

Where you start, where you get to, and the path you take are really dependent on the situation and the individual. In the picture above, I've indicated a starting point of where you are self-conscious about the fact you can't do something; although the literature talks about the strict theoretical starting point of being totally unaware you can't do something (automatic - cannot do in the diagram).

So anything interesting to note?
  • Progressing from knowing you can't do something to thinking you can (the redish line above) is, I think, a perfect defintion of what we call "blur like sotong" in Singapore

  • How straight-line your pregession towards automatic-can do is probably a good guide of "natural ability"

  • Learning (or training, education and guided practice) tends to shift you up the scale of competence only - since it is more about giving you the knowledge and techniques to do the job 'right'

  • Experience (or practice with reflection) tends to move you up the conscious scale towards the point where it is automatic.



So is this model of any practical use? As a point of reflection on your own, or your collegues situation, I think it can be a good but crude diagnostic. It makes you remember things like just plain training needs to be coupled with real experience to get you all the way up the curve.

Tuesday, July 29, 2008

Heroku - Ruby in the Sky with Diamonds

I've been using Heroku since I heard about it on the Ruby on Rails podcast. It offers a hosted Rails development environment (all web-based), with instant deployment ... essentially you are running your dev, test and production environments 'in the cloud'. Heroku themselves use Amazon S3 I think.

It's worth checking out, even if you are not specifically interested in rails. A great example of how to operate 'up in the clouds'.

A couple of key things I've learned/noted in working with heroku..

Disabling the heroku toolbar


You probably don't want the heroku toolbar appearing for public users of your application (and I found it had some issues with IE). Disabling the toolbar is done by creating a file config/heroku.yml:
toolbar_collaborators: true
toolbar_public: false
request_timeout: 10

(picked this tip up from the mailing list)

Running with Rails 2.1


Rails 2.0.2 is the default, and 2.1 support took a while to arrive. It's here now. Simply update your config/environment.rb file to specify..
RAILS_GEM_VERSION = '2.1'

Distributed Version Control


Version control using git is rolled into heroku. And if you want to develop locally, there's a heroku gem that simplifies setting up your local clone. Once git and the heroku gem are installed, a typical session goes like this:
heroku create myapp
heroku clone myapp
cd myapp
ruby script/server
[..work locally for a while..]
git add .
git commit -m "some changes made locally"
git push
[..work on the server for a while and commit..]
git pull


Postscript Aug-09: heroku have since split their services in two: herokugarden.com, which includes the online, web-based editor, and heroku.com which is intended for high-performance production deployment (with no online editing)

Monday, July 07, 2008

OpenID - the missing spice in Enterprise 2.0?

I have been playing around with OpenID recently and considering its significance. OpenID offers a "single digital identity .. you can login to all your favourite websites", and its adoption is rapidly accelerating especially since services like Yahoo and Blogger have added OpenID support to the many millions of existing user accounts.

Maybe I'm missing something here, but I am surprised by the lack of attention OpenID is getting in the enterprise context.

And when it is considered, it is often as an either/or proposition. As Nishant Kaushik writes in his excellent identity blog:
.. simple web applications with minimal needs could get away with simply supporting OpenID. But that should not be confused with not requiring a full-fledged identity services infrastructure where appropriate.
I think this is somewhat misdirected; certainly not the whole story. OpenID-enabling existing applications for an external audience is already a trivial exercise. It's a simple API, and plugins or toolkits are available for most programming environments. I think the much bigger deal is looking at OpenID from the opposite perspective - using enterprise security infrastructure to support OpenID authentication.

In my view, OpenID is key to unlocking the true potential of "Enterprise 2.0", which is what I wanted to discuss here to try and explain my thoughts and get some feedback.

It may also lead us to think more clearly about what Enterprise 2.0 really is. This is the current definition up on wikipedia:
Enterprise social software, also known as Enterprise 2.0, is a term describing social software used in "enterprise" (business) contexts..
The "social" nature of Web 2.0 tends to get the headlines, and hence by simple transference must be to basis of Enterprise 2.0. Right?

However, I'm not convinced.

Expecting Enterprise 2.0 success by simply adopting social networking features of Web 2.0 just seems a little naive. For a start, it implies and requires phenomenal change in the social and organisational fabric of a company to get off the ground, and there is no guarantee the benefits will be worth the pain of change. In many organisations it may just be too much, too soon, and fail completely.

Much as I love them, I don't even think "mashups" will be the killer app for Enterprise 2.0.

I think the key is a much more mundane aspect of Web 2.0 that gets lost in the facebook frenzy: the simple fact that users are being exposed to just so darn many useful tools in the ever increasing range of web applications (or Rich Internet Applications aka RIA).

We see unprecedented utility in the applications on offer, approaching what we expect from desktop or dedicated applications. And there is an incredibly low barrier to participation - you can sign-up within a minute and with usually no immediate associated cost.

So my main proposition is that the quick win for Enterprise 2.0 is for companies exploit the RIA boom. Spend your time figuring out how to exploit the burgeoning Web Application offerings. Do NOT waste your time scheming how to clamp down on usage, or on replicating the tools yourself.

The real and immediate benefits include reduced IT spend, better utility and happier users .. and set the stage for moving to the world of "Advanced Enterprise 2.0" with mashups and social networking for example.

The caveat of course is that the enterprise must ensure that matters of availability, data protection, confidentiality and privacy are not compromised in making such a move.

But this presents a dilemma for the enterprise. A tough choice between undesirable outcomes:
  1. ban and fore-go the benefits of adopting external Web Applications for enterprise use;

  2. allow their use, but lose control of the data, identities and secondary use derived from using such applications;

  3. or be faced with re-implementing all those cool features within the firewall (and risk becoming disconnected from the external audience).


This leads us to the present state-of-the-art in Enterprise 2.0, which must necessarily work around the constraints of the corporate boundary.

  • Some companies are adopting External Web Applications where they address a largely external audience (a good example is the official Oracle Wiki which runs on wetpaint). But here they remain disconnected from internal systems.

  • For internal adoption of Web 2.0 technology, IT departments are often re-implementing all the cool stuff inside the firewall.

    The CEO wants a blog? Customer support want to setup a wiki? Sure, we can install it. Where install means friggin' around for a few months to select and acquire the software, integrate it with the standard enterprise security/monitoring/hosting/blah environment, customise it to the corporate branding etc etc.
Toto, I've a feeling we're not in Kansas any more.. suddenly Enterprise 2.0 doesn't seem so exciting.

And I think it denies the dirty little secret that I bet exists in most organisation: your employees are already using these services for business purposes!

Using a personal credential for business purposes on an external service (whether OpenID or not) presents a whole range of challenges:

  • It is a provisioning nightmare. What happens when the employee leaves? The company doesn't control the account, so it can't be disabled. Whether you can remove access from any corporate data held in the external service depends totally on the application itself and how it was setup.

  • For the individual, there is a concern about keeping their professional and private lives appropriately separated. Too easy for your tweets to end up in the wrong hands in the wrong context.

So what's a girl to do? I'd suggest the answer is pretty obvious - we need corporate identities that can extend beyond the boundaries of the the organisation in a safe and controlled manner. This was the intention with SAML, but adoption has been slow - I suspect hindered by the complexity of its WS-Deathstar burden - and now OpenID is streets ahead in terms of acceptance (an interesting parallel to the adoption of SOAP v. REST for SOA Web Services).

In other words, the key to all of this IDENTITY.

Imagine for a moment the ideal world. I would have a corporate identity that works transparently within the enterprise and also for useful external services. And I could keep this quite separate from my personal identity (even though I may use some of the same external services on my own time).


The question now is whether we are far from being able to achieve this? I think not...

The call to Enterprise Identity Management Stack providers..

That means Microsoft, Oracle, IBM, Sun and so on.. the companies that produce the security software that is managing your enterprise identity every time you sign in to an enterprise application.

Many of these guys are members of the OpenID Foundation, but on the whole it is hard to find clear statements of direction at the moment, and the initial focus has been around demonstrations of how they can use credentials from other OpenID providers.

We need to see two things in particular:
  • OpenID provider support in their core identity management stacks, so that enterprise credentials can be used as OpenID credentials under the control of the company (e.g. they can be disabled when the employee leaves). Call that part of a "Service Oriented Security" strategy if you like, just make the option available;-)

  • Include that ability to blacklist/whitelist sites that the credentials can be used for.

    There will always be good reasons why certain Web Applications may be off limits for corporate use. For example, a law firm may not be able to use Google Documents because of jurisdictional concerns.


Dion Hinchcliffe presented the case well in the recent article "openid: The once and future enterprise Single Sign-On?", along with a great visualisation:


The call to Web Application providers..

Firstly, the big guys like Yahoo! need to support third party OpenID credentials. This seemed to be the main thrust of Hinchcliffe's article. I hope this is just a matter of maturity and not business model pig-headedness, but to offer OpenID sign-in only if your OpenID provider is the same company is not really in the right spirit of things!

More generally applicable however is a major consideration for any Web Application provider that wants to target the enterprise market: addressing the security issue with OpenID support only opens the door. To step through, you must be ready to meet the specific demands of an enterprise customer.

First of these must be data ownership. I didn't want to focus on it in this post because I think it is an orthogonal concern to security. But if you want enterprise customers, be prepared to to consider requirements such as:
  • Access to all data owned by the company's users on the service. For backup, export, and analytics.

  • Audit and compliance

  • Service levels

The call to Enterprise Software vendors..

The idea of a "Web 2.0 appliance" is I think very attractive to many organisations: an easy on-ramp to the space without the need to build up a whole range of specialist skills within the company. In the appliance category I would include Oracle WebCenter and the new IBM Mashup Center. Needing OpenID authentication support in these products is of course a no-brainer in order for them to have appeal in cases where you wish to mix internal and external user audiences.

Enterprise Software vendors need to go further however. The enterprise of the future, which expects to operate seamlessly on the web, will need the ability to "export" corporate identity to the world. Right now, that means capabilities like having OpenID provider support in your Enterprise Identity Management services.

Given the state of consolidation in the industry however, OpenID may present a dilemma for vendors who are faced with the prospect of OpenID support in their Identity Management stack cannibalizing sales of their application suites, as users start to exploit external Web Applications.

But to be recalcitrant and stand against the move to OpenID will only accelerate the onset of a winner-takes-all showdown in the enterprise applications market.

Personally, I believe the showdown is inevitable: with the combined pressures of RIAs, cloud computing, oligopolistic pricing and increasingly sophisticated open source alternatives, I think it is quite likely we will see the enterprise software market go supernova within the next 5 years i.e. blow itself to pieces after a few more years of consolidation ... but that's a topic for another post perhaps;-)


The enteprise software vendors that survive will be the ones who truly embrace being open, and that includes OpenID.

Conclusions?

Well, I wonder if I've convinced anyone?

To me it seems that the ability for enterprises to add OpenID provider support to their security infrastructure will be the key to unlocking the full potential of Enterprise 2.0.

Until such a facility is available from the mainstream Identity Management vendors, we will just be messing around on the fringe.

NB: edited for clarity 9-Sep-2008

Tuesday, June 24, 2008

Regrettably .. my Disqus experiment is over

It held great promise .. and I think still does .. but I am calling my experiment with Disqus commenting to en end.

I've unfortunately had too much feedback that it is just too (friggin) hard for the casual commenter. Bash me upside down, isn't it?

I hope the Disqus folks to manage to improve the interface to remove any barriers to adoption, because I still do look forward to the day we can wave goodbye to forums, and bring in an era of universally connected discussions!

Monday, June 23, 2008

The cutting edge of web applications? 280slides

It is amazing to see the art of the rich internet application (RIA) rocketing ahead over the past year or so, after a slow and troubled gestation over the past 12 years or so. Much of the progress has been incremental and focused on technical reimplementation of old non-web concepts (think event handling in a form GUI). Sometimes we take a big leap forward (think rails, prototype).

37signals arguably kicked of the current phase of web applications with basecamp that finally allow us to forget we are working in a browser (or was it writely? - now google docs).

Now we are seeing a selection of frameworks or products specifically designed for building modern RIAs. Rails is of course now fairly established in this space, but products like Flex, Air, Appcelerator and WaveMaker are redefining the envelope.

Well I'll be bold enough to say now that I think the guys from 280North have just redefined the cutting edge again with their powerpoint/keynote killer called 280Slides.

It's just out in public beta (isn't everything?), but I challenge you not to be impressed with just how much like a great piece of desktop software it is ... except you've also got the power of web access, sharing and delivery.


Perhaps even more impressive is the story behind the app, which you can hear in an interview on net@nite #57. When these guys set out to write web applications (like 280slides), they wanted a real development environment - like cocoa which they were familiar with having worked at Apple. So they built a cocoa-compatible/Objective-C like platform that runs in pure javascript. That's what is running 280slides, but building it is like building any old cocoa app. NB: the platform is still being kept internal, but their intention is to go open source when it is ready for the wild.

280North have only recently gone public with 280slides and the platform they have been building. Interesting to see at the same time we have Apple announcing a more conventional javascript library SproutCore. Can anyone spell a-c-q-u-i-s-i-t-i-o-n  t-a-r-g-e-t?

Exciting times!

Tuesday, June 17, 2008

Doing one thing at a time

James Shore discussed Agile Release Planning on this recent PM podcast, and it was refreshing to hear the benefits of agile pitched to a product management audience.

Like the best ideas, the tenets of agile appear almost too simple to be true. "Master of the bleeding obvious" Basil Fawlty would say. Yet most organisations seem structurally incapable of behaving along these lines.

James' presentation is very entertaining, and well worth a listen. He keeps the agenda short and well tuned to a PM audience. Although the ideas are born from a software environment, they are largely transferable to other domains. A discussion of five concepts to help you increase the value you deliver in business:

  • Work on one project at a time .. it improves your ROI

  • Release early and often .. get to market faster with a minimum, but valuable feature-set. Not only do you get to take advantage of the real customer voice sooner, but, again, better ROI.

  • Adapt your plans .. to slavishly avoid change is to confound the opportunity to increase the value of your work as new things are learned along the way

  • Conduct experiments .. your project can have many outcomes, and you will never know which is best unless you test options, collect data, and analyse

  • Plan at the last responsible moment .. avoid costly planning that is basically trying to predict the future (unsuccessfully). The later the decision, the more information you will have available to make a good decision.

The one project at a time struck a chord with me, as I've recently been campaigning in a minor way along these lines. The classic "proof" is the positive impact it can have on ROI if you allow appropriately sized teams to focus on one thing at a time. This is of course in addition to any productivity benefits you get from avoiding task switching, and giving people the chance to get into a flow state.

Here's my version of the graphic to illustrate the point:

Monday, June 16, 2008

bookjetty - a great new site to track, share, buy and borrow books

I've fallen in love with bookjetty, a great new site for books by Herryanto Siatono.

Although my It's a Prata Life blog is officially dedicated to prata (and always will be!), I also use it to keep a diary of the books I'm reading. I probably always will, but I do make sure to try out all the "book tracking" sites, facebook apps and so on that I come across.

None have really jiggled my worm until I discovered bookjetty.

The killer feature for me is the great library integration on the site. It helps answer all the usual questions I have whenever I hear about a new book..

  • Have I already got it or read it before?

  • Does one of my friends have it? Maybe I can borrow it..

  • Can I get it from the local library?

  • Can I buy it online?

  • (oh, and if the last two steps fail, I may actually visit a real bookstore!)

The library catalogue checks work a treat - right within your booklist. I used this feature yesterday as I knew I would be heading to the library. Within 5 minutes on bookjetty I had added a few books I'd been interested in reading and found out that 3 of them were available and on the shelf at my local library. An hour later, I had them checked out.

The bookjetty developer(s?) have done a great job of integrating the libraries, especially considering that most are still running archaic web 0.1 systems which are not very mashup friendly. I've posted before about a kludge to do library lookups from an amazon page, but it never works very reliably because of the dumb library catalogue it needs to talk to, so I can appreciate some of the challenges they may have had.

And here's an example of how the library checks appear...


If you are into books, I heartily recommend you go and register at bookjetty and check it out!

Sunday, June 15, 2008

Moving to Disqus for Comments

I recently moved this site's commenting feature to disqus.com after listening to the great interview with Daniel from Disqus on net@night#53. I see I'm not alone..

You may think A Blog Without Comments Is Not a Blog, and most people have reviewed Disqus in terms of the improved commenting features it provides.

There is another point of view that really hit home for me as I considered the move.

I remember the pre/early web days when I was a very heavy nntp (news) user. In the job I had at the time, it became my lifeline to various specialist groups where I would share the little I knew and was able to draw on the sometimes instantaneous feedback from a global community of peers. I think those days still rank as the best and most productive community networking experience I have ever had.

As the early web came to life there were many areas in which we took short-term hits for (hopefully) long term gain. We moved from (pre-Domino) Lotus Notes to web publishing for example, not because it was better but because it represented a broadly accessible, stanadards-based platform. Web 2.0 is I think only now starting to surpass the degree of interactivity you could achieve with Notes circa 98.

IMHO, collaboration is another area that's been through a similar process. Simplifying somewhat, I saw blogs and web-based forums as a bifurcation of the old collaboration experience I had with nntp. Blogs at least did a decent job of allowing anyone to publish what they thought was worth sharing. Web-based forums never really tickled my mustard however.

Implementations have never been quite as efficient for greasing collaboration as nntp, and they lack the universal federation model that nntp has always had baked in. It also meant that forum discussions and information publishing (via blogs etc) became divorced.



So when I look at Disqus (and other similar offerings), I see a scheme to finally re-unify the publishing and discussion worlds. Disqus provides the forum capability integrastes with tyhe blog publishing world, eliminating the question "should I blog it, post it to a forum, or both?"

As you can tell from my little diagram above, I don't see much role for web forums as we know them today in the new world of collaboration. Maybe I am overly negative, but it does make me smile/cringe whenever I hear someone talking about "web 2.0: you know, forums etc..."

Notes on integrating Disqus with blogger


I'm using blogger. Since there are various guides around for the manual integration of Disqus, I thought it would be worthwhile to report on how the process went for me.

I'm using customised blogger layouts for my blogs, and actually found that the automatic integration support built into the setup process on Disqus worked very well.

Just a few things to note:

  • I used the "upload template" feature to load the version modified for me by Disqus. I think because of this, I had to "expand widget templates" and save the template again after the upload to have it take effect.

  • There is no import of existing comments yet (future feature), but it is possible to go back to old posts that do not yet have comments and switch them to Disqus mode by selecting the "Don't allow" reader comments post option.

Postscript: as I noted here, I've unfortunately had to drop my disqus experiment because it just isn't proving easy enough for people to use. Shame .. for now!