Saturday, 27 December 2008

Technology after the Crunch


I was listening to ‘Analysis’, a BBC Radio 4 podcast about the credit crunch. It turns out that giving people six figure bonuses to destabilise the banking system isn’t the best way to run a modern economy. So given that driving the economy via financial services has ended in collapse and misery, the question being asked was what should replace it?

The answer was that we should get back to what we are good at – technology. The argument was that finance has gone too far, other countries do basic manufacturing better and cheaper (admittedly by working children 14 hours a day with no toilet breaks) and we’re not suddenly going to start exporting huge quantities of basic commodities. So technology will be the new driver.

So good news fellow tech nerds. When the dust settles on the credit crunch we will be the new investment bankers. So say farewell to tiny monitors, rickety office chairs and crappy vending machine coffee and say hello to corner offices, chair massages and ludicrous annual bonuses. It’s Aston Martins’ all round. So when I’ve finished delivering a minor website upgrade I see you all in the champagne bar for a 4 day celebration. It’s only what we deserve.

Thursday, 25 December 2008

The Long Day's of Christmas


I once worked in an office where the boss didn’t understand the concept of Christmas. He wasn’t scrooge like – because scrooge acknowledged the existence of Christmas. My boss didn’t even go that far – he just wasn’t aware of it at all. The Christmas season would run like this -

On the First Day of Christmas my PM gave to me
A new spec for a shiny app

On the Second Day of Christmas my PM gave to me
Two day’s training
And a new spec for a shiny app

On the Third Day of Christmas my PM gave to me
Three pep talks
Two day’s training
And a new spec for a shiny app

On the Fourth Day of Christmas my PM gave to me
Four tight deadlines
Three pep talks
Two day’s training
And a new spec for a shiny app

On the Fifth Day of Christmas my PM gave to me – five change requests
Four tight deadlines
Three pep talks
Two day’s training
And a new spec for a shiny app

On the Sixth Day of Christmas my PM gave to me – six bugs a breaking
Five change requests
Four tight deadlines
Three pep talks
Two day’s training
And a new spec for a shiny app

On the Seventh Day of Christmas my PM gave to me – seven clients complaining
Six bugs a breaking
Five change requests
Four tight deadlines
Three pep talks
Two day’s training
And a new spec for a shiny app


On the Eighth Day of Christmas my PM gave to me – smoke tests a smoking
Seven clients complaining
Six bugs a breaking
Five change requests
Four tight deadlines
Three pep talks
Two day’s training
And a new spec for a shiny app


On the Ninth Day of Christmas my PM gave to me – nine weekends working
Smoke tests a smoking
Seven clients complaining
Six bugs a breaking
Five change requests
Four tight deadlines
Three pep talks
Two day’s training
And a new spec for a shiny app


On the Ten Day of Christmas my PM gave to me – ten releases cancelled
Nine weekends working
Smoke tests a smoking
Seven clients complaining
Six bugs a breaking
Five change requests
Four tight deadlines
Three pep talks
Two day’s training
And a new spec for a shiny app


On the Eleven Day of Christmas my PM gave to me – eleven coders weeping
Ten releases cancelled
Nine weekends working
Smoke tests a smoking
Seven clients complaining
Six bugs a breaking
Five change requests
Four tight deadlines
Three pep talks
Two day’s training
And a new spec for a shiny app


On the Twelfth Day of Christmas my PM gave to me – a twelve week extension
Eleven coders weeping
Ten releases cancelled
Nine weekends working
Smoke tests a smoking
Seven clients complaining
Six bugs a breaking
Five change requests
Four tight deadlines
Three pep talks
Two day’s training
And a new spec for a shiny app


Merry Christmas!!

Wednesday, 24 December 2008

Dr Who and Gender Reassignment


It’s as seasonal as Turkey, Santa Claus and squabbling with relatives. The Christmas special of Dr Who is on BBC tomorrow and it should be a particularly special special since Mr David Tennant is stepping down from Timelord duties. So who will be taking his place in the swirling time vortices of BBC central? The smart money at the moment appears to be on David Morrisey with Robert Carlyle on the outside track. While these are both worth recipients of the keys to the Tardis I want to give a shout out for Tilda Swinton.

I truly believe Ms Swinton would be a timelord to remember. She played an excellently disturbed turn recently in Michael Clayton and her other worldliness is without question after her performance as the Angle Gabriel in the otherwise average Constantine. She is stylish, elegant and an excellent actress. So who could be better for the most important role of our age?

There may well be nay sayers who point out that Ms Swinton is in possession of an awkward set of XX chromosomes. I say being a lady of the female persuasion is no problem. Firstly, she is no stranger to androgyny. The aforementioned Angel Gabriel was a fella angel and the more seasoned Swinton watchers among you will remember Orlando - the entire premise of which was based on shifting sexuality. Secondly, this is science fiction. Someone changing gender a little bit is hardly beyond the realms of what goes on in the genre. So long as Dr Who doesn’t descend into Deep Space Nine levels of ludicrousness then that’s OK by me.

