Wednesday, 23 January 2008

Adding a graph

So, Hands up all those that have 'use(d) GD;'?

Now that includes me!

So, I needed to show a table of numbers in a bar chart format. Quite simply, I had an arrayref of hash refs, each hash ref using keys date and percentage.

First off, the GD plot needs it as an arrayref containing 2 arraysrefs, the first of the x-axis (in this case the date) and the second of the percentages. ($cmap is an object of in-house stuff to work out appropriate colours to use).


my $plot = [[],[]];
foreach my $href (@{$arrayref}) {
push $plot->[0], $href->{date};
push $plot->[1], $href->{percentage};

my $graph = GD::Graph::bars->new(1000,400);
'dclrs' => [
map {
} (qw(red purple orange blue green yellow magenta cyan))],
'fgclr' => 'black',
'boxclr' => 'white',
'accentclr' => 'black',
'shadowclr' => 'black',
'y_long_ticks' => 1,
'x_label' => 'Date',
'y_label' => 'Percentage Activity'
return $graph->plot($plot)->png();

See, I said it was easy. :)

So, of course now I have said that, everyone wants their data in a graph format. Luckily, GD provides lots of graph formats. I just wish that we could submit to them as array of hrefs, rather than array of arrays, which I personlly think is

1) messier
2) relies on the end user to know the order the arrays should be in
3) Sends no additional information for legends (should this be needed), whereas the key can be the legend.

Oh well. I shouldn't complain really. I didn't have to write it. Don't you just love the CPAN!

(GD and it's suite of components by Lincoln D. Stein and searchable on CPAN. There are lots of additional stuff to link into Template::Toolkit, etc written by others. Have a look!)

FooMongers today. Don't yet know what we'll discuss.


Friday, 18 January 2008

Release of Acme::Hardware::Light::Bulb

OK, so it itsn't the biggest thing ever, but now Acme::Hardware::Light::Bulb is in sourceforge svn

If you SVN Browse, you can see a file trunk.tar, which should download you the tarball of the trunk. Else you could just get an svn co of the trunk.

I take no responsibility for anything that happens when you use these modules!

The coverage of tests though is 97,2%, and all the programming is to the standards supported
by Test::Perl::Critic.

You will need Carp and Class::Std.

The modules are

Acme/Hardware/Light/ - which generates a Light Bulb object
Acme/Hardware/Light/Bulb/ - which generates a Change Light Bulb object with as the base class.

Anyway. Yesterday was moving methods from the View to the Model, as that is where they should reside, and then today was tests. Coverage of two modules from 48 to 97% Hurrah!

Only 3 modules below 50% now, and total is 86% over the main project. We are getting there.

next week - creating a bar chart on a web page!


Thursday, 17 January 2008

Sprint ended

So, after a frantic week of finishing off the bits, and getting an extra feature to need to add in this release,
we deployed yesterday to massive applause.

Well, OK, so that was a bit of a lie. We deployed. I then needed to fix a bug which hadn't shown up in my
test version of the database, which then crashed the server, which then needed another fix.

However, it is done,and we added many new features. Some are ready for a need to change what group people belong to and the permissions of that group. Some are already there. Some need a new feature change in the next sprint to move from a table to a bar chart.

On other things, I was writing Acme::Hardware::Light::Bulb and Acme::Hardware::Light::Bulb::Change, since at PerlMongers last week, Michael and I couldn't find any modules relating to changing a light bulb.

We started it last week, and then I finished it over the week. Complete with96.7% test coverage, and completely happy with Test::Perl::Critic, and POD/distribution test coverage.

I tried to tarball it and mail it around, but for some reason the tar files would unpack.

I then went to upload to sourceforge via SVN, and ...

... accidently deleted the whole directory --AAHHH!

Exactly what svn/cvs is supposed to help prevent, I did whilst trying to put it in there. It was due to my own stupidity though. I did a mv instead of a cp within my dev area, and then deleting that moved directory to try again did me in. Note to self: NEVER mv a whole directory.

Anyway, I have resurrected the modules and all the critic stuff. I just need to rewrite the tests. However, it is all available on sourceforge should you wish to check it out.

Once completed, I will look to adding it to CPAN.

Enough for now. Back to my main job.


Wednesday, 9 January 2008

1 week left of the sprint to 7.0

So, 1 week left of the current sprint. Deployment of 7.0 is scheduled for next weds.

Manipulating to increase the level of the loader was not difficult. Putting it into the profile of the user, just a submit button to "promote", with the next level as a hidden field. Then in the tt2 template, a wrapper to ensure that the button isn't generated if the user him/herself is the viewer (we don't want users promoting themselves), or that they are already at "Gold" standard.

