Thursday, June 18, 2009

Allocating rewards in co-operative environments

At Cogent Consulting we compensate people in two ways - we have healthy base salaries and we offer profit share that is not linked to performance or to salary. It's close to equal shares (there are some details that mean that's not true overall). We debated this arrangement when we created Cogent and I've discussed it with colleagues back as far as 2001, but it's based on our gut feel of what would minimise conflict and maximise co-operation. It avoids the debate about relative performance that bonus systems create, that are normally circumvented by secrecy (secrecy isn't an option at Cogent). So it was interesting to read this in No Contest: The Case Against Competition by Alfie Kohn:



"In recent years, Deutsch and his associates have investigated not only the way tasks are set up but the way rewards are distributed. Among the possibilities are a winner-take-all system (which is what many contests amount to), a distribution proportional to accomplishment, and an equal distribution. Much as we tend to assume that competing boosts performance, so it if often taken for granted that the first two arrangements provide a crucial incentive for working hard: reserving a desirable reward for the winner is thought to promote excellence. A series of six experiments with Columbia University students, involving tasks that ranged from decoding Japanese poetry to estimating the number of jellybeans in a jar, was devised to test this assumption. The results: When tasks could be performed independently - that is, when there was low means interdependence - the system of distributing rewards had no effect on how good a job they did. There was absolutely no evidence to suggest that people work more productively when rewards are tied to performance than when everyone gets the same reward. But for those tasks where success depends on working together, there was a clear difference. A system of equal rewards, Deutsch discovered, "gives the best results and the competitive winner-take-all system gives the poorest results".



Notice that this is also a profit-sharing scheme, not a bonus system tied to some particular behaviours. We hope that our behaviours are driven by our principles, and that long-term this will generate profits. We wouldn't want people to change their behaviours to maximise single year's profit. If we ever detected that we'd need to review the profit-sharing scheme.

Wednesday, June 17, 2009

Cogent moves forward

Cogent has made a couple of steps forward this week. We'll tell you what those steps are in a minute, but first a little bit of background. Cogent Consulting really started two years ago when Marty and Steve merged their consulting revenue into one pool - now we have 11 employees, and we're going to come close to $2m in sales for this financial year. We generate enough margin to have two people on product development, we've released Runway, and we're about to start on another product venture. We still keep all our financials open and we operate reasonably democratically. Things are tracking fairly well.

So here are our two big steps. Our 11th employee was a business development manager, Rachel Morley. Having a business development manager increases our overheads, but it also gives us a more active, structured approach to business development that lets us (and indeed encourages us to) support more employees. As a result, we're looking for people who would like to become Cogent employees.

Cogent isn't your typical employer. We're interested in the usual things - people who have deep technical knowledge, people who can represent us well on client sites, people who like to learn. You've heard all that before. We're quantitatively different in that regard, in that our standards are very high, but there are some things that are qualitatively different about Cogent. If you're looking for someone to tell you what to do, in detail, then we're not the place for you. We're much more likely to give you some rather vague goal and ask you to figure out how to achieve it - and a lot of the things you need to do won't involve programming. They may involve marketing, or copy writing, or business analysis, or something as mundane as going and buying some stationery.

We truly need you to be collaborative and collegial - we don't have any places for people who want to work alone or who don't want to subject their programming thoughts to critique. Bob Sutton's "The No Asshole Rule" captures our philosophy quite well. In exchange we'll be completely transparent to you - you'll know our clients, our rates, our revenue, our costs, and everyone's salaries. You'll have the chance to be involved in decisions that you probably don't even know happen at your current employer.

We need you to be passionate. While we pay good salaries, we need you to be the sort of person who would program for enjoyment even if you weren't getting paid for it. We need you to be highly ethical - to be more concerned with doing the right thing than the profitable thing if there's a conflict.

We're interested in programmers, web developers, business analysts and possibly testers. So if you're interested in undertaking a variety of consulting work, off-site development, and product development at a place like Cogent, please drop us an email.

Sunday, June 14, 2009

Cogent as a business

Updated June 18



Along the Cogent Consulting journey we've documented a few different sets of values, principles and goals. Our manifesto was created quite early. Recently we've supplemented this with a simple list of values




  • Openness

  • Integrity

  • Respect

  • Craftsmanship

  • Collaboration



and goals


  • Develop non-consulting sources of income

  • Build some kick-ass software

  • Work with good people

  • Have flexibility in lifestyle and the amount of time I want to work



We should probably rationalise all this (and I just added that task to Runway), but first I want to add some more philosophical statements that occurred to me after I read Small Giants by Bo Burlingham.


  • We need to make a profit, otherwise we can't achieve our other goals. That's a constraint

  • Doing the right thing for the customer is more important than maximising profit

  • Our families are more important than our customers

  • For everything we do we should ask not 'is it profitable', but 'is it the right thing to do?'.

  • Right now, product development depends on consulting, and consulting depends on business development. We need to bear that in mind when we're setting priorities.

When I started to write I thought there would be more points, but combined with our existing manifesto that seems to say most of what I need to say.

Wednesday, June 10, 2009

Is it right?

After my JAOO Australia presentation on agile values a friend of mine referred me to Barry Schwartz's TED talk about Practical Wisdom and asked me if I thought there was any relationship between the agile values and what Schwartz was saying.

I think that philosophically there's a great deal of overlap. Among other great things, Schwartz says that over-reliance on rules reduces us to mediocrity. In "The Rise of the Chaordic Age" Dee Hock says "Complex rules and regulations give rise to simple and stupid behavior." Same message. Often these rules exist because we've "learned from the past" - because someone once made a mistake that we'd like to avoid in future we add an extra rule, and then another, and then another, until we are so constrained by the sludge of regulations that exceptional behaviour has moved beyond exceptional to impossible.

One of the things that the agile movement has said is that people inevitably make mistakes, but rather than eliminate the possibility of mistakes we should reduce the probability and the cost of the consequences. But if you don't trust people to do the right thing then this seems insufficient, and you start to add more rules, and you end up with the dogmatic flavours of agile - "you MUST do XXX or YYY". That's not the way to get the benefits that agile development promises.

Some people will say that adding rules is the wrong approach, and what you should do is create incentives instead, and let people establish specific behaviours based on those incentives. No stupid rules for these folks. But both Schwartz and Alfie Kohn (author of "Punished By Rewards") argue that any incentive scheme can be subverted by bad will, and that they send the message that you should "do the right thing" not simply because it is the right thing, but because you will be rewarded for doing it. Kohn in particular talks about the need to continually increase incentives and what happens if the incentive is removed.

So what should we do instead? Here Schwartz quotes Barack Obama - "We must ask, not just is it profitable, but is it right". We need to celebrate moral exemplars, to eulogise moral acts rather than financial acts, and encourage the development of moral will and moral skill. It may be faint to many, but I hear the echo of Kent Beck's values of transparency, accountability and responsibility.

I believe in all of this at a personal level. I believe it is consistent with the values of the agile community, as I understand them. And I'm very clear that these are the values of my employer, Cogent Consulting, otherwise I'd dissolve the company.

Tuesday, May 12, 2009

Cogent Values and Goals

Cogent recently had an off-site meeting that we used for a wide-ranging discussion, including a session on what we considered our values and goals as an organisation. We had a fairly spirited exchange on both these topics, constrained by finding at most five points in each area that captured our business. There were many things on the margins that people thought were important, so it was difficult to hone the lists to a concise consensus. In the end we had this:

Cogent Values

  • Openness

  • Integrity

  • Respect

  • Craftsmanship

  • Collaboration



Cogent Goals


  • Make more money than we can from consulting

  • Build some kick-ass software

  • Work with good people

  • Have flexibility in lifestyle and the amount of time I want to work



I was going to add some commentary, but on reflection I think these speak for themselves (but I'm interested in your comments).

For your interest, here are the next group of goals - things that influence us, but that aren't core and didn't make it into the definitive list:


  • Prove that you can run a company humanely for both customers and employees

  • Learn new things, learn proven things from experienced folk

  • Grow as practitioners

  • Change the way people develop software

  • Inspire one another and others

  • To have some fun



So while we would like to change the world and have some fun, we're realistic enough to understand that for us, for the people we are and the stage of life that most of us are in, there are some selfish things (money and flexibility) that are actually more important. That doesn't really make me feel great about myself, but I think it's the right decision and I think it's good that we've been clear and articulated this.

I'd be interested to know the outcomes from any other small firms that do some exercise like this.

Saturday, May 9, 2009

Runway

Cogent is very proud to announce the release of our very first product - Runway!

Runway is an action management system. It's inspired by Getting Things Done (GTD), and will eventually grow into a more complete GTD system. Why do you need an action management system? Because your brain is a terrible secretary?Right now you're wasting precious mental energy worrying about things you need to remember to do, which ones are important, which ones are urgent, what needs to be done next, and so on. Runway provides a trusted repository for all the things that you need to do - and trust me, there are hundreds of them.

Runway is designed to be quick and simple to use, and to become intuitive over time. An action is created through a simple, single-line entry field. No check boxes, no drop-down lists, no tabbing between fields. You can also create an action by sending an email to Runway, or by sending a Twitter message. We want to extend Runway to other sources, so that you have ubiquitous capture for your important ideas.

Do Today - Runway.jpg



Actions appear in your to-do list right away, and can be prioritised easily with drag-and-drop. You can rapidly filter your actions by when they need to be done, the context you need to be able perform the action, the time required, the energy you need, and any other tags you want to use.

Actions - Runway.jpg


Most people will use Runway to track all their actions, select the actions for the day at the beginning of the day, and then work through that list. I've been using Runway that way for over six months.

I'm really excited by Runway, because it makes my life simpler and helps me get things done. It's also a great piece of software, but I hope that people forget about that, that Runway merges into the background and just becomes an invisible helper. Please visit http://www.runwayapp.com and give it a go. Perhaps you'll have the same experience as Jonathan, one of our beta testers, who says, "Runway has changed my life!"

Sunday, May 3, 2009

Cogent Customer Brief

We're not heavily into formal contracts at Cogent, since we think they fail to capture the essence of the relationship. We understand that everyone needs to know how much they're paying and for how long, and we've also had some unfortunate experiences where we didn't do a good job of communicating expectations to the customer, so we've put together a document that describes, in the plainest language we could muster, what to expect then you collaborate on a project with us. You can find it on this page of our website.

Wednesday, April 29, 2009

Partnerships

My prior post (about excess work) generated a private email suggesting that partnerships would be one way to deal with the problem - that Cogent could enter into an arrangement with one of the larger companies to pass on excess work in exchange for some fee. That would seem to tick most of the boxes - the work gets done by someone we would have referred the customer to anyway, and we get some financial return, so I should feel less like we're "giving something away".

Yet I have some visceral reservations that I need to try to rationalise. I think it's mostly about responsibility and care - if Cogent is going to take money for something then I think we need to stand behind the result, and my experience is that you can lose a lot of money (and reputation) from bailing out one bad gig. If all I say is "here are some folk that have historically done a good job, and we don't have any stake in whether you work with them or not" then I don't feel as much responsibility for what happens downstream.

I think that's the heart of it - thanks for listening/reading while I figured that out.

What we do with excess business

Cogent doesn't do too much in the way of overt marketing and advertising. We spend some money on conference sponsorship, and about $30 per month on Google Adsense, and I think that's about it. Despite that, we get a steady stream of enquiries, and we generally end up with more work than we can handle - particularly if it's urgent work as we're often committed a few months in advance.

If a customer wants to start something right away, we do very little (if anything) to discourage them - instead, we pass along the contact details of the best people we know who can do the work and leave it to the customer to make any further arrangements. This is the simplest approach that can work, since it means that we don't get caught in the middle either managing communications or guaranteeing the quality of the work, and in principle the customer doesn't end up paying two margins so they should get the work done at a reasonable price. We're usually passing the work to companies that are "bigger" than us, and It's also worth saying that Cogent gets referrals in the same kind of way, mostly from independent contractors.

So by all rights I shouldn't be unhappy, but I have to admit to being irked by handing my competitors leads, especially when we don't get a lot of love in return. I understand it logically - if we had available resources, we wouldn't pass work to a competitor either, and these companies are much more likely than us to have available resources - but it still feels wrong or unfair on some level.

I'd be interested to hear how other small companies deal with similar situations.

Tuesday, April 14, 2009

Failure is mandatory

A few days ago I had a conversation with Travis about failure. In some senses I'm a hard ass about failure - I think if you protect people from failure all the time you also protect them from learning anything. It's still important to protect people from potentially traumatic failure, but traumatic failure is the exception rather than the rule.

The context was how far our duty of care extends as consults, particularly in regard to the transfer of a solution to the customer. There's typically tension around this issue - the customer wants to maximise their investment in the solution itself, and in other projects as well, and that works against either documenting the solution or getting permanent staff involved. One position is that we should go out of our way to document/record knowledge of the solution for handover, even if the customer hasn't made that a priority. I think that's paternalistic (which is ironic given the example I'll use later). I think it's our responsibility to warn the customer that there's a handover risk, and to give some advice on how we'd handle that, but in the end it's up to the customer to decide how to invest their resources, and to wear the consequences of those decisions. I think it would be quite wrong of us to divert resources into documentation against the customers wishes. We might think the customer has made the wrong decision, but it's still their decision and they won't thank you for subverting it.

Another context that we talked about was when you see someone else about to do the "wrong thing". You should definitely draw attention to the problem as you see it, but if the person goes ahead anyway, should you do anything to protect the project from the outcome? My position is that you should not - you should let the project suffer the consequences (again excepting traumatic outcomes). It's possible that your fears won't be realised, in which case you'll learn something. If they are realised, the project team will learn something (including perhaps to pay more attention to your advice) and may be able to avoid similar problems in future. If you just fix it, then what the project team will learn is that there are no negative outcomes from that behaviour, so they'll quite happily repeat, and you'll have the same personal situation later. Ad infinitum.

The same kinds of things apply to my son. I try to protect him from traumatic outcomes, but sometimes I need to let him get hurt (physically or emotionally) so that he learns not to repeat a behaviour.

Monday, April 13, 2009

Cogent is talking about open rates

Some of you will already know this, but Cogent is an ongoing social experiment along the lines of Thoughtworks, but with different axioms. Transparency is one of our axioms, but historically we've applied this internally and the public information about Cogent has been much the same as what you'd know publicly about any other consulting company. We're about to step that up a notch and publish our rates schedule publicly.

As usual, we see pros and cons to this decision. First thing is that no one else seems to do it, so perhaps we're just being stupidly naive and we'll discover the reasons why no one else does it in some catastrophic way.

More obvious to us that we lose one of our supply-and-demand levers. Our supply (our employees) is fixed in the short term, and it's always been hard for us to figure out what the "real" demand for our services is (we get plenty of unsolicited contacts that don't turn into any business). One of the levers we can use to affect demand is price - if we had lots of people doing non-billable work then we'd clearly think about dropping prices to get people onto billable work. Historically this would have been transparent to customers, unless they talked to one another, but with public pricing it will be clear if we offer discounts.