Furthermore Tilda meets the most important prerequisite for Doctorhood. She is British. Whilst I think that most Whovians would quite happy to accept a bit of gender reassignment during a regeneration – if the Doctor was to become more trans Atlantic then thousands of geeky sci-fi fans would recoil in horror. An American Doctor would be a step too far. It would see us putting down our Games Workshop bags, manning the barricades and throwing our shoes at George Bush.

Saturday, 20 December 2008

Self Documenting Code – Gimme Just One Less Line

I was in a technical interview a good while back and it was review your answers to the tech quiz time.

INTERVIEWER: OK, that’s a good answer. That would work but can you do it in less lines of code
ME [chewing pen]: Errmmm –OK that’s it in two lines
INTERVIEWER: OK – but I’m sure you can do it in one line
ME [scratching head]: Oooooo – Errmmmm – that’s one line
INTERVIEWER: Well Gee – that does it. But I’m sure you can do it in maybe 10 characters
ME [Weeping real tears]: Ahhhhhhhh !!!!!! Please let me out.

OK – maybe the end of the interview went a bit better but I must have spent a good 20 minutes frantically trying to trim down my code to the size of an atom. I retrospect I think it was a fair enough way to grill me – but in the day to day work of chipping away at in the salt mines of computer code do you ever want to trim your code down to the bare minimum?

Consider this code
private static string RemoveTrailingTag(string input, string tag)
{
if (input.Length >= tag.Length && input.Substring(input.Length - tag.Length) == tag)
{
input = input.Substring(0, input.Length - tag.Length);
}
return input;
}
OK – it’s trimming tags from strings. But what on earth is the 'if' statement doing. The revised code tells us
private static string RemoveTrailingTag(string input, string tag)
{
if (HasTrailingTag(input, tag))
{
input = input.Substring(0, input.Length - tag.Length);
}
return input;
}

private static bool HasTrailingTag(string input, string tag)
{
return input.Length >= tag.Length && input.Substring(input.Length - tag.Length) == tag;
}
OK – the ‘if’ checks for the trailing tag. Admittedly I’ve expanded the code but I’m a big believer in more is less (confusing). Of course self-documenting code isn’t new (Steve McConnell etc..) but there does seem to be a real mind set of trimming code down to the smallest, most elegant (i.e. unreadable) fragments. It’s as if we’re developing assembler code to run on the chip of a washing machine. Except most of us aren’t and never will be.

Wednesday, 17 December 2008

Flow

There’s all kinds of advice around for career development in IT (career calculus, coding horror, red queen) but if I really think back to projects that have gone well when I’ve received a pat on the from the boss du jour – it seems effortless. I haven’t waded through treacle and hacked away the woody vines of confusion to get the outcome – it’s just happened. I’ve felt energised, focussed, in the zone – I’ve been in flow

Flow is a psychological state when concentration is easy. It’s the time when you lose yourself because the task is so absorbing. It’s the time when you look up and everyone has gone home except the office cleaner and you didn’t notice. It’s the time when you LOVE your job. I contend that to truly be a great developer you should aim to spend as much time as possible in the groove i.e. in flow.

There are certain things from a task perspective that can encourage this. The task should be challenging without been overwhelming. It should have immediate feedback (software development provides this in spades), have a clear goal and you should have a measure of control over it.

Unfortunately many of us for much of the time don’t have control over our individual tasks at work. So are there ways an individual can broaden there capability to go into flow? Michael Buffington gives some tips but interestingly practicing martial arts, yoga or meditation have been linked to increased flow states. So if you want to do well in your job you could work late, read a new text book and offer your wash your boss’s car. Alternatively you could take up karate, buy a yoga mat or meditate before work.

Sunday, 14 December 2008

DataTable Filtering Gotcha

The mission – if you choose to accept it is to filter a .Net DataTable to return results from a year or more ago. The code is
DataTable dtDataTable = GetDataTableMethod()

//.. limit the dataset
DataView dvDataTable = new DataView(dtDataTable);
dvSurveyList.RowFilter = "DateField < '" + DateTime.Now.AddYears(-1) + "'";
Our spies tell us that it doesn’t actually work. Agent tech splurge what is the solution? Stand well back folks while I insert the missing line.
DataTable dtDataTable = GetDataTableMethod()
dtDataTable.Locale = CultureInfo.CurrentCulture;

//.. limit the dataset
DataView dvDataTable = new DataView(dtDataTable);
dvSurveyList.RowFilter = "DateField < '" + DateTime.Now.AddYears(-1) + "'";
To me this makes sense. If you’re playing with dates then you’ll need the culture information – dates being different in different cultures. The odd thing is that the first set of code worked perfectly – until it stopped working. I have to confess I still don’t know why.

Wednesday, 10 December 2008

Software Estimation for the Courageous


