Friday, April 28, 2006
I added AdSense ads to some of my websites as an experiment to see if it would be worthwhile adding them to the Random Pub Finder. I've now been signed up long enough to get a reasonable idea of how much money can be made. Based on my earnings, which may not be completely representative, you can get anywhere between $0.05 and $1.50 per click. But Google don't provide any information about which keywords provide the high-earning clicks, so it isn't possible to optimise your site based on that, which would be a pretty lame thing to do anyway. Earnings per 1000 pageviews seems to be about $5, so I'll never make a living based on it, but I might make a little bit of pocket money. So how many hits would you need to actually pack in the day job? OK, say you need to earn $6000 a month (which may be a bit high or low depending on where you live and your lifestyle) how many hits would you need? That works out at $200 a day, or 40,000 pageviews. My guess is you'd need to be running your own server to handle that kind of load (I'm sure any free host would throw you off their servers before you got to this level) so that's another expense. I've no idea how much that would cost but if you are getting that number of hits I'm guessing you also need support people to ensure your server is always alive (unless you want to provide the 24-hour support...) so add some more for that. Guy Kawasaki, who says he's in the Technorati top 100, also says he gets upto 1200 pageviews a day, so it certainly looks like it would be pretty hard to get near the 40,000 from blogging, doing IT writing at least. And more popular subjects lke the sex publishing industry seems pretty well covered already (so I hear). So in conclusion, I don't think ads are likely to finance mine or your lifestyle, but they could provide some useful extra cash. And are they worth it for the Random Pub Finder? Not until we get so large we get kicked off our free host. It's only a matter of time...
Tuesday, April 25, 2006
Apparently Windows Vista will have a whole slew of new dialog boxes for us to contend with. This is all in the name of security so perhaps there is some reason behind the apparent insanity, but us programmers have a bit of a soft spot for dialog boxes and our users don't. For a programmer, a dialog box is often the easy way out. What's the alternative? It depends on the scenario, but the typical situation where we would consider popping up a dialog is when the user is about to do something that could lead to some kind of data loss, so we throw up a dialog saying 'Are you sure?'. The alternative here is to have some kind of undo functionality and that can be pretty tricky to implement. So why don't users like dialogs? Because they interrupt workflow. The user is merrily going about their business when up pops a dialog and they have to think about the answer. After a while of course they learn to ignore the dialog and just hit the Enter key, which is another problem with dialogs that popup too frequently. They lose any effectiveness they initially had. Another problem occurs with multitasking. In one application I use, loading a document takes some time, so I open a file, then switch to some other application. When I flip back to the original application, there's a dialog asking a dumb question... So how do we get rid of them? First, remove any dialogs that serve no purpose at all. Examples of these are dialogs that merely say 'I've completed task X'. What is the user meant to do? Congratulate the computer? Next, find dialogs that 99% percent of the time serve no purpose, the 'Are you sure?' dialogs and just do what the user asked for but allow them to undo that action. Then look for dialogs that ask a question that invariably has the same answer. Add a checkbox that says 'Always do this and never ask me again'. You may decide that you want to provide a way of turning this back on, but have you ever needed to do it? I'd go even further at this point and suggest looking at any modal windows in your application and see if you can make them non-modal. Modal windows make user interaction more difficult, even though they make programmer's lives easier. If a user is likely to want to copy and paste between windows in your app, make sure they are non-modal so they have some chance of doing so. But I don't have an original bone in my body. All these ideas come from the great book 'About Face', that everybody should read.
Sunday, April 23, 2006
One of the few visitors to this site came here looking to learn how to do serialization in Delphi, so I thought I'd oblige. Fire up Delphi, create a new Windows Application project and add a button and a memo control to the form. In the event handler for the button, add some code as follows- procedure TForm1.Button1Click(Sender: TObject); var LStream : TMemoryStream; begin LStream := TMemoryStream.Create(); LStream.WriteComponent(Memo1); LStream.Position := 0; Memo1.Text := ''; LStream.ReadComponent(Memo1); LStream.Free; end; Now run it and hit the button and, er, nothing happens, which is exactly as it should be. This just shows that the memo control is getting serialized to the stream, the text in the memo is getting cleared, and then the memo is getting deserialized and the text is getting put back. And that is about all there is to it. To add a bit of excitement, add another button and another memo. Add the following code to the event handler for the new button- procedure TForm1.Button2Click(Sender: TObject); var LStream : TMemoryStream; LStringStream : TStringStream; begin LStream := TMemoryStream.Create(); LStream.WriteComponent(Memo1); LStream.Position := 0; LStringStream := TStringStream.Create(''); ObjectBinaryToText(LStream, LStringStream); Memo2.Text := LStringStream.DataString; end; By default, Delphi serializes objects in a binary format. The ObjectBinaryToText method converts it to a human-readable form and there is another method to go the other way. Recognize the text format? It's the same as Delphi uses for storing DFMs. The serialization support in Delphi was developed purely for the IDE, which is why it's only really a half-arsed implementation. The only properties that will be serialized are published ones, which will likely limit what you can do with it. Of course, there are all the problems with serialization you should consider before you start using it. There's a whole lot more to serialization than this, but I hope this has been a useful introduction.
Monday, April 17, 2006
My previous post about visible instance fields actually got a comment, which is my first ever proper comment, unless you count the ones from my brother. Not only that, it actually got commented on by a member of the FxCop team at Microsoft. Crikey! I think that lifts me up from being a Z-list blogger to what, a Y-list blogger perhaps. Anyhow, the comment was that although moving from a visible field to a property won't break source compatibility it will break binary compatibility, which is a fair point. You can see this if you look at the IL for setting a field value compared to setting a property (via our old friend Reflector). ldloc.0 ldc.i4.1 stfld int32 ConsoleApplication1.Thing::Field ldloc.0 ldc.i4.1 callvirt instance ConsoleApplication1.Thing::set_Property(int32) So in some ways it will also break source compatibility if someone is using you class library from an IL application, if there are such crazy people around. But I think this does highlight a problem with FxCop. It was originally designed to help the .NET Framework team find problems in their code. But the kind of problems they need to worry about are not the same as what most programmers need to worry about. Mostly I don't care about binary compatibility, although I can see there will be companies doing component development who do need to care about it. Yes, I can turn off warnings that aren't of interest, but there are so many warnings in there, it's pretty overwhelming to even know where to begin. Perhaps I'm asking too much, after all FxCop was designed for people writing class libraries, but the fact it now ships with Visual Studio 2005, suggests Microsoft are now thinking application developers should be using it as well. If MS do think this, then I think they need to start thinking about having some different modes of operation in there for different use cases. As an example, it would be great to throw an application (ASP.NET or WinForms) at it and it to tell me which public code never gets called. It doesn't do this now, because it doesn't know who's going to be using the assemblies, but if the assemblies aren't shared with other applications then it should be able to work it out. Now, that would be cool...
Saturday, April 15, 2006
When programmers start out they are like small children, they have no awareness of danger. So they just go ahead and hack code, with no thoughts for the consequences. It's only after a few late nights caused by introducing serious bugs due to a one line change for some minor cosmetic problem that programmers develop the fear. The fear is a good thing, it helps us programmers to spot potentially dangerous changes to code and try our best to reduce the risk of breaking things. But there are two main ways that programmers (and managers for that matter) will deal with the fear. The first approach is to try to limit the amount of code change. If they are fixing a bug in an area they are unfamiliar with, they'll try to find the smallest amount of code they can change that fixes the problem, so rather than try to understand what the code is trying to do, they'll just shove in something that fixes the problem for this specific case and move on. This approach has some merits, there is certainly a link between the number of lines of code changed and the chance of new bugs being introduced but it doesn't solve the underlying problem, that the programmer doesn't understand what the code does. If they did, the fear wouldn't be so bad and they'd likely fix it properly. In the short term, that bit of code probably just got even more difficult to maintain. In the longer term, areas of the product can become no go areas that haven't been touched for years and nobody understands anymore. But they work mostly so that's OK, until a new feature needs to be added. At which point, the developers will turn round and say "we need to rewrite it all because it's such a mess". So how else can we deal with the fear? What you need to do is get into a place where the fear holds no, er, fear. It starts off simply enough, get some source control in place. If you haven't got source control, you're pretty much screwed, unless you're working on the next 'hello world' app. It's a great thing to be able to check out some code, hack it around, then if it doesn't work out go back to what you had before. Or two weeks down the line, when you realise that the bug fix wasn't such a big success, you can rollback to something that's more sensible. Check in regularly, like twice a day, not every two months. There are lots of other things to help reduce the fear. If it's code you don't understand too well, try to work out what's going on, do a bit of refactoring, try adding some unit tests, throw FxCop at it (or in the Delphi world Pascal Analyzer), adopt some agile methods, get a QA team. The tools are out there, so lose the fear.
Thursday, April 13, 2006
FxCop rocks, in a kind of hectoring school teacher kind of way. It complains about loads of things that are only relevant if you happen to be developing a class library that will be used by 3 million developers using every conceivable .NET language and in every human language known to man. But us mere mortals are mainly developing code that might get dumped onto one web server if we're lucky. But FxCop still helps out on stupid things like code that never gets called and visible instance fields. Except, what's wrong with visible instance fields? OK, making fields public that users of your class never need to access is pretty dumb, but how does a public field differ from a property with simple getters and setters? The FxCop help says "the code in a property's accessors can change as the type's features expand without introducing breaking changes." But if I need to change a public field to a property, how will this cause a breaking change? Fields and properties are used in exactly the same way by client code. The only explanation I can think of is that it may cause serialization code to break, but serialization code breaks all the time anyway so that doesn't seem particularly relevant. Saying all that, I'm still going to continue to use properties, if only to stop FxCop complaining.
Sunday, April 09, 2006
In the late 90s, things went a little crazy. We had websites popping up here, there and everywhere that allowed us to do lots of exciting things, mostly for free. It turned out that this kind of business model wasn't generally very successful so most of these sites went bust. At the time, being an IT professional was pretty good, since the job market was red hot. Then suddenly in 2000, it all went tits up. So here we are in 2006 and the job market is moving very quickly upwards,lots of new websites are popping up doing lots of exciting things, mostly for free, many with a business model that seems to entail nothing more than ad revenue, or value added services. So is this another bubble or is this different? It seems to me the key here is the growing online ad business which is doing very well at the moment. It seems slightly crazy to me that I can get paid $1.50 just because someone clicks on a link on my site (and the advertiser is paying even more). If that stream of revenue stops or severely reduces, a lot of these new web businesses might start having problems I reckon.
Saturday, April 08, 2006
I can't remember how it all started. I think I entered some competition that offered the chance to win some free wine (how could I refuse?) and Virgin Wines got hold of my email address. Soon I was getting an email every week or so exhorting me to purchase a case of wine. I've no idea whether Virgin Wines provide decent wine or not, but the fact I've got a Majestic Wines about five minutes away means I wasn't tempted to purchase anything from them, so I sent an email to email@example.com (after all they are reputable company, right?). Then, nothing. the emails kept coming. So I sent another. And the emails still didn't stop. Then I got an email from the founder of Virgin Wines, not apologizing but offering me more wine to buy. So I replied directly to him telling him his unsubscribe functionality didn't work. I then got an email from Customer Services saying "Thank you for contacting Virgin Wines and we have arranged for the email address you have provided to be removed from our mailing list which will be actioned within the next few days.". So that was the end of it? Well, no. I then received what looked like a personal email from the founder saying "Dear Christopher I thought that, as we were warning our staff not to lose out on last weeks free case offer, we should do the same for you!Please don't hang about - when the free cases are gone, they are gone! Go to www.virginwines.com/reminder9 Cheers, Rowan Gormley Founder Virgin Wines" I presumed I was actually being offered some free wine at this point, perhaps as an apology for all the emails. But looking at the offer showed it was just another attempt to get me signed up to Virgin Wines. OK, I'd get a free case but only if I bought another case... OK, the price looks pretty reasonable, coming to just over £3 a bottle, but my corner shop does a nice red at £10 for 3 bottles. Then today I got yet another email offering me more wine at bargain prices. Frankly I don't care how good Virgin Wines are, they are spammers, so I will not be buying any wine from them, ever. And perhaps their PR department will see this and realise their mistake. Or they'll sue me...
Thursday, April 06, 2006
So I'm still trawling through this ASP.NET app and keep finding great WTFs. I spotted this method in one of the classes
So presumably the writer of this piece of code assumed nobody had ever faced a similar problem before and might have provided a solution in the framework???? Anyway, that's some more redundancy I can get rid of.
private ArrayList SplitString(string str, string separator)
Monday, April 03, 2006
I've just picked up somebody else's ASP.NET 1.1 application and like probably every developer who's picked up somebody else's code, I think it's crap. The thing that worries me most is how hard it is to create a new page. I create a new web form and then I have to copy and paste the markup form another page. Then I need to go through and add a bit of code to the code behind file. ASP.NET provides lots of mechanisms to avoid having to do this (as does pretty much every other web development platform). We have page inheritance, so common code can be put in a parent class. We have user controls, so bits of repeated HTML can be put in them. OK, a bit of setting up of a new page may well be necessary but copying and pasting, whether markup or code, is a very bad sign. When the change request comes through (as it always does) to redesign the whole site, if every single file needs to be modified, life will be very painful.