We may also find that we get less contacts because people look at our prices and decide that we're too expensive without even talking to us. It's not clear if that's good or bad - we may actually save time because we don't waste time doing estimates for work that's never going to proceed anyway. Or we may miss out on legitimate business.

And finally, our permanent colleagues on consulting gigs will now have a pretty good idea of what the consultant sitting next to them is being charged out at. That may or may not prove embarrassing (hoprefully not).

So why do it? We have some feedback that clients like simple, public rates schedules. It means less discussion internally about "how much as we going to charge this client?". And it means extending the reach of our core principles, and each time we've done that in the past it's been good - if nothing else it tells the employees that we "walk the walk" consistently.

We've split the rates along two dimensions - the type of work and where the work happens. We do two types of work - agile coaching from senior staff, which involves some hands-on development but is focussed on influencing the entire team rather than producing features directly, and development work, which is mostly focussed on delivering features but also on influencing the entire team to work more effectively. We have different rates for agile coaching and development work, and we also charge less for development work that's performed at our own premises. There are three reasons for charging less for working on our own premises - i) we aren't able to influence the client staff as well, so we deliver less value; ii) we prefer working on our own premises and price our services to encourage this; iii) when we're working on our own premises we're effectively competing against teams all over the world and we need to reduce prices accordingly.