In days of yore a man used to prove his bravery by a mighty quest for a fair maiden, the slaying of a ferocious dragon or by acts of great swordsmanship on the battlefield. Sadly in modern times these opportunities rarely present themselves to the average software developer. But fret not stout of heart – there are still ample opportunities for bravery without moving away from your monitor. Simply give an estimation of how long a software project is going to take using the following methodology.


I truly believe that software estimation is blackest of all the black arts in software development. Entire books are (quite rightly) written on the subject.


The best and simultaneously the worst advice I’ve have ever read about estimation comes from Crash – Learning from the World’s Worst Computer Disasters. Quite simply - sit down in a quiet room with a bit piece of paper and a large mug of coffee and truly and honestly work out how long you believe the project will take. Miss nothing out. Remember the testing, remember the deployment, remember the reworking, remember it all. Then TRIPLE it. No matter how bleak the answer looks – bravely go out and tell your project manager. He/She will not thank you for it. They will request re-evaluations, ask second opinions and doubt your sanity. You may be sidelined, sneered at or send off in exile to the build team. You will be tattered, torn and unloved but you will be correct.


If you are brave then try this. I did once and it caused a career damaging fight between the head of development and the project manager. The project manager left, the head of development sulked but the work was delivered in the (tripled) timescales that I said. I was unloved but correct. I was brave. I never did it again.

As an addendum to this – a far better way of estimating projects would be to actually start to build historic data in your company as base predictions on that. Steve McConnell gives excellent advice on this in Rapid Development. The moral of the above little anecdote is that it’s not enough to be correct; you have to be correct and believable - and that takes evidence.

Saturday, 6 December 2008

T-SQL Identity

This is probably as old as the hills but I still see this everywhere. What’s wrong with this line of T-SQL
Declare @PrimaryKeyVariable int
Set @PrimaryKeyVariable = @@IDENTITY
Nothing until it gets deployed into a high volume usage situation and the number of users ramps up after a few months. Then it will blow up and someone will be in at 3a.m. desperately trying to restore the referential integrity of the database.

The problem is that it will set the variable to the most recently set identity flag in the database no matter who has done it. That might be you or it might be another connection – thus linking up/deleting/updating the wrong records. If you’re lucky the transaction will fail. If not then you’ll be digging around in those two hourly transactional backups to get it back. Oops.

And the answer is really straight forward. Just use this instead
Declare @PrimaryKeyVariable int
Set @ PrimaryKeyVariable = Scope_Identity()
The identity is now only taken from current connection. It’s scoped – just like mother always used to scope her identities. Lovely.

Wednesday, 3 December 2008

The BMA, BCS and the Devil


It’s said that the best trick the Devil ever performed was convincing mankind that he didn’t exist. In the same vain the best trick the British Medical Association (BMA) performed was convincing the British public that it’s not a union. The BMA appears to style itself as a professional body that’s only concern is for patient welfare. The doctors that I have personally known are more of the opinion that it is a highly efficient union getting the absolute best deal for its members. I have nothing whatsoever against the BMA, in fact I wish we had a bit of that in computing. But instead we have the British Computer Society (BCS).

I’m sure that the good people at BCS believe they are doing their very best to professionalise the computer industry. However the fact remains that I have never met anyone who professes to be a member let alone speaks of the BCS in glowing terms. Never …. Ever.

Play this game with your family and friends. Which one is the odd one out? The BMA, The Law Society, The Royal Institute of Charter Surveyors, The Mafia, The British Computer Society. Answer – the BCS because the rest actually seem to do something for their members.

Saturday, 29 November 2008

.Net Repeater - Say it again

Up till recently I’ve been very suspicious of the higher level tools that ASP.Net 2.0 offers. Site Map, Menu controls, the dreaded Web Parts. Be a man – write it yourself. This even stretched to a refusal to use the DataGrid and related controls. I can do better with a small screwdriver and a dynamic control collection. And for years I stuck to that.

Recently though I’ve been working in an environment where they are big fans of Microsoft controls, so as a wise man once said ‘When in Rome use the same ASP.Net controls as the Romans do’. With that in mind I have been getting my hands dirty with DataGrids, DataViews and Repeaters. One of the things that has always put me off of these controls is which control do you use for what. The confusion was so great that often I had 2 or 3 different controls on a page at one time to compare, contrast and moan about. The result of all this moaning/development was

  1. For paging – use a DataGrid
  2. For an easy primary key for each row – use a DataGrid
  3. For multiple columns – use a DataView
  4. For fine control over what is displayed on each cell – Moan a lot then go back to using a dynamic collection of TableCells (that designers will never, ever be able to see).

But then as I was walking on the road to Damascus (a local falafel shop) a bright light shone from the clouds and a wise voice spake unto me and said “don’t mess around with all those other controls – just use Repeaters”. Thus and verily I journeyed back to the promised land and recoded all my grids with repeaters using the following divinely inspired techniques to get over the aforementioned limitations.



