Good to Great part 2 - Going Full Circle

Posted about 7 years back at work.rowanhick.com

Following on from Good to Great (rules to live by) post. One thing that constantly irks me is the "It's not my job" syndrome. This is most apparent in call centers "Sorry I can't help you with this, let me transfer you to.." [cue another 10min wait time]. We've all been on the receiving end of that one and can attest to how we get annoyed by it. This also manifests itself in development teams and developed systems. The biggest impact you as a IT person (be it developer, analyst, project manager) can make, is take a 'full circle' approach to your interactions both within a team and directly with clients and your developments. What do I mean ? take extra time out of your day when faced with an issue, that's not technically your, or your apps responsibility, to solve it completely for your client or team member. Or if you can't solve it, take ownership in handing it off properly**. The end result is to have the initiator of the request client, user etc, not required to go elsewhere to solve their initial problem. Why would we possibly want to do this, when our time could be better served browsing Digg, checking out Facebook, breaking out the office xbox ? - Client is vastly happier, happy clients pay bills, come back for more work, and refer you/your company - You get credit, and respect within the team and from the client - You will likely gain greater domain knowledge - You will likely see opportunities in your app to further improve it's usability Lets look at some examples: ... as applied to a hosting management Case: Your client forget to renew their domain name The standard approach is to send them an email 'you need to renew your domain name'. The full circle approach is to lookup their domain registry details, tell them where and how to renew their domain name - as so often clients have simply no idea. Takes an extra 15mins of your time but you will be rewarded massively in return. If you're really on the ball you'll pop in your calendar an annual recurring reminder to make sure it gets renewed ahead of time. ... as applied to internal development Case: You stumbled across a bug you think most people won't notice. The likely approach would be to fix the bug you found and case closed. Lets say you made a mistake that caused all historical orders in a system to miss the city off the shipping details. So the first approach is to go 'ooops, shouldn't have done that, let's fix it here and move on'. Taking a full circle approach to it would be to go and contact everyone who was affected by it and let them know what the problem was, how it would present itself, that you found the problem, fixed it, and what would occur now. By being open and honest with them and taking the time out to inform them, will gain trust and appreciation. Suffice to say if the little bug was caused by you and resulted in a minor loss of a few million dollars it might be time to hang up the keyboard and quickly get out of dodge. ... as applied to developing a system Case: An order system ships stuff via a major shipper, tracking number's get emailed to the buyer. ( This one is my personal pet peeve ) How about your system goes away to your shipper(s) requests shipping information, and updates your user. So you don't require your user to go elsewhere to find shipping information. Better yet - when your shipping service says delivered how about an email 24 hrs later "We have been notified your package has been delivered, please click on this link to let us know you've received your package and if you may have any comments you can make them there". That way your system has a true end to end connection with the user from the time the order was placed, till it hits their doorstep. In summary Whenever interacting with someone, take time out to put yourselves in their shoes, and ask yourself was this problem completely solved for me? Take ownership and pride in the solution and you will be rewarded 10x over with fellow team members and clients, willingness to work with you in the future. ___ ** Handing something off properly ? How so ? For the love of god never expect your client to explain everything all over again to another team member. Talk to the client, say you can't personally solve it, however you've given all the details to person x and they will be contacting them, you'll follow up in y timeframe to make sure it's all their issue has been dealt with a-ok.

Can’t find Essential Actionscript 3 and in Canada ?

Posted about 7 years back at work.rowanhick.com

For all the Canadians out there wanting this book (at time of writing) my order from chapters.indigo.ca just shipped, so there must be a few of them in stock - go get your order in quick ! Whereas amazon.ca is currently out of stock, and chapters two weeks ago were out of stock, and O'Reilly is/was of stock when I tried a couple of days ago to order.

Swing Reduction Sauce

Posted about 7 years back at zerosum dirt(nap) - Home

JRuby continues to develop in interesting ways. Earlier today, Zed Shaw (Mongrel’s dad) announced the release of Profligacy 1.0, which you should take a look at if you’ve got a thing for building cross-platform desktop apps in Ruby. It’s pretty cool.

