Saturday, 22 June 2013

News is bad for you – and giving up reading it will make you happier

A few months back I read this article about how News is bad for you and I thought I would give the advise a try to see what would happen. I would give up the News, sort of. Would it result in any kind of improvement in my day to day? Would it make me more .. or less ..?

The first thing to point out is that I haven't completely cut myself out of the news cycle, my radio alarm is still set at 07:00 every morning, with the (electronic) dial set to Radio 4, so I do get some news, not many as I'm normally out of the door by the time the sports section start, so this is normally about 25 minutes or fewer.

Furthermore, I don't actually go out of my way to avoid the news, but since I don't own a television, this means that at most, I'm only going to catch the odd glimpse of the news from a TV left on somewhere or a newspaper laying about. In essence, what I have done is stopped browsing news websites, mostly the BBC and various other newspapers here and abroad. 

So, Gave I had an epiphany? Has my (mild) depression lifted? my productivity increased 2 fold? 3 fold? 10 fold? Has anything changed at all?

Perhaps, unsurprisingly, there is very little that has changed in my life. I think this is probably down to two main facts:

  1. Rolf Dobelli is mostly right in his assertion that we don't really need the news.
  2. I avoid local news like the plague.
I admit that I have not completely cut myself off from the News, so perhaps we do need the News, but he is correct that there is hardly a news item that, has affected my life in any meaningful way, and I have benefited from knowing it as early as possible or most of them at all.

It is worthwhile mentioning black swans events and opportunity cost here. The former, as it would seem that only such events would be worthwhile knowing about as soon as possible and opportunity cost because all the time, mainly, spent consuming the news in the vain hope of being ready for the black swan event, which might never come and even if it does, will it compensate for all the other things that could have been done with that time (money)?

On the aftermath of the Boston bombing, somebody wrote a blog post/article on the best way of having the most accurate information about the bombing or any such event. Their suggestion was to turn yourself off from the electronic world, go out with your mates to the park or something and then read all about it on the morning paper. 

Mr Dobelli would probably argue that even reading about on the morning paper would be a waste of time, which is probably true.

I think number 2 is the key to why I feel very little change in my life without a constant stream of news.

There really is no easy way of saying this, but Local news are simply evil. They tend to concentrate, overwhelmingly, on crime and because by their very own definition, they are local, it does not even allow us to dismiss them as something that would/could not happen here, as it has happened. Furthermore, since we are notoriously bad at probability, reading them is very likely to make us anxious even though nothing, or very little, has changed about the probability of being the victim of a crime. Yet, reading about it is likely to have made us more likely to believe that crime is worse than what it actually is and even, and I'm going on a limb here, before we read the story about the horrific crime.

The murder rate in the UK is 1.2 per 100000 inhabitants or 12 per million inhabitants. The local news in my area cover approximately 1000000 people (some local media cover smaller areas, of course), which means that on average there will be 12 murders a year, or put another way: 1 per month. Not enough to be a constant worry, but enough to be a constant reminder. Never mind the fact that most of the crime is essentially criminals killing each other. Yes, there are cases were there are random acts on innocent people, but just because you can easily recall an example does not mean it's common, in fact, it's quite the opposite. Media coverage tends to be inversely proportional to frequency of an event. This is one of the reasons why the attacks on the London bombings on July 7th 2005, got the coverage they got. 

The one positive effect, that this voluntary withdrawal from news sites has had in my life, is related to my somewhat complicated relationship with sports, which I'm not going to go into detail here, but suffice to say that not knowing anything sport news has left me without those little moments of joy when the results went my way or those loooong periods of annoyance, frustration, irritation and helplessness when they didn't (I am of course exaggerating a little here for effect).

If you consume local news, I do recommend that you stop, for everybody else you can probably carry on as you were, but know that being au fait with the latest is unlikely to be of much use for anything unless your job depends on it, in which case what the hell are you doing reading this blog?

Monday, 17 June 2013

Interesting behaviour of MS Dynamics CRM 2011 when updating fields.

I found out something interesting, although, really annoying is more accurate today about updating fields in MS Dynamics CRM 2011 today.

Updating an entity field via custom code (either plugin, custom workflow activity or a simple app) or through a workflow activity, Update Record, will always trigger an Update event, even if the field is not actually being changed, i.e. it's being updated with the same value.

This might sound obvious, but it wasn't to me and some of my colleagues and it has repercussions for workflows that trigger on record field changes as they will be triggered when the value is set, regardless of whether it was an actual update or not.