Primary Key for each Row
Use a hidden field (i.e. label with visibility set to false) and write the value into that

<asp:Repeater runat="server">
<ItemTemplate>
<asp:Literal ID="lblPrimaryKey" runat="server" Visible="false"
Text='<%# DataBinder.Eval(Container.DataItem, "PrimaryKeyId") %>' />
<%# DataBinder.Eval(Container.DataItem, "Name") %>
<%# DataBinder.Eval(Container.DataItem, "Address") %>
<%# DataBinder.Eval(Container.DataItem, "DoB")%>
</ItemTemplate>
</asp:Repeater>
Once written in the primary key can be accessed through the event handlers of the data grid – see below.
protected void Repeater1_ItemCreated(object sender, RepeaterItemEventArgs e)
{
Control lblKey = item.FindControl("lblPrimaryKey");
Int primaryKey = Int32.Parse(lblKey.Text);
//do something with the primary key
};
Multiple columns
Use divs for the columns and float them to the left (see http://css.maxdesign.com.au/floatutorial/ for float tutorial). The below code shows it in action.
<asp:Repeater ID="Repeater1" runat="server">
<HeaderTemplate>
<div style="width:800px;">
</HeaderTemplate>
<ItemTemplate>
<div style="width:200px;float:left;">
<%# DataBinder.Eval(Container.DataItem, "DisplayField")%></div>
</ItemTemplate>
<FooterTemplate>
</div>
</FooterTemplate>
</asp:Repeater>
The above example gives 4 columns i.e. 800px box surrounding the repeater with divs of 200px floated inside – sooo only 4 can fit before a new row is started. Obviously you don’t need to be a maths genius to work out the numbers for other numbers of columns (e.g. 600px outside, 200px divs – 3 columns etc…).

Fine control over each cell
If you have a requirement to modify each cell depending on the primary key of the row – leverage the On_ItemDataBound event of the repeater grid and modify the contents of each cell as it’s rendered
<asp:Repeater ID=" Repeater1" runat="server"
OnItemDataBound="Repeater1_ItemCreated">
<ItemTemplate>
<asp:Literal ID="lblPrimaryKey" runat="server" Visible="false"
Text='<%# DataBinder.Eval(Container.DataItem, "PrimaryKeyField")%>' />
<%# DataBinder.Eval(Container.DataItem, "Name") %>
<%# DataBinder.Eval(Container.DataItem, "Address") %>
<asp:Button ID="btnGo" runat="server" Text="Details" />
</ItemTemplate>
</asp:Repeater>
The below event is fired when the grid is rendered
protected void rptSurveyListNao_ItemCreated(object sender,
RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item
e.Item.ItemType == ListItemType.AlternatingItem)
{
Control lblSurveyStatus = item.FindControl("lblPrimaryKey");
Int primaryKey = Int32.Parse(lblSurveyStatus.Text);
If(primaryKey > 0)
{
btnGo = (Button)item.FindControl("btnGo");
btnGo.Enable = true;
}
}
}
It the above example we could control the button activity based on the primary key in the repeater row.

Paging
Use the PagedDataSource following the technique outlined in 4GuysFromRolla. . OK hands up for this one – I’ve never used it but I’ve been assured by real life people that it works



And from that day forward all the HTML coders and designers in the land
came to pay homage to the lowly Repeater because they could easily access the
HTML tags behind the controls and not struggle with the arcane DataGrid styling
properties.

Thursday, 27 November 2008

Accelerando - Serialising Lobsters


I make no apologies about being a sci-fi geek. Being a software geek pays the bills so I think I deserve a bit of extra-curricular sci-fi geekiness. In that vain I just have to recommend Accelerando by Charles Stross – it drips with geeky goodness.

I can’t begin to summarise the plot – all I can do it assure you that the book positively fizzes from page 1. Not enough, you want more of a reason to buy, read and adore this lovely tome. OK
  1. Mr Stross is was a computer scientist amongst other things and it the first sci-fi book that I’ve read to really have that embedded in it. At the start of the book sentient lobsters get serialised and sent up a data stream – Fab.
  2. One of the main characters is a cat. It total catches the animal’s don’t give a damn attitude – double Fab
  3. Charlieboy Stross comes from my hometown, Leeds. I have a LOT of regional pride soooo – Triple Fab.
If I had to categorise it then its cyberpunk without the noir elements and it’s actually well written unlike other so called cyberpunk classics i.e. everything I’ve ever read by William Gibson.

Sunday, 23 November 2008

Website Publishing Gotcha

I was trying to publish a web site in Visual Studio 2005 this week and kept coming across this strange error when browsing to the published website.

Cannot convert type 'ASP.login_aspx' to 'System.Web.UI.WebControls.Login'

After some pen chewing, head scratching and news group ferreting I came across the solution in this posting.