Profligacy is a (wildly extravagant?) library that purports to take the pain out of using Swing components with JRuby. It uses LEL, Layout Expression Language, to bring a sort of wiki-ish flavor to component layout. This is truly bizarre at first glance, but damn cool at the same time. Basically the Ascii art you lay out with LEL translates into a Swing GroupLayout. Ah-wha? Yep. Check out some examples. I told you it was cool.

It also does some other neat stuff like auto-converting procs to Listener interfaces, but I won’t go on about that, as you can go check the release notes instead. If you’ve ever worked in Swing before, you know how painful it can be. Profligacy makes it significantly less bitter to swallow. Now stop reading blogs and go build your first cross-platform Ruby desktop app. You know you want to.

Redesign RubyForge?

Posted about 7 years back at Synthesis

With the whole RailsForge survey thing, it’s also come out that a lot of people hate the current incarnation of RubyForge.

Some are suggesting to redesign RubyForge, which is a good idea. Re-think RubyForge and give it some 37signals-style, UI-first design love. I haven’t talked with any RubyForge maintainers yet, but I’d be interested in helping out.

By the way, I totally appreciate RubyForge, and I’m so thankful to the people who run it and donate their time and money to keep it going.

RubyForge pet peeves

What is it about RubyForge that’s so annoying? For me, when I arrive at a project page on RubyForge, I’m greeted with a plethora of “stuff” cluttering the page, that’s either un-used or not really telling me anything. I often leave more confused, and I’m an experienced developer. Imagine how a beginner feels! I then look elsewhere hoping someone has written a helpful tutorial on their blog.

RubyForge-specific complaints from the RailsForge survey responses:

  • Most of the features go unused.
  • Biggest problem is the UI.
  • It’s very difficult to do the things the majority of people want – 1. learn about a project, 2. download and install it, 3. learn how to use it.
  • 90% of the project page has nothing to do with any of this and it just adds clutter.
Suggestions:
  • Let project maintainers selectively turn on the features they want.
  • 80% want to learn. 20% want to contribute. Refocus the UI to reflect this.

A choice of databases, or PostGres vs SQLite

Posted about 7 years back at Saaien Tist

When managing data in bioinformatics, one of the main tools you use is databases to store the stuff. In many cases, flatfiles are sufficient, but sometimes you need the flexibility and reliance of a nice relational database. (Note: Excel is not a database). Actually, in quite a few cases it does make sense to use flat text files instead of databases, but that's the subject of another post.