This is slightly disappointing as this can lead to workflows being triggered despite the fact that for all intents and purposes, the field has not actually been changed and yet the workflow will be triggering, which could lead to users raising issues because things are happening in the system that shouldn't be happening.

The obvious answer is not to do the update if the value is not changing, which is what we are doing in a few places were this is an issue, but it seems to me that the platform, i.e. MS Dynamics CRM 2011, should be handling this. Particularly given that it's possible to prevent users from seeing the audit information, if auditing is indeed on at all, which for many things, it could well not be on.

Oh Well. 

Wednesday, 12 June 2013

Developers vs Testers

Last week I had the usual argument between developers and testers. (Note, I did not actually write the code that was the source of the issue, but I am getting ahead of myself.)

Tester: Why did you close the ticket as working to spec?
Me: Occam's razor. 
Tester looks baffled at me
Me: Wikipedia
Tester looks even more baffled
Me: Look it up in Wikipedia
Tester left admitting defeat.

That's how it should've played out but alas it wasn't.

The issue raised was that the invoices related to an account did not have the correct number, for various reasons too involved to explain here, we have separate auto numbering counters for different invoice types, thus it's perfectly valid to have 30 invoices and the 31st be numbered 1 if it's the first invoice of this type, e.g. 30 for consultancy services and 1 for accountancy services.

Unfortunately, the auditing system in MS dynamics CRM 2011 is not perfect so deleting invoices, which is actually a custom entity, leaves a record that they were deleted, by whom and at what time, but crucially it does not say which invoice was deleted.

I responded to the tester, after checking the audit view, that he must've deleted the invoices and that explained the incorrect number and closed the ticket.

The tester was not happy, they thought it was a real issue that needed looking at and this is where things normally take a turn for the worse, because we, as developers, assume that the tester did something wrong. 

We don't just assume that the tester did something wrong, of course, we check our code (✔), we run a unit test (✔), we might actually prove to the tester that the functionality that the tester raised a defect about working properly (✔), so why is this insignificant little tester wasting my time rather than accepting that they did something wrong?

It's pretty simple really, they need an explanation that satisfies them

Nobody likes admitting that they are wrong and in cases like this, where the issue, at least to the tester, is intermittent, they would like the developer to prevent it from happening again.