So, on to writing tests to exercise the code. We aren't doing to much test-driven development (SHOCK HORROR!), but rather writing the tests afterwards and using Devel::Cover to ensure it is as full as possible. (When FireWatir is improved, I may start looking at that for testing the web interface, but at the moment, it is just Test::More unit tests)

It is quite amazing how quickly the time can go still when writing tests. It isn't the sexiest of topics, but it is good to know that the code we are writing is able to be checked, in case something down the line changes it.

I am opting for writing new test units for each of the additions I have written, rather than adding them in to previous units. This may mean an additional time overhead when running the tests, but I have found it easier when they fail to see via the name of a unit what the problem is (which is reported at the end of the make test output) as well as via the name of the test itself (assuming you have verbose switched on).

So, over the last 3 working days, I have enabled a loader to be assigned a level, and tested that the level can be found for a user who is in the loading group, and that it is displayed in the right places.

Just need to tidy up a couple of extra options and we should be ready for deployment.

Bye for now

Thursday, 3 January 2008

Database manipulation

So, the time has come to start looking at the SQL in the models.

Simple premise - Loaders are tested and move through grade to be either Bronze, Silver or Gold.

Now a loader is a user, but a user isn't necessarily a loader. A loader is a user who also belongs to "Loading" group, but he/she can also be in other groups.

So I decided, and got my boss's agreement, that we should add the level to the joining table between id_user and id_usergroup (user2usergroup).

This makes it fun though as no programmatically where do I call for the level.

In model user2usergoup - but how do I know the user id. I only want the one!
In model usergroup - but there are many members of the group!
In model user - but the user can be in many groups.

I have opted (today) to go for model user, choosing to specify the id of the usergroup, and write my sql to call out of the joining table with the known $self->id_user().

It works, and with the templating system, selects the correct Medal icon for the level.

Tomorrow, its onto a new page to assign a level to a loader (assuming the forecasted snowfall doesn't hinder me). Although, I do now have the whole thing downloaded onto my MacBook, so I can do some work without internet connections. (Would need to hope that my littl'n will let me though).

That all for today.

Wednesday, 2 January 2008

A new year, a new start

Well, here we are. A new year. This is looking to be the most exciting for me yet, as it's the first one in a new home, and as a fully fledged programmer.

Also, Perl 5.10 is now out there. I don't know what that will entail where I work at the moment, but some
of the new features look good.

Just used Devel::Cover for the first time today. It produces some good results, and has set us up for a plan a few release cycles down from here (if the feature requirements ever slow down). Better coverage. We did have very good coverage for a while, but things slow down and you get the job of doing the work above doing the tests. However, our coverage is still very good. Just some room for improvement.

Also, I have discovered the joys (or lack of them) of ssh-ing files into databases, over wireless connections. My Mac is still tied up doing this after 4hrs. Fun and games all round then. Think I'll be leaving that to do it's stuff overnight then.

Programming today has been little, but necessary. We have agreed a release schedule to try to stick to, to ensure good releases and done when expected. Agile development with Scrum! It's the way forward.
Luckily my Boss doesn't need to sell this to me, as someone did that last Summer anyway, but I think it's good, and for any of you out there not doing it, Why? Read some of the Pragmatic Programmer (Hunt and Thomas) and Xtreme Programming (Beck) if you need more.

Anyway, end of the day for me now. Back tomorrow.

Info on Perl 5.10 can be found via and Devel::Cover from the CPAN.