As there is a plethora of RDBMS (relational database management systems) available, the first thing you have to ask yourself is what system to use. There's mysql, oracle and others. But for the purpose of this post, I'll focus on PostGreSQL (http://www.postgresql.org) and SQLite3 (http://www.sqlite.org), because that's what I normally use.

For the big projects with a lot of data, I normally use postgres, while smaller projects are typically served by sqlite databases. Both of these however have their good and bad things. Choice depends on a number of factors:

Installation. The main difference between postgres and sqlite3 is that one is based on running a server and the other is not. To be able to use postgres, you'll have to install the software, create a postgres user on your system and have that user start the postgres server. Next thing to do is create a user within the database system and grant it the right permissions (e.g. to create other users or databases). That's a bit more complex than installing sqlite3.

Database creation. To create a new database in PostGreSQL, you issue a createdb MyDatabase. This will add the database to your RDBMS. You can get into the database with psql MyDatabase. In contrast, sqlite3 databases are just text-files like any other. Create a new databasebase by calling it: sqlite3 my_database.s3db. This will create a file in your present directory called my_database.s3db. Note: you don't have to use the .s3db extension, but that makes it recognizable for the SQLiteAdmin tool (see below).

Use. Once you've got your databases created, their use is really similar. On the command line, use the psql or sqlite3 command. On Windows, you can e.g. pgAdmin and SQLiteAdmin.

I must say that psql is a bit easier on day-to-day typing, because it's got tab-completion, which I haven't been able to activate yet in sqlite3. I should spend some time one day to configure sqlite exactly like I want it to.

Locking. This is what bit me in the ankles with sqlite3... According to the website: "SQLite version 2.8 allowed multiple simultaneous readers or a single writer but not both. SQLite version 3.0 allows one process to begin writing the database while other processes continue to read. The writer must still obtain an exclusive lock on the database for a brief interval in order to commit its changes, but the exclusive lock is no longer required for the entire write operation." Indeed, I could load hundreds/thousands of records while simultaneously querying the database. But at what looked like a random moment, after hours of loading, it would choke, leaving me with a partially populated database. Any small child can tell you that this is not what you want to happen. I've never encountered something like that in postgres, and probably never will.

Backup. Because sqlite if file-based, making a backup of a database is nothing more than taking a copy and moving that copy to another hard disk or burning it on a CD-ROM. To make backups of postgres databases, we typically use pg_dump, which dumps the contents (and if you want the schema as well) of a database in a big-ass text file. So the backup is outside of the RDBMS itself.

So both RDBMS have their advantages and disadvantages. For huge projects, I tend to use PostGres, although I've started to use sqlite more and more lately. If only it wouldn't choke on the locking...

Episode 56: The Logger

Posted about 7 years back at Railscasts

Learn all about the logger in this episode. See how to send messages to the log and how to customize it.

mms2r 1.1.3 Released

Posted about 7 years back at Mike Mondragon

mms2r version 1.1.3 has been released!

DESCRIPTION:

MMS2R is a library that decodes the parts of an MMS message to disk while
stripping out advertising injected by the cellphone carriers. MMS messages are
multipart email and the carriers often inject branding into these messages. Use
MMS2R if you want to get at the real user generated content from a MMS without
having to deal with the cruft from the carriers.

If MMS2R is not aware of a particular carrier no extra processing is done
to the MMS other than decoding and consolidating its media.

Contact the author to add additional carriers to be processed by the
library. Suggestions and patches appreciated and welcomed!

Corpus of carriers currently processed by MMS2R:

  • AT&T/Cingular => mmode.com
  • Cingular => mms.mycingular.com
  • Cingular => cingularme.com
  • Dobson/Cellular One => mms.dobson.net
  • Helio => mms.myhelio.com
  • Nextel => messaging.nextel.com
  • Sprint => pm.sprint.com
  • Sprint => messaging.sprintpcs.com
  • T-Mobile => tmomail.net
  • Verizon => vzwpix.com
  • Verizon => vtext.com

Changes:

  1. 1.1.3 / 2007-07-10 (Charles Foster Ofdensen)
  • Helio support by Will Jessup
  • get_subject returns nil on default carrier subjects

http://mms2r.rubyforge.org/

mms2r 1.1.3 Released

Posted about 7 years back at Mike Mondragon

mms2r version 1.1.3 has been released!

DESCRIPTION:

MMS2R is a library that decodes the parts of an MMS message to disk while stripping out advertising injected by the cellphone carriers. MMS messages are multipart email and the carriers often inject branding into these messages. Use MMS2R if you want to get at the real user generated content from a MMS without having to deal with the cruft from the carriers.

If MMS2R is not aware of a particular carrier no extra processing is done to the MMS other than decoding and consolidating its media.

Contact the author to add additional carriers to be processed by the library. Suggestions and patches appreciated and welcomed!

Corpus of carriers currently processed by MMS2R:

  • AT&T/Cingular => mmode.com
  • Cingular => mms.mycingular.com
  • Cingular => cingularme.com
  • Dobson/Cellular One => mms.dobson.net
  • Helio => mms.myhelio.com
  • Nextel => messaging.nextel.com
  • Sprint => pm.sprint.com
  • Sprint => messaging.sprintpcs.com
  • T-Mobile => tmomail.net
  • Verizon => vzwpix.com
  • Verizon => vtext.com

Changes:

  1. 1.1.3 / 2007-07-10 (Charles Foster Ofdensen)
  • Helio support by Will Jessup
  • get_subject returns nil on default carrier subjects

http://mms2r.rubyforge.org/

Getting started with Flex - what you should know.

Posted about 7 years back at work.rowanhick.com

Okay, so like me you've done a lot of web development with scripting languages ala Ruby, PHP, Perl etc and you've decided to try out Flex for a front end. What do you need to know ? This is just my own humble opinion - take it with a grain of salt, but for those looking to jump in you should find something valuable. This is all encompassed with the caveat that you are using the right tool for the right job, now what ? We know the advantages of using Flex - I'm not going to reiterate them. What I am going to tell you is the things to be aware of - not critiscims. Be prepared to invest time. Considering I had a working app with rails in one all night code marathon, I feel that I've only just waded in with Flex - granted this is apples to oranges comparison - however of everything I've jumped into, Flex is the one that takes the most time - mainly because it is developing interfaces, not yet another scripting language/framework stack. Beyond the basics you will spend a lot of time figuring out the nuances of what you need to do to get something working. You will have moments of happiness, and moments of wanting to heft your computer off a cliff.... Flex is not flash. Flex is a very real grown up interface language / architecture. Sure Flex is rendered via the Flash Player, and gets compiled down to a SWF but thats where the similarities start and end. [As a side note, I personally can't help but wonder if they just rebranded the flash player etc whether that would help Flex adoption...] Flex requires compilation of the runtime swfs. No biggie, but if you happen to be in Mac land on a Dual Core G5 (or worse) machine you might want to talk to your tech department about an upgrade. Compared to pure web scripting it can put a dent in your workflow, code-compile-refresh vs the time honoured code-refresh. If you're not going to break out the cash for Flex Builder lookup the Flex Compiler Shell (FCSH) on adobe labs. This dramatically cuts compilation time. Break out your OO skills. You're going to need them.. Actionscript 3 is strongly typed. If you've come from a dynamically typed background ala Ruby, this can hinder you - you have to consistently be aware of the types of objects your dealing with and what they can/can't do. Time and experience will render this issue obsolete. Event based programming - say hello to your new friend dispatchEvent. Everything is event based, and a solid part of learning flex, is realising when and where to send events and listen to events. You have to change your mindset to look at every possible combination of things the user can do in your app. Learn how to get events into your custom components and use them wisely. Learn how to use the Flex Builder Debugger. This is exceedingly powerful and useful for figuring out why your apps aren't doing what you expected them to do. Adobe can expect my money when they release Moxie for this feature alone. Code Completion. Again another life saving feature of Flex Builder is the code completion / inspector. An advantage of the strong typing this helps in your coding by seeing the correct properties/methods on objects - which in turn saves a lot of time referring back to the livedocs. More than one way to a skin a cat. For everything you try to achieve there normally multiple of ways of doing so. Keep persevering and find the one that works and is most suitable for the problem at hand.  You're not on your own - Adobe developer support is fantastic. Case in point the giant wall posters that I scored from Adobe for free - great for me but scary for the general populous walking into my office. You can see that Adobe want this to succeed and they're doing all they can to do so. A free SDK, good documentation, free PDF book downloads (for AIR), onAIR tour events, videos.onflex.org, open sourcing... you name it they're trying to do it - which gives me the warm fuzzies about investing my time in this technology. Above all, keep persisting it all pays off ! You can produce beautiful works of interface-art, that work as you expect them to, consistently and repeatedly. Pixel perfect and cross platform, beyond any interactivity possible with AJAX (unless you're a sadomasochist)

Episode 55: Cleaning Up the View

Posted about 7 years back at Railscasts

This episode starts off with a big, messy template. Watch as this code shrinks and becomes more readable while the interface stays the same.

The Hobo Migration Generator

Posted about 7 years back at The Hobo Blog

Right back at the start of the Hobo project we made writing migrations a little easier. We made it so you didn’t have to write the word “column” quite so many times.

create_table "users" do |t|
  t.column :name, :string
end

Became:

create_table "users" do |t|
  t.string :name
end

A pretty small contribution in the scheme of things, but kinda handy, and it made it into core Rails (by a circuitous route) which was nice.

Somehow though, it wasn’t good enough. It was quicker, but it wasn’t Hobo Quick. Don’t you always get the feeling that writing migrations is kinda mechanical? Especially those tedious down migrations. Don’t you wish you never had to write another migration again? I know I do. Or did, I should say.

Announcing the Hobo Migration Generator.

Creating your database tables in the next version of Hobo will go something like this:

Step 1. Code your models (being sure not to generate any migrations)

Step 2. ruby script/generate hobo_migration create_initial_tables

(Step 2.5. Observe db/migrate/001_create_initial_tables.rb)

Step 3. rake db:migrate

And you’re done.

Hang on one darn minute I hear you say! Where are the columns declared? One of the much loved features of Active Record is that you don’t have to enumerate the columns in your models - AR interrogates the database and finds them for you. If Hobo generated the migration, where were the columns declared?

In the model class.

class User < ActiveRecord::Base
  fields do
    name :string, :null => false
    email :string
    about :text, :default => "No description available"
  end
end

Sacrilege! Not at all - it’s actually much better this way. Work with me for a minute here.

What is it that you really love about not having to list the columns in your AR classes? It’s the fact that it’s DRY. You don’t have to list them once in the migration and then again in the class. Well that’s still true, all we’ve done is moved those declarations to where they should be - in the same place that defines all the rest of the behaviour of your model. Yes those column declarations will be in the migration too, but that is generated for you.

There’s no more trawling through old migrations or messing with MySQL in order to remind yourself what columns you have - it’s right there in your code.

The generator looks at the database, looks at your models, figures out the difference and creates a migration such that the database gets with the program.

It generates the down migration too of course.

Moving forward things get even more interesting. Say you wanted to get rid of one of those fields. Just delete it from the fields declaration. Run the migration generator again and you’ll get a remove_column migration. Change the type of a column or add a default? No problem, you’ll get a change_column.

What if you delete a model class outright? Well we’re guessing your production data is kind of important to you, so the generator is interactive. It will require you to physically type “drop users” (or whatever) before it will generate a drop_table migration. The same goes for removing columns in fact.

What about renaming a column or table? Those are kinda tricky. Say we rename the field name to username. All the generator sees is that an existing field name has gone away, and a new field username has appeared on the scene. The generator will alert you to the ambiguity and invite you to enter either “drop name” or the new name “username”.

That’s the long and short of it, but there’s a couple more niceties.

Inside the fields block you can say simply timestamps to get created_at and updated_at.

You can declare fields using Hobo’s rich types like :html and :markdown. These end up as :text columns unless you override that by giving the :sql_type option. Your DRYML tags will know what it really is and render appropriately.

As for foreign keys – don’t even bother. Just declare belongs_to as you normally would, and the migration generator will spot the need to add a foreign key. Either with the conventional name or a custom one if you gave the :foreign_key option. Delete the belongs_to later, and the migration generator will remove the foreign key.

If, like most Rails programmers, you’ve written a lot of migrations, I think you’ll find using this puppy to be a fairly pleasing experience :-) I know I do.

