Saturday 5 December 2009

Apps Hungarian vs Systems Hungarian

Hungarian Notation is a convention where a prefix is given to a name to indicate its type. There are two flavours of Hungarian, and most of the criticisms are directed at Systems Hungarian, while people don't realise that Apps Hungarian even exists.

Systems Hungarian prefixes variable names with their type. One big argument against doing this is that if the type changes, then you have to change every occurence of that name to match the new type.

Apps Hungarian prefixes variable names with semantic information about the variable.

Without the prefix, "Filename" might be a string, a text box, or something else. "Car" could be an instance of the car class, or a pointer to a car, or an index into a list of cars. "First" and "Second" could be almost meaningless, but in a spreadsheet application (for example) they could refer to rows, columns, cells, or something else.

With a semantic prefix, things become clearer. In a forms application txtFilename is now likely to be the name of a textbox which contains a file name, while strFilename is more likely to be the string itself. Note that strFilename doesn't constrain me to any particular type of string - just that it is a string of some description.

"iCar" is a sensible index into an array of cars, "pCar" is a pointer to a car, and "car" is most likely to be a concrete instance of the car class.

My favourite example comparing Apps Hungarian to Systems Hungarian is based on spreadsheet software.

Using Systems Hungarian (prefixing the type to the name), if "first" and "second" are integer indices, the assignment "iFirst = iSecond" looks alright at first glance. However, if the two variables were refering to rows and columns respectively, then the assignment was used to assign incompatible values.

If we'd used Apps Hungarian instead, the assignment now becomes "rowFirst = colSecond" and without knowing anything about the type of the data, if we saw that assignment, alarm bells would be ringing.

A colleague told me that a 'p' prefix before a pointer name was unneccessary - His arguments were:
  1. we have strongly typed compilers which can tell us when we've tried using the variable incorrectly
  2. intellisense can tell us a type just by hovering the mouse
  3. if a name was followed by a dot '.' then it was a concrete instance
  4. if it was followed by an arrow '->' then it was a pointer.
My counter-arguments are:
  1. Wherever possible, I want to type code correctly in the first place - not have to wait for the compiler to tell me it's incorrect.
  2. Intellisense requires me to shift control-context to the mouse - which can be very disruptive during an intense coding-at-the-keyboard session
  3. Intellisense doesn't always get it right
  4. The code that has already been written isn't guaranteed to have used dots and arrows yet - explained below:
If you had a variable m_CurrentVehicle - and a member function, EnoughFuel(); which is correct? m_CurrentVehicle.EnoughFuel() or m_CurrentVehicle->EnoughFuel() ?
If the variable was named m_pCurrentVehicle, then you would be able to see the answer instantly.

I used to hate seeing things in Systems Hungarian like lpszMessage (long pointer to a string which is zero terminated), but I like Apps Hungarian.

Monday 30 November 2009

10 Reasons why I like Scrum for Games

This is a response to Steve Tovey's 10 Reasons why Scrum sucks for Games. Steve and I used to work at the same company (but on different projects), and it sounds like he and Scrum didn't get along very well. I think Steve's a very clever chap, but I had a somewhat different experience of Scrum.

Scrum is a project management framework. A project is broken down into a strictly prioritized set of components (the backlog) and every few weeks (called a "sprint") the highest priority items are taken off the backlog, divided among the Scrum teams, developed, and signed-off. Additional features include Planning Poker, Sprint Planning Meetings, Sprint Retrospectives, and a Scrum Master whose job it is to make sure things run smoothly.

My team (the tools team) was one of the last teams in the company to adopt Scrum, and when the Powers That Be were trying to push Scrum to us, we resisted at first (why would I want to Scrum? sounds like a load of rubbish!) It was the early days of a new project, and we had all the time in the world, so there was no pressure on the tools team, no deadlines, and it felt like we could do whatever we wanted. The trouble is, without targets, there was no feeling of achievement - things just rolled along at a less than optimal pace. When we started Scrum, we suddenly had deadlines and targets, and over time we could see where our work fit into the bigger picture. Which leads me to my first reason:

1. Scrum improves visibility. You can see exactly what is important and what isn't - what you should be spending time on, and what is acceptable to slip.

During the sprint planning meetings, you divide tasks into manageable chunks. In Scrum, "Manageable" is no more than a day, and preferably less. If a task is estimated at taking a week, it needs breaking down some more and thinking about more. As Steve rightly points out, estimating is hard. The first few planning meetings are going to have estimates that may be quite a bit off the mark. But estimating is a skill that can be improved with practice. This is reason number 2:

2. Scrum improves developer's estimation skills. And when management sees that the developers are able to give accurate estimates, they get more realistic expectations of what can be achieved by the end of the project.

When development time is underestimated, tasks end up dropping off your current sprint and returning to the backlog, but the important thing here is that they are still at the same relative priority to all the other tasks. They will be dealt with next sprint. Eventually, when you run out of sprints, you will inevitably have to drop features because you ran out of time. But thanks to the strict ordering of the backlog, the features you ultimately ship without are of the lowest priority, meaning

3. Scrum makes sure you work on the most important things.

That isn't to say there's no time for polish. Between sprints is a period of time for integration (combining all of the Scrum teams' work). While this is going on, and developers get a bit of a breather, they can use this time to add the bits of polish that didn't fit into the main product backlog. Also, if the product owner wants to put more time on polish, he can simply bump up the priority of polish - with the understanding that anything of a lower priority will move down the list, possibly causing another of the lowest priority tasks to be unachievable.

4. Each sprint generates "deliverables".

In a project meant to run over a couple of years, you might expect to see somewhere in the region of 10 - 20 sprints. At the end of the early sprints, you might not have anything that could be boxed and sold, but towards the end of the project, it is possbile that you could finish the project early because you made sure that there was a deliverable at the end of each sprint. Alternatively, you could ship on the expected end date, and then run extra sprints for a patch or version 2.

I will agree with Steve on his point 5 "Why do I get a say?" I was lucky in that my Scrum team consisted entirely of programmers. I can imagine it being very frustrating having an artist telling you how simple (or difficult) a programming task is, or generally just pulling numbers out of thin-air during planning, and similarly having a programmer tell an artist how much time it takes to be creative. So I'll give my reason 5 as

5. (assuming your Scrum team is composed of developers from the same discipline) Everyone relevant gets to have a say.

Steve says taking an entire sprint to react to change isn't very Agile. After a quick glance at both the Agile and Scrum entries on Wikipedia (thus making me an expert in the fields) I'd says that the Agile timeboxes (of one to four weeks) correspond rather neatly with sprints, and I'd say that adopting changes between the timeboxes fits in rather comfortably with the Agile ethos. If reacting to changes every 4 weeks isn't rapid enough (say I want to react in a day), then by all means make an emergency change to the sprint - it's not going to bring the whole system crashing down! So

6. Scrum is Agile, in my expert (ha!) opinion.

I partially agree with Steve on his point 7 "less done". You do get less coding done if you spend more time in meetings - it is a simple calculation. But to be fair, (anecdotal evidence alert) I don't feel that you loose that much, especially if you value what you gain - a better ability to estimate tasks, and a greater focus on what the customer (project manager) wants. So

7. While less overall code gets done, more important code gets done. There's no risk of not having enough time to finish the critical features just because you decided that it would be nice to work on a small pet project / task / feature.

In the daily Scrum meeting, the team move Task post-it notes from the "pending", to the "in-progress" to the "complete" sections of the Scrum board. I have a feeling Steve found this a waste of time! I think they served a useful purpose.

I remember reading about computerization of air traffic control. Prior to computerization, aircraft were represented by plastic tags on a board, and when an aircraft changed position in their queue, the controller responsible for that aircraft had to move the tag. I don't remember details of what disasters happened after the computers took over, but I remember reading that the controllers felt less responsible for their charges. The reason I read was, that the tags that they moved around were things they could physically grab hold of or pass to other controllers and that physical movement or handover, psychologically, made the controllers feel more responsible for the planes they were in charge of. Without the physical tags, there was a psychological disconnect between the controller and the plane.

I think the post-its, in their small way, make the team members feel more responsible for their tasks. Usually. I do remember on a number of occasions a team member who would say things like "I've done X and I'm just waiting for Y so I can finish it" or "I can't do Z this sprint" while moving his post-it note into the complete section. Occasionally I would (in a joking-but-not-joking kind of way) try to pick him up on this, but his post-its still managed to find their way in to the complete section anyway! I think this was partly due to a slightly competitive feel that some people might get when you can see how many tasks you've completed compared with your team mates; but I also think a bit of friendly competition is healthy for the team. I'm not saying you can't be competitive without Scrum, but I'd say that Scrum makes your progress that much more visible.

Steve says "Too many coders spoil the broth". I'd use the saying when it came to Scrum team sizes in general - lots of coders in a daily meeting wastes a lot of peoples' time - but I'd say sharing higher level tasks among three or four people is a sensible idea, because I'm a fan of team ownership.

I hear a lot of people voraciously cheering the Code Ownership bandwagon, but they are supporting Strong Code Ownership - the idea that every piece of code is owned by exactly one individual. While it sounds like a good idea that one person knows everything thoroughly and is the highest authority on that code, if that coder leaves the team, or company, (or gets hit by a bus), the company is in trouble. The opposite extreme is that nobody is responsible for any code, anyone can change anything, and if anyone wants to know how something works, they pretty much have to work it out for themselves because so many people have had their fingers in the code pie.

In the middle, you have team ownership. I don't remember reading a definition of it anywhere, so I may have invented it, but probably not. Anyway, with team ownership, while individuals work on components, the team should be more or less knowledgeable of the whole subsystem that they have been made responsible for. Which means if one member is ill, or on holiday, or leaves the company, any of the other team members can quickly and easily take up the slack.

This fits in nicely with Scrum - during the sprint planning meeting (the process by which high-level post-it-notes get turned into lots of low level-post-it-notes) the low-level tasks can be shared among the team (as long as the tasks and boundaries are well defined). I like scrum because

8. Scrum facilitates shared code ownership.

Each daily sprint meeting is attended by the Scrum master. Each day, the team has the opportunity to bring to light any impediments and the Scrum master can go off and prod the relevant people until the impediment is removed. The impediments can also be brought to the Scrum master at any time, not just during the daily meetings.

9. Having a consistent Scrum Master really helps remove impediments!

After each sprint you have a sprint retrospective. The team brainstorms about the past sprint, trying to decide what went well, what went badly, how to improve things in the future. Also, each team member draws a graph of how they felt during the sprint - from very happy, to very sad. There are no numbers on the graph, the important part is sharing the reasons behind the peaks and troughs of the graph, hopefully helping to improve future sprints.

10. Scrum encourages frequent communication.

No need to wait until the end of the project for a post-mortem!

Just before I finish, I will say that you don't need Scrum in its entirety to get all of the benefits - individual elements are probably strong in their own right. But I do feel that there are a lot of good reasons to adopt Scrum as a whole.

Sorry the post was so long! Feel free to blast apart any of the arguments I just made :)

