• Book review: Why

    As part of their support for user groups, O’Reilly sent me a free copy of “Why: A Guide to Finding and Using Causes ” by Samantha Kleinberg to review.

    Kleinberg is an Assistant Professor of Computer Science, so I was interested to see what she had to say about finding “causes”. It probably wouldn’t be the first book I chose if I was browsing, but I’m always interested in learning new things.

    What I liked about this book was the use of written examples and illustrations. The first chapter opens with the story of Sally Clark. A tragic miscarriage of justice that resulted in Clark serving 3 years in prison for the murder of her babies. One of the significant pieces of evidence that was used to convict Clark was the suggestion that the probability of two babies dying of SIDS was 1 in 73 million. This is wrong, because the witness (a medical expert) didn’t understand statistics and probability. The expert witness believed Clark was the cause of death the two babies.

    The Clark story isn’t the only one told. I’m glad for the generous sprinkling of those examples – without which it would be pretty dry going. It is very helpful to bring things back to something you can relate to.

    A warning, this is a pretty in-depth book. I can’t say I found it an easy read, but there’s plenty of detail there.

    Before reading this book I guess I assumed that finding the cause for something was a pretty straight forward. Turns out the correct method is “it depends”.

    Trying to identify the real cause of an event is not always easy. Kleinberg takes us on a journey to better understand ways (and there are more than one) of finding causes – Beginnings (concepts), Psychology (how do we learn about causes), Correlation (correlation and causation aren’t the same thing), Time, Observation (watching to learn), Computation (automating the process), Experimentation (experiments and research), Explanation (this caused that), Action (making decisions).

    The writer comes from the Computer Science field but she writes in a generally accessible (if a little bit academic) way. There are plenty of references (the notes and bibliography take up a not insignificant amount of the book). I noticed a lot of examples were medically-related, so if you work in the medical field, then I think you would get a lot out of it too.

    Finally, a suggestion for the title of the sequel – “Just Because” Smile

  • Backwards compatible ignoring Roslyn Analyzer warnings

    The “Roslyn” Analyzers are a great new feature that shipped in Visual Studio 2015. One nice thing about them, is you can still add them to a project even if the target platform for a project is not .NET 4.6. This makes sense, as the analyzers just run as part of the compiler – they don’t affect the generated code in any way.

    This also means you can safely add analyzers to a project and get all the warnings/errors when using Visual Studio 2015, but you can still open the same project in an older version of Visual Studio and the analyzers are just ignored.

    Sometimes you want to suppress a specific warning. It turns out there’s two ways to do this:

    SuppressMessageAttribute

    The first is the same that you would have done to suppress an old FxCop/Code Analysis violation – using the System.Diagnostics.CodeAnalysis.SuppressMessageAttribute attribute.

    [SuppressMessageAttribute(“Microsoft.Performance”, “CA1811:AvoidUncalledPrivateCode”)]

    It turns out, the only bit that Roslyn really cares about is the second parameter. As long as it starts with a valid CheckId, then that violation will be suppressed. My observation is that the first parameter (category) doesn’t seem to matter too much.

    [SuppressMessageAttribute(“StyleCop”, “SA1514”)]

    Pragmas

    The new compiler is much more flexible in disabling warnings and errors. You can now use a compiler pragma to disable a particular warning or error code – and the code isn’t just for the C# language, it can be for an analyzer too. eg.

    #pragma warning disable SA1514
    

    One advantage to using pragmas is that you can re-enable them if you want to limit the scope of the pragma to just a particular block of code in a single file.

    Backwards-compatible pragmas

    The only problem with the pragma approach above is if you try and compile the source code with the older non-Roslyn C# compilers. They haven’t ever heard of this ‘SA1514’ that you’re referring to and will generate a compiler error. The workaround is to wrap the pragmas with a conditional block, like this:

    #if VS2015
    
    #pragma warning disable SA1514
    
    #endif
    

    The final part is to define ‘VS2015’. Do this by editing the .csproj file and adding the following block (insert it after the last configuration/platform-specific PropertyGroup)

    <PropertyGroup>
      <DefineConstants Condition="$(VisualStudioVersion) &gt;= 14 ">$(DefineConstants);VS2015</DefineConstants>
    </PropertyGroup>
    

    This has the effect of defining a conditional constant only when we’re compiling with Visual Studio 14 (aka 2015) or above. For earlier versions, the constant is undefined and so the pragma is not visible to the compiler.

  • Time for a new laptop?

    I thought it might be my imagination, but running powercfg.exe /batteryreport shows the truth – my laptop battery isn’t what it used to be.

    Battery capacity history | PERIOD | FULL CHARGE CAPACITY | DESIGN CAPACITY | | — | — | — | | 2015-11-17 - 2015-11-23 | 5,656 mWh | 6,600 mWh | | 2015-11-23 - 2015-11-30 | 5,480 mWh | 6,600 mWh | | 2015-11-30 - 2015-12-07 | 5,177 mWh | 6,600 mWh | | 2015-12-07 - 2015-12-14 | 5,177 mWh | 6,600 mWh | | 2015-12-14 - 2015-12-21 | 5,177 mWh | 6,600 mWh | | 2015-12-21 - 2015-12-28 | 5,177 mWh | 6,600 mWh | | 2015-12-28 - 2016-01-04 | 5,129 mWh | 6,600 mWh | | 2016-01-04 - 2016-01-11 | 4,059 mWh | 6,600 mWh | | 2016-01-12 | 3,276 mWh | 6,600 mWh | | 2016-01-13 | 3,276 mWh | 6,600 mWh | | 2016-01-14 | 3,276 mWh | 6,600 mWh | | 2016-01-15 | 3,276 mWh | 6,600 mWh | | 2016-01-16 | 3,276 mWh | 6,600 mWh | | 2016-01-17 | 3,276 mWh | 6,600 mWh | | 2016-01-18 | 3,276 mWh | 6,600 mWh | | 2016-01-19 | 3,276 mWh | 6,600 mWh | | 2016-01-20 | 3,276 mWh | 6,600 mWh | | 2016-01-21 | 3,276 mWh | 6,600 mWh | | 2016-01-22 | 3,276 mWh | 6,600 mWh |

    This is not the original battery that came with my Dell XPS 1645. I originally had two 90mWh batteries, but both of those wore out. The current replacement was the only one I could find online (from a 3rd party – unfortunately Dell weren’t selling theirs anymore). I bought the 1645 back in 2010, so it will turn 6 in April – that’s not a bad effort for a laptop that has been lugged around a fair bit.

    And so my mind now turns to thinking about getting a replacement laptop…

    My initial specs are:

    • Gen 6 i7 or Xeon CPU
    • Minimum 16GB RAM (Prefer 16 would not be the maximum)
    • Minimum 512GB SSD (Ideally PCIe interface)
    • Decent screen resolution
    • Lighter than my 1645 (3.06KG/6.6lb according to the kitchen scales)
    • A bit smaller than the 1645 (380x260mm)

    Possible options:

    Let me know if you have any other suggestions or recommendations?