It’s working now in the tom_sandbox branch, and will be in the next release, which, if the coding gods be willing, will be out by the end of the month.

The Hobo Migration Generator

Posted about 7 years back at The Hobo Blog

Right back at the start of the Hobo project we made writing migrations a little easier. We made it so you didn’t have to write the word “column” quite so many times.

create_table "users" do |t|
  t.column :name, :string
end

Became:

create_table "users" do |t|
  t.string :name
end

A pretty small contribution in the scheme of things, but kinda handy, and it made it into core Rails (by a circuitous route) which was nice.

Somehow though, it wasn’t good enough. It was quicker, but it wasn’t Hobo Quick. Don’t you always get the feeling that writing migrations is kinda mechanical? Especially those tedious down migrations. Don’t you wish you never had to write another migration again? I know I do. Or did, I should say.

Announcing the Hobo Migration Generator.

Creating your database tables in the next version of Hobo will go something like this:

Step 1. Code your models (being sure not to generate any migrations)

Step 2. ruby script/generate hobo_migration create_initial_tables

(Step 2.5. Observe db/migrate/001_create_initial_tables.rb)

Step 3. rake db:migrate

And you’re done.

Hang on one darn minute I hear you say! Where are the columns declared? One of the much loved features of Active Record is that you don’t have to enumerate the columns in your models - AR interrogates the database and finds them for you. If Hobo generated the migration, where were the columns declared?