Apparently if you call an aspx page the same as a standard WebControl then the publishing freaks out. Which fool would do that? Well this fool does on a regular basis. I always call my log in pages Login.aspx – the same as the login control. The solution – a quick rename of the page to Default.aspx and stride manfully out of the office declaring that the website is now released into the wild. Job done (and will be done a bit quicker next time).

Wednesday, 19 November 2008

Boring Names

The other evening I was reflecting on past projects I've worked on – as a gentleman often does. When I started work as an IT tadpole I first worked on PEO, graduating to RMS then TMS. I then worked on the CRS Portal, EMISWeb and interfaces to LV and PCS. Lately I have been doing work with BVA, NAO and ePIMS.

Other than suffering under my hand – what have all these applications got in common? Are they all high-transaction wonder apps? No. Are they all shrink-wrapped money spinners? Not that either. Are they all groundbreaking super fast system software? Nope, nope, nope. The real connection is that they all have boring names.

I don’t know if there is something about business type applications that encourages people to give them vague three letter acronym names. Perhaps users of these applications need to be in a sedate state of mind before use so hand them software in a grey box with a vague name. Otherwise hyper stimulation and all kinds of unpleasantness may ensue.

However 7 years of working on apps with generic TLA names is enough. So, starting from tomorrow I’m going to rechristen all my apps. I won’t be working on IPD tomorrow – it will henceforth be called Timux Turbo Polka Fortress Green Hat v5.1. My project manager will be delighted.

Saturday, 15 November 2008

ExecuteNonQuery Gotcha

Here’s something that made me roll my eyes this week. I’ve been trying to get the number of rows executed returned from SQL Server to an ASP.Net data layer. It promised to be straight forward but it had a cheeky little gotcha nestled in the middle of it. To take the simplest example for demo purposes (all error handling type stuff omitted)

The stored procedure

CREATE PROCEDURE usp_TestProc
@PersonId int
AS
BEGIN
Set Nocount On

Update Person
Set
FirstName = 'Willy',
Surname = 'Wonka'
Where
Id = @PersonId
END

The calling business layer

conn.Open();
cmdNonQuery = conn.CreateCommand();
cmdNonQuery.CommandType = CommandType.StoredProcedure;
cmdNonQuery.CommandText = “usp_TestProc”;
cmdNonQuery.Parameters.AddRange(sqlParameters);
numberOfRecords = cmdNonQuery.ExecuteNonQuery();
 

Logic (and the .Net API documentation) dictates that the ExecuteNonQuery method returns the number of rows. But it steadfastly returns -1 no matter what is occurring in the database.

So what is happening?? It turns out that the Nocount setting stops this information coming back. Removing the statement – or setting NoCount Off causes the ExecuteNonQuery method to behave as expected. It returns -1 if no rows affected otherwise the number of rows actually affected.

This would probably be too arcane to worry about except the SQL Server standard template for creating stored procedures includes the Set NoCount On statement. In other words – select ‘create new procedure from the SQL Server menu’ and you get this template

CREATE PROCEDURE <Procedure_Name, sysname, ProcedureName>
-- Add the parameters for the stored procedure here
<@Param1, sysname, @p1> <Datatype_For_Param1, , int> = <Default_Value_For_Param1, , 0>,
<@Param2, sysname, @p2> <Datatype_For_Param2, , int> = <Default_Value_For_Param2, , 0>
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;

-- Insert statements for procedure here
SELECT <@Param1, sysname, @p1>, <@Param2, sysname, @p2>
END
GO

Very lovely – except it contains the very code that disables the proc return values. Ouch.

Wednesday, 12 November 2008

There are 10 types of people

It’s that rarest of all things – a joke about number bases

There are 10 types of people – those that understand binary and those that don’t.

Hahahahaha – brilliant. Tell you friends, write it on all your Christmas cards, put it on your e-mail signature – spread that joy. Sadly it doesn’t work quite as well in hexadecimal

There are 1A types of people – 1 that understands hexadecimal and 25 that don’t

However I’m convinced it can be made to work in other bases. I’m going to apply for an EU grant to study the application of this joke to other mathematical systems. If they’ll fund the Large Hadron Collider I’m sure they’ll fund this similarly important work.

Friday, 7 November 2008

IT Demographics and Logan’s run


I have a few baseless theories about the IT workplace – here’s one.

Logan’s Run is an old sci-fi film starring Michael York and the much loved (by me anyway) Jenny Agutter. The basic premise is that in a post apocalyptic society youth is prized above all else. So much so that when a citizen reaches 30 they are executed. And don’t try to run off because Michael York will don his leather pants, run after you and shot you to bits. Ouch!

I’ve often thought that software development must work in the same way. When you reach a given age, probably about 40, you’re taken quietly into a room for a bit of professional development and quietly exterminated. What else can explain the lack of older developers in a profession that’s been going in strength for 30 years or more.