At this points my options were:

  1. Get into a ticket passing ping pong match (which almost certainly would've escalated to ..)
  2. Escalate to PM and/or TM
  3. Reproduce the bug.
So I did, and it turned out that my explanation was only half right. Yes, they had deleted some invoices but there were genuine holes in my explanation.

Is there anything that can be learned from this episode?

  1. Don't be lazy.
  2. Don't assume that the tester made an error
  3. If you are sure that the tester made an error, then see #1 and do replicate the error that they made, who knows they might help you uncover some bugs in the system.

Friday, 7 June 2013

Getting over the 8192 SQL Server truncation limit in SSMS

Today, I was trying to find out whether any workflow was modifying an entity as my memory was somewhat hazy and since I was already logged on the database server, I thought I'd check on the database server, but alas I couldn't as the results were being truncated, which made the query useless.

I whinged a bit to a colleague who simply said:
Why don't you cast the xaml to xml?
My response was, I didn't know that casting the xaml to xml would help, but it does.

select top 1 name, cast (xaml as xml) from workflow
where xaml like '%Process%'

This is the result:


Clicking on the xaml will open a the workflow definition on different window as an xml document.

Sunday, 2 June 2013

More quotes and a joke

In software, we rarely have meaningful requirements. Even if we do, the only measure of success that matters is whether our solution solves the customer’s shifting idea of what their problem is.
Jeff Atwood
Reader, suppose you were an idiot. And suppose you didn’t use version control. But I repeat myself.” 
Mark Twain
A man can never really know whether he isn't sitting in a madhouse. 
Georg Christoph Lichtenberg
A Foolish Consistency is the Hobgoblin of Little Minds 
Ralph Waldo Emerson
The joke

A mathematician and an engineer are sitting in on a string theory lecture. The engineer is struggling, while the mathematician is swimming along with no problem. Finally the engineer asks, "How do you do it? How do you visualize these 11-dimensional spaces?" The mathematician says, "It's easy: first I visualize an n-dimensional space, then I set n equal to 11."

Monday, 27 May 2013

Set Activities filter on contact's entity form to All on MS Dynamics CRM 2011

The default filter for the activities lookup view on the contact form is Next 30 days, which is something that I was asked to change, so this is what I did.

The SetView function was registered on the onload event of the contact form and a parameter of 'All' was passed to set the view

function SetView(Value)
{
   SetDefaultView = function (viewCombo, viewName, appGrid)
   {
      if (viewCombo.value != viewName)
      {
         viewCombo.value = viewName;
      }
   }
/*I don't think this is actually needed, too lazy to check */
   areaActivitiesFrame_OnReadyStateChange = function ()
   {
      if (this.readyState == "complete")
      {
         var frame = getiFrame("areaActivitiesFrame");
         var viewCombo = frame.contentWindow.document.getElementById("crmGrid_Contact_ActivityPointers_datefilter");
         var appGrid = frame.contentWindow.document.getElementById("AppGridFilterContainer");
         if (viewCombo.readyState == "complete")
         {
            SetDefaultView(viewCombo, defaultValue, appGrid);
         }
         else
         {
            viewCombo.onreadystatechange = function ()
            {
               if (this.readyState == "complete")
               {
                  SetDefaultView(this, defaultValue, appGrid);
               }
            }
         }
      }
   }

   if (document.getElementById(navActivities) != null)
   {
      document.getElementById(navActivities).onclick = function ()
      {
         loadArea(this,"areaActivities");
         var iframe =  getiFrame(areaActivitiesFrame);

         iframe.onreadystatechange = function ()
         {
            if (this.readyState == "complete")
            {
               var frame = getiFrame("areaActivitiesFrame");
               var viewCombo = frame.contentWindow.document.getElementById("crmGrid_Contact_ActivityPointers_datefilter");               
               var appGrid = frame.contentWindow.document.getElementById("AppGridFilterContainer");
               if (viewCombo.readyState == "complete")
               {
                  SetDefaultView(viewCombo, defaultValue, appGrid);
               }
               else
               {
                viewCombo.onreadystatechange = function ()
                {
                   if (this.readyState == "complete")
                   {
                      SetDefaultView(this, defaultValue, appGrid);
                   }
                }
               }

            }
         }
      }
   }
}

function getiFrame(iframeName)
{
 var frames=document.getElementsByTagName('iframe');

  for(var i =0 ; i < frames.length;i++)
  {
    if (frames[i].name == iframeName)
     {
      var theFrame = frames[i];
     }
  }
 return theFrame;
}

Wednesday, 22 May 2013

Comparing Calibre vs Instapaper mobi (Kindle books) conversion capabilities

I've been using Instapaper for a while now and the only thing that has kept me from subscribing is the poor quality of the conversions to mobi, which is the main usage I've given the site.

Generally speaking pictures are a no show on any converted to mobi website by Instapaper, there are formatting issues too, but until very recently this had not been a major problem, as it was pretty much the only game in town, but then I learnt about Calibre's news feature and after giving it a try, I've not really used Instapaper anymore. Admittedly I have had to write an application to use the news feature in Calibre in a similar way to Instapaper, but there you go.

Here's a side by side comparison of conversions from Calibre (left) and Instapaper(right):



As mentioned above, the first image of the article is missing, this is not a major issue, however all the code samples are images and thus do not appear on Instapaper's conversion, which makes the conversion next to useless in this particular example.


There is hardly any difference here between the two, I still like the Calibre conversion better as it's removed some of the useless links at the top.


Again, Calibre's conversion is a lot neater, the first page hardly contains any content in Instapaper's conversion. Plus the "twitter" text is not separated from the main article, given the impression that it's part of the article.


The code in Calibre's conversion is a lot neater to read than it is in Instapaper's. This time Instapaper packs more content in, but since it's code we are talking about, this is probably a bad idea, as it impacts negatively in the readability of it.

Instapaper beats Calibre in convenience, all one needs to do is have a bookmark on one's browser's toolbar and clicking on it will send the page to be stored in Instapaper's servers ready for conversion at a later time.

I realize that it's taken me a while to write this post and Instapaper might have got better in the meantime. 

Friday, 17 May 2013

MS Dynamics CRM 2011 Workflows not sending emails - Set Allow other Microsoft Dynamics CRM users to send E-mail on your behalf privilege programmatically

Today I had an issue where a workflow would fail to complete, oddly it was failing on a Send Email Activity, with the following error message:
You cannot send e-mail as the selected user. The selected user has not allowed this or you do not have sufficient privileges to do so.Contact your system administrator for assistance.
The issue is caused by users not having send as privileges set. Note that this will only occur if the sender is different from the owner of the email, which will be the case if you have workflows owned by the service account sending emails on user's behalf, a common enough business scenario.

Here's the method I used to allow this:

private void SetSendAsSetting(IOrganizationService service, Entity user, bool state)
{
    try
    {               
        UpdateUserSettingsSystemUserRequest updateRequest = new UpdateUserSettingsSystemUserRequest();
        UpdateUserSettingsSystemUserResponse updateResponse = new UpdateUserSettingsSystemUserResponse();
        
        Entity userSettings = new Entity("usersettings");        
        
        //Ensure that help language is set
        userSettings.Attributes["helplanguageid"] = 1033;
        userSettings.Attributes["issendasallowed"] = state;
        
        updateRequest.Settings = userSettings;
        updateRequest.UserId = userId;
        
        updateResponse = (UpdateUserSettingsSystemUserResponse)service.Execute(updateRequest);
    }
    catch (Exception ex)
    {
        Logger.Write(ex);
    }
}

Sunday, 12 May 2013

Set IIS website https binding programmatically (add certificate too)

I found myself needing to set a website's https binding for a few servers, this week and I wondered whether this could be done programmatically.

Although in this case the method, see below, is used to set https as a binding it can be easily modified to add any binding type to any website. I kind of did it as halfway house, I might modify it later to make it a little bit more robust and generic.

private static void SetBinding(string siteName, string bindingInfo, string fileName,string password)
{
    using (ServerManager serverManager = new ServerManager())
    {
        Site site = serverManager.Sites.Where(x => x.Name == siteName).SingleOrDefault();

        X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
        store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadWrite);

        X509Certificate2 certificate = new X509Certificate2(fileName, password);

        store.Add(certificate);

        if (site.Bindings.Any(x => x.Protocol.ToLower() != binding.ToLower()))
        {
            Binding binding = site.Bindings.Add(bindingInfo, certificate.GetCertHash(), store.Name);

            binding.Protocol = "https";
        }

        store.Close();
    }
}

