Friday 14 December 2007

Pic

Sunday 18 November 2007

iTunes software piracy incentives

People steal software for many reasons. Of course it's generally easier to copy and share your mp3 collection than it is to walk out of HMV without paying for a bagful of CDs. Mailing application serial numbers around is certainly convenient for the morally corruptible amongst us and sharing account details for online systems is a well established practise.

So where does iTunes fit into this battle for moral righteousness? It only takes a casual browse around the iTunes store to see how many people think their pricing structure may help to promote piracy. Let's look at an example:

Lost series 1 Pay £32.99 on iTunes for video quality that is inferior to standard DVD (PAL resolution)

Pay £34.98 on Amazon for the full DVD boxed set

So for £1.99 extra you get a nicely boxed DVD set for your bookshelf that you can watch on a PC, Mac, TV or even projector with no scaling problems whatsoever. Additionally, there is lots of free software that will convert your Lost episodes to a format that can be viewed on any video capable iPod.

There is, of course, convenience to consider. With a few button clicks and a decent broadband connection you can download episodes of Lost directly to your computer and quickly switch them across to your iPod via firewire or USB2. It still seems a ridiculously high price to pay in my opinion when I can get next day delivery from Amazon for a 'real' product. This seems to be the general concensus of the general public too according to the comments that accompany many of the downloads that iTunes offer.

And there's more! Video downloads to the UK from iTunes cost considerably more than from the US. Alarmingly, in the US this same download costs $34.99 - meaning us poor souls in the UK pay almost double for an identical product. Come on Apple, be fair!

It's also bizarre that you are not able to make legitimate backups of your downloaded video to DVD. It seems that the very steps that iTunes are making to try and prevent piracy are alienating many of their potential customers.

Whilst these issues will not convert me to a life of piracy, I will certainly not be using the iTunes service unless some serious changes are made.

Friday 9 November 2007

Temperature and double standards

A friend sent me a link to a funny but alarming article in The Register today regarding a young woman's invalid scratchcard claim. Basically each scratchcard has a temperature printed on it; the idea is to scratch away a small window to reveal a number that is hidden beneath it. If the uncovered number is less than the printed temperature then the card owner wins a prize. The temperature on the woman's card was -8 degrees and the number she uncovered was -6; she was not happy when Camelot refused to acknowledge her claim. She was reported to say "I phoned Camelot and they fobbed me off with some story that -6 is higher, not lower, than -8, but I'm not having it."

Being an Englishman, hot Summer days are a rare experience and we tend to report the temperature in farenheit, for example "It must be 90 degrees today, quick get me another beer!" Yet on a cold, frosty morning as we're scraping the ice off the car windows we're equally likely to exclaim how it must be at least -5 which of course is measured in centigrade.

Perhaps 32 degrees centigrade doesn't seem quite as hot as 90 degrees farenheit and maybe 23 farenheit feels a lot warmer than -5 centigrade? I guess turning up the central heating always feels more justified when it's zero outside rather than 32 degrees.

:-)

Thursday 18 October 2007

Trial software on trial

I'm sure that just like me you often need a bit of software to help you out with a particular task. Last week I wanted something that would help me find album cover art for my MP3 collection; it just makes flipping through music with iTunes a better experience.

A few minutes with Google and I found a likely candidate; after navigating to the parent site I was asked to register my details before downloading the utility. This annoys me! After all, I took the time to find the utility in the first place and registered an interest by wanting to download a trial version. If the software did what I wanted then I would have been more than happy to pay the license fee. If it didn't then no amount of email marketing would have changed my mind. The decision is made in the first few minutes and having to spend a couple of those minutes registering my details (or Mickey Mouse's if I'm feeling particularly mischievous) does not get the vendor off to a good start.

It's a little like walking into a Virgin Megastore and not being able to look around without first filling in an application form - great marketing...for HMV!

So site registration is not my favourite exercise but it registers a poor second to functionally restricted software. Why on Earth would anyone want to provide trial software that is not 100% complete in every way? First impressions count and if my first view of an application leaves me thinking that it could do more then it is highly unlikely that I'll pay good money for it. Knowing that additional features exist in the full version does not sway the argument.

It's a little like taking a new car out for the day on a test drive only to find that the performance has been limited or the air conditioning disabled. It doesn't create a good impression.

So please software vendors, wherever you are. Don't make us register with your site, don't restrict your trial downloads (except by time) and trust your development and design skills to win us over. I, for one, would be a happier shopper and a happy shopper spends more than a disgruntled one.

:-)

Wednesday 17 October 2007

Part 4: Implicit types

With C#2, a variable's type must be explicitly declared, some simple examples are:

int clientAge;
string clientName = "Matthew";
DateTime currentDate = DateTime.Now;

Notice that we do not have to specify a value for the variable at the point at which it is declared, in the example, clientAge will be assigned a value of zero by the compiler. In C#3, variables may be declared with the var keyword in which case the compiler infers the variable type from the value it has been assigned...but it does this at compile time!

So var is not a variant (it's just a keyword that's not named particularly well) and it's not an object type either.