Ok, there may be other explanations.
  1. Lot’s of people leave the profession after 5-10 years. The plasterer that did my dining room was an ex-IT worker. I think he was happier with his trowel.

  2. People get rescued into management/project managers etc…. But there aren’t that many management positions.

  3. People go into related position because the rate of change in IT is too much. I’ve known a few testers in that position. There are undoubtedly IT trainers in the same position.
Alternatively maybe Michael York is stalking the older members of the profession. Beware of blond actors in leather pants everyone.

Saturday, 1 November 2008

Recaptcha


It’s very wisdom of the masses, the power of crowds, web 2.0, wikinomics and all that – but your very own website can digitise books without trying. Using captcha’s the little squiggles many of us spend much of the time entering in can miraculously help digitise texts.

It’s all handled by the people at Carnegie Mellon University (http://recaptcha.net/ ) Basically –they provide a plug it to website that provide the captcha display for your website. It’s a few lines to hook it up and then you’re off. I did it in PHP but it available in .Net, Java and more languages than I’ll ever know.

To implement

  1. download the relevant library i.e recaptchalib.php
  2. Sign up to recatpcha for a public and private keys
  3. Code to display the captcha in PHP below

<?echo recaptcha_get_html($publickey, $error); ?>

4. And to deal with the post back – a bit more but not rocket surgery.

if ($_POST["submit"])
{
$resp = recaptcha_check_answer ($privatekey,
$_SERVER["REMOTE_ADDR"],
$_POST["recaptcha_challenge_field"],
$_POST["recaptcha_response_field"]);

if ($resp->is_valid)
{
.. do some processing to the valid form
}
else
{
# set the error code so that we can display it. You could also use
# die ("reCAPTCHA failed"), but using the error message is
# more user friendly
$error = $resp->error;
$displayForm = true;
}
}

I was listening to the leader of the project on a Digital Planet podcast. They use OCR to get about 80% of the words and farm the hardest 20% out to people doing captchas. Apparently they are digitising hundreds of books a day through this. I am genuinely impressed.

Sadly though – it appears that captchas generally are gradually becoming less effective . But I guess so long as your site is more secure that the next guys… (all IT security professional grind teeth at this statement – OK, I realise it’s no better than recommended that I hide my website registration under a stone).

Saturday, 25 October 2008

Curved Box No.9054

Does the world need another HTML curved box – Nope. Is there already thousands of curved boxes on the internet – There certainly is. Should anyone else bother publishing yet another curved box – Probably not. So with that in mind – here’s a curved box I wrote a while back. It doesn't have borders but you can put the heading in a different colour if you want.

The only advantages to this box is


  1. It works

  2. I actually understand how it works unlike all the other curved boxes I found which seemed utterly mysterious


Images for the corners are available here (top right, bottom right, top left, bottom left)

CSS

.roundBox
{
float:left;
width:270px;
background-color:#fedd52;
margin:0;
padding:0px;

}

.roundBox .heading
{
width: 240px;
float: left;
text-align:center;
margin: 10px 0 0 0;
font-weight:bold;
font-size: 16px;
}


.roundBox .LT
{
float:left;
height:15px;
width: 15px;
background: url(../images/curveLT.jpg) no-repeat left top;


}

.roundBox .LB
{
float:left;
height:15px;
width: 15px;
background: url(../images/curveLB.jpg) no-repeat left bottom;


}

.roundBox .RT
{
float:right;
height:15px;
width: 15px;
background: url(../images/curveRT.jpg) no-repeat right top;
}

.roundBox .RB
{
float:right;
height:15px;
width: 15px;
background: url(../images/curveRB.jpg) no-repeat right bottom;
}

.roundBox .contentOuter
{
clear:both;
width: 100%;
}

.roundBox .contentInner
{
padding:10px;
}

HTML

<div class="roundBox">
<div class="LT"></div>
<div class="heading">Box Heading</div>
<div class="RT"></div>
<div class="contentOuter">
<div class="contentInner">
Content, Content, Content, Content
</div>
</div>
<div class="LB"></div>
<div class="RB"></div>
</div>

This curved box has already been released into the wild. If some one was to release another one, there is a good chance that this rarest of all HTML constructs might well breed in its natural environment. We can but hope.

Wednesday, 15 October 2008

Alternative HTTP Output

Websites are tricky fellows. They'll churn out HTML output all day long without any thought or consideration to other mime outputs. If you want your ASP.Net website to chuck out other response types – then use the Http Response Stream as below

For PDF
System.Web.HttpContext.Current.Response.Clear();
System.Web.HttpContext.Current.Response.ContentType = "application/pdf";
System.Web.HttpContext.Current.Response.AddHeader("content-disposition", "attachment; filename=ePIMSDataExportReport.pdf");
System.Web.HttpContext.Current.Response.OutputStream.Write(bytes, 0, bytes.Length);
For Excel
System.Web.HttpContext.Current.Response.Clear();
System.Web.HttpContext.Current.Response.ContentType = "application/vnd.ms-excel";
System.Web.HttpContext.Current.Response.AddHeader("content-disposition", "attachment; filename=ePIMSDataExportReport.xls");
System.Web.HttpContext.Current.Response.OutputStream.Write(bytes, 0, bytes.Length);

Thus easy to extent to other mime types such as images and video and so forth. Of course you'll need a source of bytes – e.g. from a Sql Server Report

byte[] bytes = report.Render(
"PDF", null, out mimeType, out encoding, out extension, out streamids, out warnings);

But once you have that – it’s in the pool kids and away you go.

Friday, 10 October 2008

Cool Tools: ClipX



Here’s how I see the history of tool development

  1. Stone Age man discovers the hand axe.

  2. James Watt creates the Steam Engine

  3. ClipX is written and released onto the Internet.


That’s it – all major tool based landmarks covered. There may be cynics who question the inclusion of ClipX into this 3 point history of technology. To them I say ‘pish’, ‘tish’ and ‘pish’ again. ClipX has revolutionised my desktop behaviour (sadly all my other behaviours remain steadfastedly unrevolutionised).

For years I though it was a law of the universe that you could only ever cut and paste one thing at once. You pop it onto the stack and push it off. ClipX stores a list of 25+ cut and copied objects and you can access them all with a Ctrl-Shify V (see this post’s picture). I kid you not – it’s a marvel to work with. I’m in the habit now of copying half a dozen chunks of code confident that I can retrieve them for further code based tomfoolery later.

And what is the price. Well to you governor it’s entirely free. So go mad – down load a copy and cut and paste until you can’t cut and paste anymore. Lovely.

Wednesday, 8 October 2008

Thank you, Mountain View


I’ve been (obsessively) tracking hits on techsplurge with blogtracker and after a mere 5 weeks I am now the proud owner of my very first hit. So thank you the guy or girl in Mountain View, California who is my very first viewer.

But that’s not all. It appears that Mountain View is where the headquarters of Google is located. I feel certain that it’s Larry Page and/or Sergey Brin themselves who have been browsing techsplurge particularly after my in depth technical assessment of boogle.com. Moreover, I would say it’s highly likely that I’m being hand picked by the Google founders to head up the Boogle Phase 2 taskforce. Well I have some good news for Larry and Sergey. I ACCEPT THE JOB. I’m already packed, I’ve cancelled the milk and my wife is looking forward to some California sunshine. So as soon as the contract comes through – I’m off. Thanks guys.

Thursday, 2 October 2008

JavaScript and Html Not-Comments

Here’s a puzzle for your Mum, Grandma or beloved

Take one scoop of HTML

<body>
<!--element 1 -->
<div id="element1">Content</div>
<!-- element 2 -->
<div id="element2">Content</div>
</body>

And run a cheeky sprinkle of JavaScript against it


Var element = document.getElementById("element2").previousSibling
Alert(element);

Which element do you hit?

You don’t need to be a Web developing genius to work out that it going to pickup the div element2 then navigate back one so it will hit div element1. Easy! Welll – not really – it actually navigates to the comment. The alert spits out

<!-- element 2 -->

So if you’re navigating the JavaScript DOM that can be a real gotcha. What I found particularly interesting is that this code totally breaks my mental model of how all programming/scripting/markup languages work i.e. comments never count. They’re not included in binaries, they don’t count for code coverage analysis, they don’t display on the UI. Comments never count – except when they do.

Saturday, 27 September 2008

Boogle – The future of search


Why, oh why, oh why does Google waste it’s time developing cutting edge applications such as Google Earth, Google Checkout, Chrome etc… when hiding in the Google closet of unwanted applications is Boogle. I first came across Boogle 6 years ago when a co-worker in what can only be described as a moment of extreme boredom, was inputting variants of google.com into a browser. Imagine everyone’s delight when he came across Boogle – a search engine which fires a random quotation and a completely unrelated but vaguely inspiring image at you on each page refresh.

So I was completely delighted to see this week that Boogle still exists. Sadly its stablemate, Froogle, has become the boring Google Products Search Beta. A sad demise – but the important one, Boogle still exists, its heart beating stronger than ever. I have this vision that in Google Towers there are teams of attractive, thrusting, excessively enthusiastic American youths working on the next release of Google Apps/Youtube/Gmail etc… and in one dusty corner is a bearded, pallid individual (sex undecided) who has sole responsible for maintaining Boogle.

But let’s all rise up now and show our support for this benighted individual. So I urge you all to forget Google.com, cast aside Google.co.uk and delete your personalised Google accounts and make the mighty application that is Boogle the homepage for your browser. And if you work on a I.T. helpdesk – make Boogle the homepage for your entire organisation. They’ll thank you for it in the end.

Saturday, 20 September 2008

Cool Tools: Regmon

There comes a time in every young software developer’s life when he casts his eyes over the sweeping vistas of software development, over the swirling streams of XML schemas, the limpid pools of database connection strings and the great herds of thread safe applications and he notices a small glinting software tool. He reaches down takes the tool noticing the way the light shines off its surface and he thinks to himself “why the bloody hell didn’t I know about this before?”

I had just such a moment with Regmon – a tool which monitors registry access. Embarrassingly I’d never heard of it but massively useful in finding out why my app wasn’t picking up it’s config. In my (vague) defensive – I primarly a web application developer and it more usual (certainly with ASP.Net) for the config to be stored in XML file.

Regmon is part of a library of windows type tools at SysInternal . The cryptic names look very enticing. Filemon also look good for pen chewing “why doesn’t this installation work” type tasks. And I can’t wait to joust with my colleagues tomorrow using PsKill. No idea what it does but I bet it can be lethal in the wrong hands.

Saturday, 13 September 2008

How to make friends and deal with Byzantine .Net control Ids

Anyone who spends anytime developing in ASP.Net rapidly builds up hierarchies of controls. They can rapidly become deep. A typical hierarchy might be

  • Master Page

  • Child Page

  • User Control

  • ASP.Net control


This is simple – multiple stacks of child pages user controls etc.. are possible and I certainly use them all the time.

What surprised me when I started doing this was the effect it had on the element Ids as exposed to JavaScript. I printed off one such example this week – an id of a dropdown list.

ctl00_ContentPlaceHolder1_dashboardMain_ddlOrganisation

Mmmmm – but I thought I’d just called it ddlOrganisation. Apparently not. The breakdown is

  • ct100 – from the master page

  • ContentPlaceHolder1 – from the child page (hold my hand up for this – it’s a rubbish name)

  • dashboardMain – the user control

  • ddlOrganisation – my control that I want to target.



OK, fine. Lots of under the hood .Net stuff going on. But it confused the hell out of me when I wanted to target this stuff in the Javascript DOM. Once you figure out the ID then you could just use it. But any change in the names of your controls higher up in the hierarchy will break it. And it will break it 5.00 p.m. on the day before you are due to ship – believe me. A better idea is to use the ClientID property that ASP.Net controls expose. This will provide the Byzantine ID that we see above.

So to add a JavaScript event I would add the JavaScript into the attribute collection of the control within the ASP.Net page – so adding a JavaScript method to the OnSelect event

ddlOrganisation.Attributes.Add("OnChange", "activateSurveyStart('" + ddlOrganisation.ClientID + "')");

And to complete the circle – register the Javascript file programmatically in your usercontrol to avoid tears later

Page.ClientScript.RegisterClientScriptInclude("genericScript", "scripts/genericScript.js");

Not a revolutionary method admittedly (none of my stuff ever will be – promise). But I use this all the time and I think it’s more obscure than it should be. And the making friends thing? Well, be nice to people and bring cakes into your office every Friday. That’ll do the trick

Sunday, 7 September 2008

The Red Queen



"Well, in our country," said Alice, still panting a little, "you'd generally get to somewhere else — if you run very fast for a long time, as we've been doing."

"A slow sort of country!" said the Queen. "Now, here, you see, it takes all the running you can do, to keep in the same place. If you want to get somewhere else, you must run at least twice as fast as that!"

Alice Through the Looking Glass

As a software developer – I feel a bit like Alice Through the Looking Glass. It’s not that I dress like a Victorian school child (we’re only allowed to cross dress on a Friday – boooo). It’s that I often seem to be running to stand still. Just mastered ASP.Net 1.0. Here’s 2.0 – to dig through. Just at the top of your stored procedure game. Here’s LINQ to chew on. Really chuffed that you’ve done a fancy windows form with tabs and everything. Well here’s Windows Presentation Layer. And Sliverlight, and the Semantic Web and WAP, and XAML and WCF and and and and ………….

How is it possible to manage? Is it? Should we just abandon all hope? In my humble opinion – if you want to continue to be a software developer you’ve got to do something. Probably quite a few things. Here’s a few


  1. Do some certified type exams – Microsoft, Sun et. al.

  2. Read a book. Maybe go mad and read two. Jeff Attwood (IT blog hero) comments that’s developers don’t read – easy to fix. Read something.

  3. Join a professional society (IEEE, BSC etc..)

  4. Volunteer to do a bit of IT outside work

  5. Hope that you get to use exciting new technologies in work – or change jobs to one that lets you.
  6. Step off the escalator altogether And become a manager and spend your time explaining to angry clients exactly why the project is over budget, over schedule, over sized, under performing and over tired.



It’s hard. Running to stand still always is. But it you don’t keep running sadly you won’t keep up. Unfortunately IT isn’t a slow sort of country – it’s a very fast one.

A note: how effective are the above and other things at coping with a fast country? I really think that some a better than others, some are better for some people and some are better a certain career points. And some are probably no good at all. Further musings to follow.

A Splodge

A kiss is just a kiss and a sigh is just a sigh. A sploge is just a sploge and this blog is just a blog. Random tech musings for the masses. Serve with double cream but don't be afraid to eat with your fingers. This blog as a wipe clean surface.