Sunday 25 October 2009

Style sheets for IDEs

As programmers, code layout is very important to us.

If code is presented in a way we are familiar with, we can skim-read entire passages of code in very little time and find our way to the significant details very quickly. With well presented code, you can often see the general flow of the code without even having to read the fine details.

Conversely, if the code we read is layed out poorly, it can be a real struggle to read through, and can take a very long time to get even a basic understanding of the code.

Unfortunately, "well presented" is a very personal, subjective description of code.

Indent with 3 spaces or 4? Tabs or spaces? Braces on the same line as other code? Alignment of variable names? Prefix? Hungarian?

There are hundreds more examples. If you surveyed every programmer you knew, I'm sure you wouldn't find any two who agreed on every point of code layout.

The trouble is, there is no right answer - there are valid reasons for all the choices.

What we need, is a way of separating out the code from its layout - syle from substance.

When we have IDEs which can present any piece of code in your style, we'll have made a great leap in the speed of code comprehension.

Wednesday 22 July 2009

What do I want from a mobile phone?

  • I want good audio quality!
  • I want long battery life - specifically I want to be able to turn the screen on and off in order to save the battery - even during a phone call!
  • I want to be able to turn the phone off and the alarm clock to still work (I don't want to leave a "live" mobile phone on my bedside table at night every night).
  • I want the phone to charge via USB - then I don't have to carry my charger around with me everywhere.
  • I want the interface to be as customizable as possible - if I don't have a data plan, 100 internet shortcuts are useless to me!
  • I want the phone to vibrate for a phone call or text message - but not when navigating menus!
  • I want tactile feedback from the buttons on the phone - I often "touch-type" with my mobile, but if some buttons don't have the same "click" as other buttons it will throw me off.

Friday 5 June 2009

Open File Security Warning Removal

Fed up with having to deal with the security warning every time you download a file from the internet? Supress the warning dialog with the instructions found in the first link on this page.

Go to Run -> gpedit.msc
User Configuration -> Administrative Templates -> Windows Components -> Attachment Manager -> Inclusion List for moderate risk file types.
Enable it and in the box specify the extensions such .exe, .jpg, .com

Thursday 4 June 2009

TreeViewScroll

The .net TreeView doesn't expose a scroll event. Make your own by overriding DefWndProc.

   public class TreeViewScroll : TreeView
{
private const int WM_VSCROLL = 0x115;
private IntPtr SB_ENDSCROLL = new IntPtr(8);

public event MethodInvoker Scroll;

protected void OnScroll()
{
if (Scroll != null)
Scroll();
}

protected override void DefWndProc(ref Message m)
{
if (m.Msg == WM_VSCROLL)
{
if (m.WParam != SB_ENDSCROLL)
OnScroll();
}

base.DefWndProc(ref m);
}
}


The code above is sufficient for my needs, but if you need more details about the scroll (direction, where you scrolled to, etc) you need to interrogate the message further.

This link should tell you what the message contains:
http://msdn.microsoft.com/en-us/library/bb787577(VS.85).aspx

This link can tell you the scrollbar values:
http://www.pinvoke.net/default.aspx/Enums/ScrollBarCommands.html

Thursday 28 May 2009

Stuck in a rut

Don't get stuck in a rut! Don't miss the wood for the trees!

The other day, I was working out some long, convoluted workaround for dealing with the fact that vector iterators can become invalid if the vector resizes.

Then someone reminded me that you can access elements of a vector by index. D'oh!

Wednesday 27 May 2009

If in doubt, wiggle

A few years ago, part of my job involved making large print runs in Microsoft Word - in the region of 500 to several thousand pages per job. While doing this I discovered an unusual quirk.

In the status bar a little animated icon appears alongside a counter that tells you how far through your print job you are. Quite frequently with the large print jobs, I noticed that the counter would freeze on quite a low number. The printer would catch up to the counter and then nothing would happen for a little while.

But if you wanted, you could "remind" Word to carry on printing, by wiggling the moue over the status icon! While the mouse was moving, the status icon's counter was counting upwards - as soon as you stopped moving, the counter stopped counting.

An obvious explanation might be that the counter only repainted when mouse moved over it; but I experimented - the printer didn't print pages unless the status counter was incrementing. Whenever the counter froze, the printer stopped, and as soon as I moved the mouse over the icon, printing resumed.

How odd.

Sunday 8 March 2009

Zipping in C#

After spending hours digging around, trying to find the .net solution to zipping folders using c#, the easiest solution seems to be to use the command line for 7zip.

String zipper = @"c:\program files\7-zip\7z.exe";
String args = "a -tzip " + compressPath + " " + compressFolder;

Process proc = Process.Start(zipper, args);
proc.WaitForExit();



where compressPath is something like "C:\foo.zip" and compressFolder is something like "C:\foo".

Update: 9th March 2009
It's probably a good idea to make sure both compressPath and compressFolder are surrounded by quotes in case they contain spaces!