Note that bindingInfo should be of this form "*:443:" if you want your website to listen on all ip addresses of your server.

The certificate needs to be of PKCS #12 vintage, i.e. with a .pfx or .p12  extension (don't just change the filename extenstion to .pfx if you have a .cer or .der certificate, it won't work.)

Don't forget to add the following namespaces (the library for the Microsoft.Web.Administration namespace is called the same as the namespace).

System.Security.Cryptography.X509Certificates;
Microsoft.Web.Administration;

Tuesday, 7 May 2013

Wiring events to a Popup control in Silverlight

Last week I was doing some work on a Silverlight application and I was struggling with an event not firing for a calendar control inside a popup control and it turns out that the reason is very simple, I was wiring the event to the popup rather than the calendar control inside the popup.

This is the method I used to create the calendar within the popup. 

private void CreateCalendar()
{
    if (calendar == null)
    {
        calendar = new Calendar();
        calendar.SetValue(Grid.ColumnProperty, 10);
        calendar.SetValue(Grid.RowProperty, 0);
        calendar.SetValue(Grid.RowSpanProperty, 7);
        calendar.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
      
        var StartDateBinding = new System.Windows.Data.Binding();
        StartDateBinding.Path = new PropertyPath("StartDate");
        StartDateBinding.Mode = System.Windows.Data.BindingMode.TwoWay;
        StartDateBinding.ValidatesOnDataErrors = true;
        calendar.SetBinding(Calendar.SelectedDateProperty, StartDateBinding);

        var displayDateBinding = new System.Windows.Data.Binding();
        displayDateBinding.Path = new PropertyPath("CalendarStartsOn");
        calendar.SetBinding(Calendar.DisplayDateStartProperty, displayDateBinding);

        popup.DataContext = viewModel;

        popup.Child = calendar;            

        calendar.MouseLeave += (o, e) =>
        {
            popup.IsOpen = false;
            LayoutRoot.Children.Remove(popup);
        };
  
 calendar.SelectedDatesChanged += (o, e) =>
        {
     CreateAppointment();
            popup.IsOpen = false;
            LayoutRoot.Children.Remove(popup);
        };

    }

}

The calendar and popup objects are global objects of the MainPage partial class (i.e. they can be found in main.xaml.cs) and the CreateCalendar method gets called on the constructor, via the AddPopUp method, see below

The popup is closed when a date is selected, in which case we create an appointment, method not shown, for the user or when the mouse leaves the calendar.

private void AddPopUp()
{    
    CreateCalendar();
    LayoutRoot.Children.Remove(popup);
    LayoutRoot.Children.Add(popup);
    
    popup.VerticalOffset = 50;
    popup.HorizontalOffset = Application.Current.Host.Content.ActualWidth - 100;
    
    popup.IsOpen = true;
}