Refactoring my blogs

October 4th, 2009

Well, I’ve been reading again (always a bad move) – first Outliers, by Malcolm Gladwell, which talks about the 10,000 hour rule.  He theorises that to truly master something, you need to spend 10,000 hours practising it.

I’m an old-school geek – I started coding in year 7 on my sister’s university account, in Basic; and I spent many, many years coding bad procedural programs in Basic, Assembler, Pascal, and C.  I racked up at least 10,000 hours of procedural coding – sometimes with cool results, but generally it was pretty ugly.

Somewhere along the way, I got paid to code, and eventually I discovered C++, and a while later, Java and object-oriented ideas, and a more "professional" approach to coding; which, sadly, often meant forays into realms of ugly complexity commonly associated with "professional" coding – it can be summed up with a pile of acronyms, most of which still make me break out in a cold sweat – UML, STL, J2EE, Corba, RUP, COM, MDA … I shudder to go on.  Another 10,000+ years of ‘practice’ – and a lot of useful lessons learned, though mostly about what kind of things to avoid, and what kind of promises to be sceptical about.

Thankfully, things got somewhat better after that – moving to Agile development made the world a lot more sane; test-driven and behaviour-driven development have drastically improved code quality and transparency; and I discovered shiny new languages like Ruby, which re-introduced me to Functional Programming, which led to Clojure and Scala and a host of new ideas and technologies.  And all of these connected me to new communities of people with new ideas… This starts to look like a great 10,000 hours!

That brings me to the other book I read recently – from the always excellent Pragmatic Press, "The Passionate Programmer", all about building and enhancing your IT career.  It helped me to realise I should pull my socks up, update my websites and my blogs, and actually share what interests me with the world, rather than geeking along in a vacuum.

So hence this long ramble and this re-branded blog.  I have a pile of things to write about – a short list includes:

  • My (so far pretty limited) experiments with Google Wave
  • My team’s great use of Cucumber for Behaviour Driven Development, including some cool wiki integration
  • Some half-formed thoughts I’ve had on unifying several things I’ve heard and read on Agile and Lean Values, Principles, and Practices – not sure I’m anywhere near a grand unified theory of everything, but if my thoughts turn into something coherent, I’ll post them
  • My next big project – tentatively titled "Kanban Sync", it will use an Augmented Reality interface on a smartphone to synchronize a physical card wall (a.k.a. Kanban board) with back-end tracking tools such as Mingle or Agile Bench or Jira.  This is still in very early planning stages – but if it works, it’ll be very cool indeed.

Plus, of course, whatever actually comes up…

Curved corner images in rmagick

July 20th, 2008

RMagick is a great ruby library for image manipulation – it’s basically a wrapper around the venerable ImageMagick libraries.  There are some complexities around installing it on some platforms, and you have to be careful with garbage collection, but it’s still very easy to use and very powerful.

The curved corner images I used in previous blog posts could be built in photoshop or gimp or other gui applications, but I wanted something scriptable, so I’m trying to build all images in RMagick – and it’s really not that difficult.

RMagick has a whole set of vector graphics functions, but I’m mainly using one, the roundrectangle function – it’s pretty simple:

image = Magick::Image.new(width+bordsize, height+bordsize) { self.background_color = 'transparent'}
gc = Magick::Draw.new
gc.stroke(bordercolour)
gc.stroke_linecap('round')
gc.stroke_width(bordsize)
gc.fill(innercolour)
gc.roundrectangle(bordsize/2,bordsize/2, width,height, radius, radius)
gc.draw(image)

This basically draws a round rectangle, with a solid border, at offset (bordsize/2,bordsize/2) – you need the offset as otherwise the border edge will overlap the edge of the image.
Adding a shadow is pretty simple, rmagick has the shadow method:

shadow = image.shadow()
image = shadow.composite(image,Magick::NorthWestGravity, Magick::OverCompositeOp)

- this basically works, but sadly you get issues when you save the image. The shadow() method creates a shadow of a given image, with a specified shadow radius, which results in a larger image than the original – so the code above gives you an image which has shadow pixels at negative x and y coordinates!  Some file formats cope with this just fine – png files seem to do ok – but I wanted gif images for ie6 fallback, and gif doesn’t cope at all.

Anyway, to cut a long post short, the final code (see below) has a fair bit of logic for allocating extra space in the image for the shadow.  An example of the basic image-with-border-and-shadow image:

simple shadow sample

One last tweak I did – I wanted to have a shadow on the borders – the dark border is nice for some effects, but I wanted a slightly more 3d look:
sample with dark border
And a more subtle effect with the raised border the same colour as the diagram:
sample with light border

I also added some logic to set transparency of the image, for pretty backgrounds like the example from my last blog post (sample page here) – and to automatically save a gif version for ie6 display.

The full code can be seen at http://www.sietsma.com/korny/corner_test/corners_code.html

Obviously there’s lots of other things you can do – but this is a useful start!

Sigh – ie6 defeats my cunningness

July 6th, 2008

Well, my previous post and linked page seems to work nicely. (I did fix a minor glitch in ie7)