In the model class.

class User < ActiveRecord::Base
  fields do
    name :string, :null => false
    email :string
    about :text, :default => "No description available"
  end
end

Sacrilege! Not at all - it’s actually much better this way. Work with me for a minute here.

What is it that you really love about not having to list the columns in your AR classes? It’s the fact that it’s DRY. You don’t have to list them once in the migration and then again in the class. Well that’s still true, all we’ve done is moved those declarations to where they should be - in the same place that defines all the rest of the behaviour of your model. Yes those column declarations will be in the migration too, but that is generated for you.

There’s no more trawling through old migrations or messing with MySQL in order to remind yourself what columns you have - it’s right there in your code.

The generator looks at the database, looks at your models, figures out the difference and creates a migration such that the database gets with the program.

It generates the down migration too of course.

Moving forward things get even more interesting. Say you wanted to get rid of one of those fields. Just delete it from the fields declaration. Run the migration generator again and you’ll get a remove_column migration. Change the type of a column or add a default? No problem, you’ll get a change_column.

What if you delete a model class outright? Well we’re guessing your production data is kind of important to you, so the generator is interactive. It will require you to physically type “drop users” (or whatever) before it will generate a drop_table migration. The same goes for removing columns in fact.

What about renaming a column or table? Those are kinda tricky. Say we rename the field name to username. All the generator sees is that an existing field name has gone away, and a new field username has appeared on the scene. The generator will alert you to the ambiguity and invite you to enter either “drop name” or the new name “username”.