The following constraints apply to the use of the var keyword:

  • var can only be used within a method and not at the class level
  • Any variable created with var must have a value assigned as part of the declaration

Please see the following code for examples:

class VarSamples
{
    //This will not compile, the following error will be reported:
    //The contextual keyword 'var' may only
    //appear within a local variable declaration
    var invalidDeclaration;

    public void ImplicitTypes()
    {
        //The compiler will create postCode as a string variable
        var postCode = "B12 5HP";

        //The compiler will create postCode as an integer variable
        var houseNumber = 8;

        //This will not compile, the following error will be reported
        //Implicitly-typed local variables must be initialized
        var streetName;

        //Perform operations with var variables.
        int nextHouseNumber = houseNumber++;
        string formattedCode = "Postcode: " + postCode;
    }
}

The invalidDeclaration variable will not compile because it has been declared at the class level. This is not allowed for variables declared as var.

The streetName variable will not compile because any variable declared with var must be initialised when it is declared. Otherwise, the compiler is not able to determine an actual type for the variable when it is compiled.

So why do we need var at all?

The var keyword was introduced to support anonymous types that are also a feature of C#3. Anonymous types are described in the next article.

Part 3: Initialising objects

Consider the following simple class definition:

//Simple client class used to demonstate
//C#3 object initialisation
class Client
{
    //Read-write property for the client's name
    public string Name { get; set; }

    //Read-write property for the client's age
    public int Age { get; set; }

    //Read-write property for the client's height
    public double Height { get; set; }

    //Read only property that is True for existing
    //clients and False for new clients
    public bool IsCurrent { get; private set; }
}

A constructor has not been explicitly created for this class so the compiler will generate a default, parameterless one for us. This means that an object can be created and properties assigned inthe way that we are currently used to with C#2

//Create a client object using the default constructor
Client firstClient = new Client();

//Assign values to the class properties that have public set methods
firstClient.Name = "David";
firstClient.Age = 32;
firstClient.Height = 124;

However, with C#3, we are now able to create an object using any of the following methods:

//Construct the object by supplying the client Name
Client secondClient =
    new Client { Name = "Matthew" };

//Construct the object by supplying
//the client Name & Age
Client thirdClient = 
    new Client { Name = "Sarah", Age = 21 };

//Construct the object by supplying
//the client Name & Height
Client fourthClient =
    new Client { Name = "Daniel", Height = 131 };

//Construct the object by supplying
//the client Height only
Client fifthClient = new Client { Height = 108 };

This is essentially identical to creating a client object with the default constructor and then calling each property set method as appropriate. Looking at the disassembled code shows us what isactually happening for these client objects.

Client <>g__initLocal0 = new Client();
<>g__initLocal0.Name = "Matthew";
Client secondClient = <>g__initLocal0;

Client <>g__initLocal1 = new Client();
<>g__initLocal1.Name = "Sarah";
<>g__initLocal1.Age = 0x15;
Client thirdClient =<>g__initLocal1;

Client <>g__initLocal2 = new Client();
<>g__initLocal2.Name = "Daniel";
<>g__initLocal2.Height = 131.0;
Client fourthClient = <>g__initLocal2;

Client <>g__initLocal3 = new Client();
<>g__initLocal3.Height = 108.0;
Client fifthClient = <>g__initLocal3;

As the code above shows, each client is constructed using the default constructor and then the property set methods are called as necessary. Of course, we cannot specify a value for IsCurrent when creating a client object because the set property is marked private (as shown in the first code snippet). Trying to do so will generate a compile time error of something like: The property orindexer ‘Blog.Client.IsCurrent’ cannot be used in this context because the set accessor is inaccessible.

Part 4: Implicit types

Part 2: Automatically implemented properties

C#2 provides the ability to create properties that encapsulate class member variables; the following code provides a simple example:

//Private member variable to store the client name
private string name;

//Read-write property for the client?s name
public string Name
{
    get
    {
        return name;
    }
    set
    {
        name = value;
    }

The idea here is that the property prevents the class variable from being accessed directly. A property can be made read only as follows; this is simply a property that does not have a set statement.

// Read only property that returns the client?s name
public string Name
{
    get
    {
        return name;
    }

C#3 provides a shortcut syntax for creating class variables and associated properties; the first code example can be shortened to:

// Shortcut syntax for creating properties
//and underlying member variables
public string Name { get; set; } 

And of course, the principle of read only (or write only for that matter) properties is also supported using this new syntax:

// Shortcut syntax for creating properties and underlying
//member variables (this time ClientName is read-only)
public string Name { get; private set; }

For this shortened syntax, the compiler actually generates all of the required code behind the scenes. So in effect, you end up with exactly the same code that you would have got if you had written it using the available syntax of C#2. The code below shows the MSIL that is generated from the source code; note the use of the [CompilerGenerated] attribute that decorates the code.

[CompilerGenerated]
private string k__BackingField;

public string Name
{
     [CompilerGenerated]
     get
     {
         return this.k__BackingField;
     }
    [CompilerGenerated]
    set
    {
        this.k__BackingField = value;
    }
}

Automatically implemented properties provide a way to quickly expose class member variables; we will examine this feature more in the next article.

Part 3: Initialising objects