However, since then I’ve done some more reading – and my conclusion is, don’t do what I did – ie6 png transparency is just too risky. Have a read of the discussion at http://blogs.cozi.com/tech/2008/03/transparent-png.html?cid=106552420 – they found that when used heavily, the AlphaImageLoader filter causes ie6 to deadlock. Ow. If it’s critical, you can work around this, but it sounds really really painful.

So I’ve reverted to using something that is basically Scott Schiller’s technique – see http://www.sietsma.com/korny/corner_test/test2.html – but on ie6, you get no translucency.

The good news is, I can now use a single image, instead of slicing the image up. And I’ve fiddled my rmagick rounded-corner generation code, it’s now getting pretty nice – I’ll post it when it’s done. Not as nice as what you can do if you’re a photoshop/gimp guru, but it’s nice to have something generated by code, so I can change colours/sizes at will.

The next step is probably to make this stuff javascriptable, so I can use a single div for a minimal styling version, and then prettify it in javascript… possibly. I’m still a bit unsure if using javascript makes the code more ‘semantic’ or not.

[ed: sigh - I thought I'd posted this weeks ago.  Somehow, it got saved as a draft...]

Curved Corners with transparent png background on IE6

June 11th, 2008

I’ve been playing in the wonderful world of css – partly for work, and partly for fun.

I wanted to have fluid sized, png-based, rounded-corner dialogs for a web site. This is something that has been solved many times, but not (as far as I can see) for internet explorer 6 – which still has a big share of the browser market.

The best solution I’ve found for other browsers is the one by Scott Schiller at Schillmania – http://www.schillmania.com/content/projects/even-more-rounded-corners/ – which uses a single image, with cunning sprite tricks to get it into position. But on ie6, it has to revert to gif images.

The problem is, you can use pngs on ie6 – most simply, by using the iepngfix.htc behaviour trick (see http://www.twinhelix.com/css/iepngfix/) – but it has one big problem – you can’t align the png images to the right or bottom, so most of the usual tricks used to display corners don’t work.

So, I’ve been hacking around with ways to do corners where all the images are top-left aligned. I have a solution, I’m not sure it’s perfect, but it works – see the demo page at http://www.sietsma.com/korny/corner_test/test.html. This works in ie6, ie7, Firefox 2 and 3, and Safari.

Some caveats:

- it uses the iepngfix.htc behaviour – I experimented with using the Microsoft AlphaImageLoader stuff directly, but iepngfix does some tricks that I can’t reproduce easily, so for now I’m using the code directly.

- it’s a long way from semantic markup; there are a number of divs in there just to make it look right. I can’t see a way around this – I could make some javascript to turn a semantically-nice html page into the mess shown, which might be a good idea – but the end result would be the same (and doing it in javascript can make for ugly corner loading, and hassles re-running the javascript if you populate stuff via ajax). Anyone with hints on how to make this more web-standards-friendly, please tell! I’m still pretty new to the world of front-end stuff.

- there’s a bit of fiddling to make links work properly – the ie png stuff causes screwups if you use relative or absolute positioning on a div with a background image, and then add links to it.  So I had to mess around a bit to work around this – and I probably need to mess around more to make it cleaner.

- there are some ie-specific bits in there, added via conditional comments; at least one of them was pure trial-and-error to get things lining up right!

- there is probably more work needed to make padding and things consistent across browsers.

I’ll try to blog more later about the details, and about how I generated the images…

Faking DNS with Ruby and Sinatra

March 7th, 2008

I had an annoying problem, so I needed a hacky solution…

At work, we have a large number of boxes with dynamic IP addresses. Getting a static IP address is a complete pain, and keeping boxes running is bad for the planet.

IP addresses don’t *usually* change, but the do change often enough to be annoying – especially when you want to run a VMWare server to do something background-ish, and find that it’s IP address has changed and you have to open the console just to find the new address. Bleah.

I’m sure a DNS/DHCP trick could be done somewhere, somehow – probably setting up a special DNS server somewhere locally could be done. But I needed something quickly, so some ruby hackery was the solution…

Basically I set up a tiny web server running Sinatra, a really really simple web framework. It just listens to http posts containing mac addresses, host names, and IP addresses, and stores them (in a YAML text file on disk – this isn’t meant to be scalable!). It also serves up a general status page, plus a simple /etc/hosts file snippet containing all known hosts.

I then have a really tiny ruby script that I run on each other box, which posts that box’s IP address to the server whenever it changes. (Currently this means on Ubuntu boxes, it runs from /etc/network/if-up.d/, on RedHat it runs from a script called /sbin/ifup-local)

At any stage, a user can load the file served by the sinatra server at http://the_server:4567/hosts – this gives a snippet of text that can be pasted into an /etc/hosts file (or the Windows equivalent). I might automate this step eventually, but for now it’s a manual process; it’s usually pretty clear when your hosts file is wrong, and not that hard to update it.

The code is real simple. First, the script to post data from each machine – this basically runs ‘ipconfig’ and extracts useful fields, it would need fiddling to work on Windows or anywhere that had a different ipconfig command (or didn’t use ‘eth0′):
(note – file saved as text attachment to get around this blog’s limitations):
postip.rb

Next, the server. Sinatra does most of the work for me – but it’s documentation is kind of thin, so some bits took some fiddling. Still, it really doesn’t get much easier than this:
fakedns.rb

And that’s it!