That’s the long and short of it, but there’s a couple more niceties.

Inside the fields block you can say simply timestamps to get created_at and updated_at.

You can declare fields using Hobo’s rich types like :html and :markdown. These end up as :text columns unless you override that by giving the :sql_type option. Your DRYML tags will know what it really is and render appropriately.

As for foreign keys – don’t even bother. Just declare belongs_to as you normally would, and the migration generator will spot the need to add a foreign key. Either with the conventional name or a custom one if you gave the :foreign_key option. Delete the belongs_to later, and the migration generator will remove the foreign key.

If, like most Rails programmers, you’ve written a lot of migrations, I think you’ll find using this puppy to be a fairly pleasing experience :-) I know I do.

It’s working now in the tom_sandbox branch, and will be in the next release, which, if the coding gods be willing, will be out by the end of the month.

Now Available In Tanzania

Posted about 7 years back at Sporkmonger

Maasailand

For those of you who are interested, I’ve been in Tanzania at the Cradle of Love baby home near Arusha for the past two weeks and change. It’s been interesting for sure, lots of holding and feeding babies, playing with toddlers, trying to get through the day with as little snot and spit on me as possible. There’s a few spitters who make this difficult, but they make up for it by being excessively adorable. I try not to play favorites, but Neema ends up riding my shoulders quite a bit. I haven’t taken a lot of pictures around the baby home itself, but on the various excursions we’ve taken outside, the camera has come out with a fair degree of regularity. There’s also some new kite aerial photography shots from the trip to the bush to visit the Maasai. If you have a Pro Flickr account, the high-resolution panorama shot from the kite is pretty neat. I suspect that through August at least, my Flickr photo stream will be much more interesting to subscribe to than my blog’s feed will be. Consider adjusting accordingly.

Episode 54: Debugging with ruby-debug

Posted about 7 years back at Railscasts

This episode will show you how to debug a rails app using ruby-debug: set a breakpoint, inspect variables, change the code and more.

Ruby en Rails Amsterdam - Ruby on Rails Podcast

Posted about 7 years back at Ruby on Rails Podcast

Interviews from Ruby en Rails, Amsterdam.