So here are our rates for new work in 2009, all exclusive of GST:

Agile Coaching

  • Senior Agile Coach: $1400

  • Iteration Manager: $1300



Development (consulting / offsite)

  • Tech Lead/Architect: $1200 / $1000

  • Senior Developer: $1100 / $ 900

  • Developer: $1000 / $ 800


  • We're interested in what people think of this approach to pricing, so please let us know.

Tuesday, April 7, 2009

Post-agile, or just agile done well?

Ivar Jacobsen was in Melbourne recently, and did a presentation in conjunction with the ACS saying that development needed to "get smarter". Throughout the presentation he compared Smart development to Agile - the trouble was I couldn't see any difference.

For a few years now I've heard of "post-agilism", which was needed to overcome the woes of agile development - the trouble is I couldn't see any suggestions that weren't compatible with agile as it was described around the time of the Agile Manifesto.

Don't get me wrong - I don't think Agile is the answer to every software development problem. I strongly agree with Alistair Cockburn that the development method you use needs to depend *at least* on the degree of risk and the size of the team. However, I don't think that we need to find new methods just because Agile can be done badly. Maybe we should pause and work a little harder at doing things well before we move on to doing new things.

Monday, April 6, 2009

Experience - who gets the benefit of the doubt?

Bob Martin seems to have created a tempest with his apprenticeship model proposal, but it's worth remembering that it's not a new idea. There was at least one OOPSLA workshop on the Software Studio concept last century, and Ken Auer has implemented a related model at Role Model Software. I think Bob's raising the idea because he's had enough of crappy development and he wants to provoke some thoughtful responses (though that's just my impression). His article also triggered some related thoughts on how experience is treated in our industry.

One response to Bob's suggestion was that hierarchy somehow mistreated or devalued the more junior staff. It's quite true that this is one possible outcome, but the converse is also true. In non-hierarchical teams it's possible for the senior staff to be devalued! You can bring this into focus by thinking about a team of 2, one junior and one senior, and then asking yourself who should get the benefit of the doubt in a deadlock.

My experience is that many "juniors" think that they should get the benefit of the doubt. I've seen this attitude start immediately after graduation. I don't think that's right, or fair (but of course I'm arguing from an old guy's perspective). I've seen someone get upset because they didn't have carte blanche to replace existing frameworks, even though the changes would affect 30 people. I've seen someone simply defy the team conventions and go ahead and do it their preferred way, even after a team-wide discussion of the alternatives.

Everyone needs to understand that part of being a software developer is learning to *convince* people that your way is right - if other people don't understand, then you need to take ownership of the failure and find better ways to convince people. There is always going to be an "incumbent" position - sometimes incumbency is just the way it's done, and sometime incumbency is the older, more experienced person who perhaps can't articulate their position either. Someone needs to get the benefit of the doubt, and my leaning is towards experience.

I can't comment directly on the quality of very recent graduates, because I've stopped advising companies to hire them. My gut feel is that graduates come out with a good foundation for a career in software development, but still have a lot to learn. Sadly (for them) the salary for a graduate seems to be about $50K, and I can get people with 10-15 years of experience for just over $100K, and I'll take the more experienced person every time. I don't believe (as some people have implied) that mastery starts at 4 years and everything past that is wasted.

Wednesday, January 14, 2009

The cloud...it's full of *people*!

This is the story of the development of a small piece of software to deploy to the cloud, developed by a cloud of people, and how nominally unrelated groups interacted along the way.

I'm interested in having a way to easily create new Rails servers in the cloud (specifically AWS) and to deploy my apps to them. I'm familiar with the bits and pieces that are involved but I hadn't stitched them together. I started to write a Rails app to manage my AWS assets, partially as a path to learning extjs, but when the AWS Console came out I ditched that and started back on the original problem. Here are the different bits that I planned to use, and how I became aware of them:


  • Sprinkle, by Marcus Crafter (http://github.com/crafterm/sprinkle/tree/master) - Sprinkle handles deployment of resources on Ubuntu boxes in a pretty easy-to-understand way. Unfortunately I have a strong preference for Postgres over MySql (blame Simon Harris) and the default Sprinkle deployment recipes all use MySql. Still, it didn't take me long to make some extensions to install Postgres instead of MySql.


  • Passenger-Stack, by Ben Schwarz (http://github.com/benschwarz/passenger-stack/tree/master) - Sprinkles for Apache, Passenger, Mysql, Memcached & Git. I found out about this via a Ryan Allen tweet.


  • Amazon Web Services (http://aws.amazon.com/) - well known, but the fairly recent addition of Elastic Block Storage (EBS) gives a way to easily create persistent data that outlives a given instance, say for a Postgres database.



The last piece to this puzzle is a web site called oDesk (http://www.odesk.com/). I was talking to a client last week and she mentioned that she thought Australian Rails developers were the most expensive in the world. When I asked her what she was doing she said that she was using off-shore Rails developers and was finding good people who would work for US$20/hr, from India but also from the USA. It seemed like the recession in the USA was having interesting side affects. I was definitely curious how using oDesk would work from a client perspective.

So I had this small problem that I didn't have time to work on, and my curiousity about oDesk, and it seemed natural to solve them together. I posted my job on oDesk - produce a script that, given an EC2 instance and an ESB volume, would automatically configure the instance to use Rails with Passenger and Postgres, storing the data on the EBS volume. In addition, provide a test application so I can verify the Capistrano deployment to the instance. I posted this as a fixed price job, and my plan was to use a few different people and compare the outcomes. I posted my job last Sunday (it's currently Thursday).

I had my first response in a few hours, from within Australia! Twenty four hours didn't bring any more responses, so I pushed my job in front of a number of Rails developers who had high ratings. Many declined as they were too busy, some thought the suggested price was too low given the need to learn about AWS, and some still haven't responded. I got two more positive responses, one from an experienced developer in St. Petersburg and one from a less experienced developer on the east coast of the USA. The bids were $333.33 (Australia), $250.00 (Russia), and $166.67 (USA). The expected development times were 1 day, 1 day and 1 week.

I accepted the responses and nominated a starting date of Tuesday. On Wednesday I got my solutions from Australia and St Petersburg. I've tested the Russian solution and it works fine. There seem to be couple of issues in the Australian solution but the developer
is being very responsive, and the USA solution isn't due yet.

What's more interesting is what else happened in the 24 hours of development. The Russian developer forked passenger-stack on GitHub and hosted the fork as a public repository on GitHub (which was fine by me). However, I found out about this through an email from Marcus Crafter, who knew I was looking for a Postgres solution and pointed the fork out to me! Then I saw these tweets from Ben Schwarz (@benschwarz) "@kouky Just so you know, someone forked passenger-stack overnight rolling postgres support in, I'll try and pull everything together :)" and "@atnan @kouky, I've just blindly merged the PostgreSQL stuff as I'm up in the hills. I'll check it all out tomorrow :)" The status message for passenger-stack on GitHub now says "Adding support for PostgreSQL. Sprinkle will prompt the user to select MySQL/PostgreSQL server and the relevant Ruby database drivers."

So it looks like my little experiment ended up sponsoring the change that I wanted in the core implementation of passenger-stack. I suppose I could have asked Ben to do it originally, but that seemed like an imposition and I would have only achieved one of my goals. Now I have a script to configure my EC2 instances automatically, a better feeling for oDesk and off-shore development, and I've discovered that you can always sponsor the features that you want in a piece of open source software. Well worth my costs :-)

Sunday, December 28, 2008

An excellent idea to track drag...

Kevin E. Schlabach posted about the Snake on the Wall - a great idea for tracking the things that are slowing you down, and giving you a good starting point for your retrospectives.

Saturday, April 19, 2008

McDonalds doesn't teach queueing theory

I was in McDonalds today (don't ask), and there was a single line in front of the one attended register. One of the staff opened a second register, but everyone happily stayed in one line. Here's the dialogue that followed:


McDonalds : "Please form a second line here"

Steve : "Why?"

McDonalds : "What?"

Steve : "Why should we form two queues, when one queue is more efficient?"

McDonalds : after 3 or 4 second pause, "Because I say to"



Can't argue with logic like that....

Thursday, April 17, 2008

Batch Conversion of Pages file *in Leopard*

I was very proud of my Pages to rtf script, and then I upgraded to Leopard last night and it stopped working! In my search for the answer I came across this post, which solves the problem more thoroughly, though you need to combine it with information from here as well.



In case you don't want to do this yourself, here's a script that will start Pages, prompt you for the type of export you want, and then prompt you for a destination directory, and it works under Leopard. I told you it was more thorough than my last solution :-)




[sourcecode language='jscript']
on open theFiles
tell application "System Events"
if process "Pages" exists then
display dialog "whoops, please close Pages before running droplet!"
end if
end tell
tell application "Pages"
activate
delay 1
close front document
set theList to {"doc", "rtf", "pdf", "txt"}
set theType to (choose from list theList OK button name "Select" with title "Pages Export" with prompt "Choose one or more formats to export using Pages" with multiple selections allowed) as text item
set s to theType as string
set theLocation to choose folder
set theLocation to theLocation as string

repeat with aFile in theFiles
open aFile

if theType contains "doc" then
set asType to "SLDocumentTypeMSWord"
set docName to name of front document

-- Remove .pages extension.
set prevTIDs to AppleScript's text item delimiters
set AppleScript's text item delimiters to ".pages"

-- Add .doc extension.
set docNameNew to first text item of docName & asType
set AppleScript's text item delimiters to prevTIDs

-- Save file to Desktop.
set docPathAndName to theLocation & docNameNew
save front document as asType in docPathAndName

end if
if theType contains "rtf" then
set asType to "SLDocumentTypeRichText"

set docName to name of front document

-- Remove .pages extension.
set prevTIDs to AppleScript's text item delimiters
set AppleScript's text item delimiters to ".pages"

-- Add .doc extension.
set docNameNew to first text item of docName & asType
set AppleScript's text item delimiters to prevTIDs

-- Save file to Desktop.
set docPathAndName to theLocation & docNameNew
save front document as asType in docPathAndName
end if
if theType contains "pdf" then
set asType to "SLDocumentTypePDF"
set docName to name of front document

-- Remove .pages extension.
set prevTIDs to AppleScript's text item delimiters
set AppleScript's text item delimiters to ".pages"

-- Add .doc extension.
set docNameNew to first text item of docName & asType
set AppleScript's text item delimiters to prevTIDs

-- Save file to Desktop.
set docPathAndName to theLocation & docNameNew
set s to save front document as asType in docPathAndName

end if
if theType contains "txt" then
set asType to "SLDocumentTypePlainText"

set docName to name of front document

-- Remove .pages extension.
set prevTIDs to AppleScript's text item delimiters
set AppleScript's text item delimiters to ".pages"

-- Add .doc extension.
set docNameNew to first text item of docName & asType
set AppleScript's text item delimiters to prevTIDs

-- Save file to User Specified Location
set docPathAndName to theLocation & docNameNew
save front document as asType in docPathAndName
end if
try
close front document saving no
end try
end repeat
quit
end tell
end open
[/sourcecode]

Wednesday, April 16, 2008

Murray Gell-mann, in a TED video....

"In 1957 some of us put forward a partially complete theory of the weak force, in disagreement with the results of seven experiments. It was beautiful and we dared to publish it, believing that all those experiments must be wrong.

In fact, they were all wrong."


I love that in maths and physics truth and beauty are so frequently aligned, and that misalignment often indicates immature understanding. A new insight can reveal new beauty.



I think the same is true of programming. Your code should be at least as elegant as your problem domain (I can't do anything about accounting *s*).

Batch conversion of Pages files

My current assignment makes me a Mac weenie in a Microsoft world, so while I'm happily tootling along in Pages I need to be able to share stuff with my colleagues. At the moment I'm the primary author of 30+ short course descriptions, stored in separate Pages files, and I've been exporting them to RTF when I need to share them. That was initially ok, but got out of hand as the number of files grew, so yesterday I was introduced to AppleScript.



I know nothing about AppleScript, but I was able to find a script on the web (thanks again, Google) that did most of what I want. I'll show you the script, then tell you the parts that weren't obvious to me and slowed me down




[sourcecode language='jscript']
on open theFiles
tell application "Pages"
repeat with aFile in theFiles
open aFile
set docName to name of front document
-- Remove .pages extension.
set prevTIDs to AppleScript's text item delimiters
set AppleScript's text item delimiters to ".pages"
-- Add .pdf extension.
set docName to first text item of docName & ".rtf"
set AppleScript's text item delimiters to prevTIDs
-- Save file to Desktop.
set docPathAndName to (path to desktop as string) & "rtfs:" & docName
save front document as ".rtf" in docPathAndName
close front document
end repeat
end tell
end open
[/sourcecode]


My first challenge was that I couldn't figure out how to get this to run! Pressing "Run" in ScriptEditor did nothing. I ended up saving it as an applet (use "Save As", selecting FileFormat => application), and then I could drag and drop the files I wanted to convert onto the applet. Once I put the applet in the dock, that was pretty convenient.



The second thing that slowed me down was figuring out how to save the results to a folder (the original script saved to the desktop). What I needed was the bit ' & "rtfs:"' while setting the docPathAndName. Here I'm dealing with a string, and it already has a trailing ":" - I kept trying to add another one, and AppleScript gave me a message about the target not being writable, rather than not existing, which lead me astray for a while.



Anyway, now I can select my Pages files, drag and drop them onto the applet in my dock, and the rtf files appear in a folder on my desktop. Sweet!

Tuesday, April 15, 2008

Releases with themes


When I'm doing agile training, I commonly advise customers to give names to releases and iterations to help them decide which stories belong in which iteration, but it's not something that I see many customers do and since I rarely take that role not something I do much myself either. But today I got some direct experience!



Cogent is building a software application to help you organize your personal work, and I'm acting in the sponsor role. The details of the functionality are being sorted out by someone else, but I'm the person focussed on the operational requirements and how we get it to the billable stage as quickly as possible (everyone else in interested in this too, but it's my particular role). Yesterday afternoon I added operational stories to our list, and then prioritised the list story by story, and got what looked like a reasonable response.



Today I went back and created some themed releases, and gave them names.



  1. Homely - Ugly, but interesting. This release is usable, but won't win any design awards. We want it first because we're using the application internally now, so functionality is important. This is the release we'll pass to "friendly" testers for feedback, so it needs to support a small set of concurrent users without getting too slow. Codename : Homer


  2. Prettified - Like Homer, but certainly nicer looking and generally more usable. We still won't be confident in our backup plan, nor have stress tested the application, but it will look professional and be generally usable. Codename : Marge


  3. Robust - we need this one to be tough, so it can withstand the abuse of a lot of people. This is the point where we can do an open beta - still not charging, but giving the general public access. Codename : Bart


  4. Billable - something that we feel we could reasonably charge money for. Codename : Lisa




With these releases in mind I went back and looked at my priorities again, and found that some of them were quite different. If you are a customer on an agile project, I strongly encourage you to do the same thing - you may be surprised by the difference it makes.