<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>Mark Withall</title>
 <link href="http://markwithall.com/atom.xml" rel="self"/>
 <link href="http://markwithall.com/"/>
 <updated>2020-10-22T07:45:31+00:00</updated>
 <id>http://markwithall.com/</id>
 <author>
   <name>Mark Withall</name>
   <email>"-->"@markwithall.com</email>
 </author>

 
 <entry>
   <title>My First Video Series</title>
   <link href="http://markwithall.com/programming/2019/10/24/my-first-video-series.html"/>
   <updated>2019-10-24T00:00:00+00:00</updated>
   <id>http://markwithall.com/programming/2019/10/24/my-first-video-series</id>
   <content type="html">&lt;p&gt;Just over a year ago, I decided to try my hand at recording a programming video. Rather surprisingly, this turned into me recording a series of 38 episodes, with each episode being around 20 to 30 minutes in length, and a total duration of 16.5 hours.&lt;/p&gt;

&lt;p&gt;The subject of the video series was &lt;a href=&quot;https://en.wikipedia.org/wiki/Little_man_computer&quot;&gt;Little Man Computer&lt;/a&gt;. The reason being that I was into assembly language programming at the time. I also took the opportunity to try out C++17. It had been a number of years since I last programming C++ in anger, so this seemed like a good opportunity to get myself back up to speed.&lt;/p&gt;

&lt;p&gt;I recorded using &lt;a href=&quot;https://obsproject.com&quot;&gt;OBS&lt;/a&gt;, as that seems to be what most people use for this purpose and it seems to have produced good quality videos. Unfortunately, due to not having mastered the process early on, the first 7 episodes have quite a low volume. Later episodes have much better sound. YouTube appear to be in the process of overhauling their editing tools, so it’s not currently straightforward to fix the volume. Hopefully, I can come back and sort it out later.&lt;/p&gt;

&lt;p&gt;If you happen to have a spare couple of days, feel free to check out my efforts &lt;a href=&quot;https://www.youtube.com/playlist?list=PL138JwO5B4Luodhg5HhxG6dLd6kcWg1a1&quot;&gt;on YouTube&lt;/a&gt;.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Setting The DataContext On A Style Element In A WPF ItemsControl</title>
   <link href="http://markwithall.com/programming/2018/08/19/setting-the-datacontext-on-a-style-element-in-a-wpf-itemscontrol.html"/>
   <updated>2018-08-19T00:00:00+00:00</updated>
   <id>http://markwithall.com/programming/2018/08/19/setting-the-datacontext-on-a-style-element-in-a-wpf-itemscontrol</id>
   <content type="html">&lt;p&gt;A short post, mostly just to remind myself how to do this when I forget.&lt;/p&gt;

&lt;p&gt;If we have the following style in, for example, a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DataGrid&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;Style&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;TargetType=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;DataGridRow&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;Setter&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Property=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Background&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Value=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Green&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;Style.Triggers&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;DataTrigger&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Binding=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{Binding IsBlue}&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Value=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;True&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;Setter&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Property=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Background&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Value=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Blue&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;/DataTrigger&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/Style.Triggers&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/Style&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We get the following error message: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Cannot resolve property &quot;IsBlue&quot; in data context of type '...'&lt;/code&gt; where &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;...&lt;/code&gt; is the type of the data context for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DataGrid&lt;/code&gt; rather than the data context for the row item.&lt;/p&gt;

&lt;p&gt;To remove the error, we need to set the data context for the style. What we’d like to be able to do is:&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;Style&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;TargetType=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;DataGridRow&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;d:DataContext=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{d:DesignInstance ViewModels:ItemPresenter}&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;Setter&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Property=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Background&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Value=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Green&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;Style.Triggers&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;DataTrigger&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Binding=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{Binding IsBlue}&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Value=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;True&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;Setter&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Property=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Background&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Value=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Blue&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;/DataTrigger&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/Style.Triggers&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/Style&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Unfortunately, this gives the error message: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;The property &quot;DataContext&quot; does not exist in the &quot;http://schemas.microsoft.com/expression/blend/2008&quot; namespace.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;What actually needs to be done is:&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;Style&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;TargetType=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;DataGridRow&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;d:Style.DataContext&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;x:Type&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ViewModels:ItemPresenter&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/d:Style.DataContext&amp;gt;&lt;/span&gt;

    &lt;span class=&quot;nt&quot;&gt;&amp;lt;Setter&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Property=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Background&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Value=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Green&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;Style.Triggers&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;DataTrigger&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Binding=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{Binding IsBlue}&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Value=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;True&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;Setter&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Property=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Background&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Value=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Blue&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;/DataTrigger&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/Style.Triggers&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/Style&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;More verbose but actually works.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Writing a 6502 Assembler</title>
   <link href="http://markwithall.com/programming/2018/03/19/writing-a-6502-assembler.html"/>
   <updated>2018-03-19T00:00:00+00:00</updated>
   <id>http://markwithall.com/programming/2018/03/19/writing-a-6502-assembler</id>
   <content type="html">&lt;p&gt;Recently, I rediscovered the joy of the Commodore 64. The C64 was one of my first computers and I spent hours programming in Basic on it. However, possibly due to the lack of the Internet at the time, I never learned to program it in machine code. I always felt rather disappointed by this. It seemed to me that so much more could be done in machine code but the resources of my local library did not support learning such things. Oddly, the thing that I most wanted to do back then was to have a loading screen on my Basic programs; that drew a picture and played music while bringing the program in from the cassette.&lt;/p&gt;

&lt;p&gt;Now, with most of the books on C64 programming being freely available on the Internet, along with many other resources, I felt it was time to finally learn 6502 assembly programming (actually, 6510 on the C64).&lt;/p&gt;

&lt;p&gt;Initially, I picked up a copy of Jim Butterfield’s “Machine Language” and began working through it using Supermon on the VICE C64 emulator. But after a while I became frustrated with the speed of development on the machine itself and decided to write the code on the PC and cross-assemble. I looked into various existing assemblers and IDEs but thought it would be more fun to try writing my own; to give me a better understanding of the instructions available.&lt;/p&gt;

&lt;p&gt;The project is still a work in progress but you can follow how it is going on &lt;a href=&quot;https://github.com/MarkWithall/Assembler6502&quot;&gt;GitHub&lt;/a&gt;. I’m killing two birds with one stone here and finally taking a look at .NET Core and developing on both Windows and MacOS at the same time. Line endings aside, the process has turned out to be quite smooth; using Visual Studio Professional 2017 on the PC and Visual Studio for Mac Community Edition. I’m regularly feeling the pain of the lack of ReSharper for the Mac though; even though the refactoring tools built in to Visual Studio are coming along nicely. I’m following a relatively ‘pragmatic’ TDD approach to development and committing the code on every green or refactoring, to allow the process to be followed easily.&lt;/p&gt;

&lt;p&gt;It is my intention to record a video of the development at some point and writing that down here might actually make it happen.&lt;/p&gt;

&lt;p&gt;Once the assembler is complete, at least in first draft, I shall write &lt;a href=&quot;https://en.wikipedia.org/wiki/Conway's_Game_of_Life&quot;&gt;Conway’s Game of Life&lt;/a&gt; for the C64 and see how it is to work with and if any adjustments are needed. Maybe the next step will be writing an IDE too with nice refactoring and static analysis features.&lt;/p&gt;

&lt;p&gt;Hopefully, more updates on progress to follow.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>DDD North 2017 Review</title>
   <link href="http://markwithall.com/programming/2017/10/15/dddnorth-review.html"/>
   <updated>2017-10-15T00:00:00+00:00</updated>
   <id>http://markwithall.com/programming/2017/10/15/dddnorth-review</id>
   <content type="html">&lt;p&gt;Yesterday I attended my third &lt;a href=&quot;https://www.dddnorth.co.uk&quot;&gt;DDD North&lt;/a&gt;. This year was at the University of Bradford, which had the added bonus of free parking. It again provided an excellent opportunity to catch up with my colleagues from the North.&lt;/p&gt;

&lt;p&gt;Looking back to &lt;a href=&quot;/programming/2016/10/02/dddnorth-review.html&quot;&gt;last year’s review&lt;/a&gt;, I appear to have chosen very similar talk topics to attend.&lt;/p&gt;

&lt;h2 id=&quot;thinking-functionally-in-c&quot;&gt;Thinking Functionally in C#.&lt;/h2&gt;

&lt;p&gt;This talk was by &lt;a href=&quot;https://twitter.com/johnstovin&quot;&gt;John Stovin&lt;/a&gt;. It was a much more in depth talk than I was expecting and inspired many interesting thoughts. For example, the suggestion that a properly pure function shouldn’t even throw an exception. Instead of:&lt;/p&gt;

&lt;div class=&quot;language-c# highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;DoSomethingWithMinutes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mins&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mins&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;59&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mins&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ArgumentException&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We should restructure such that the function doesn’t need to throw:&lt;/p&gt;

&lt;div class=&quot;language-c# highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;DoSomethingWithMinutes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MinuteComponent&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mins&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MinuteComponent&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_mins&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MinuteComponent&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;FromInt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mins&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mins&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;59&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mins&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ArgumentException&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;MinuteComponent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mins&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;MinuteComponent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mins&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_mins&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mins&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It also provoked the thought that there is some trade-off between the use of F# matches and the &lt;a href=&quot;https://en.wikipedia.org/wiki/Open/closed_principle&quot;&gt;open-closed principle&lt;/a&gt;; requiring many updates if there is an addition to a union type. The suggestion was that &lt;a href=&quot;https://en.wikipedia.org/wiki/Monad_(functional_programming)&quot;&gt;monads&lt;/a&gt; may be a solution to this but I don’t know enough about them at the moment.&lt;/p&gt;

&lt;p&gt;Other things to look into include: reactive extensions (like LINQ but for events) and finding out if C#7 can be used from Visual Studio 2015 in any sensible manner.&lt;/p&gt;

&lt;h2 id=&quot;teaching-an-old-dog-new-tricks&quot;&gt;Teaching an old dog new tricks&lt;/h2&gt;

&lt;p&gt;This talk was by &lt;a href=&quot;https://twitter.com/ismailmayat&quot;&gt;Ismail Mayat&lt;/a&gt;. As I’m a big fan of clean code and TDD, this talk was a must. There were many good quotes and anecdotes in the talk, in particular Venkat Subramaniam’s “We cannot be agile if our code sucks”. It was also interesting to find out that the NASA Mercury probe had been developed in Smalltalk using what was basically TDD.&lt;/p&gt;

&lt;h2 id=&quot;scaling-agile-in-your-organisation-with-the-spotify-model&quot;&gt;Scaling Agile in your Organisation with the Spotify Model&lt;/h2&gt;

&lt;p&gt;This talk was by &lt;a href=&quot;https://twitter.com/stephenhaunts&quot;&gt;Stephen Haunts&lt;/a&gt;. I went to his talk last year as well, so he’s clearly doing something right in his marketing. This prompted me, yet again, to look at &lt;a href=&quot;https://www.meetup.com/Derbyshire-Dot-Net/&quot;&gt;Derbyshire DotNet&lt;/a&gt;; something that I didn’t do after last year’s talk. I’m sure I’ll say the same thing again next year. Also, &lt;a href=&quot;http://www.hack24.co.uk&quot;&gt;Hack24&lt;/a&gt; in Nottingham was an interesting discovery.&lt;/p&gt;

&lt;p&gt;The concept of “internal open source” was an interesting one and something that we do where I work but didn’t have a name for. I must also look into &lt;a href=&quot;https://launchdarkly.com&quot;&gt;Launch Darkly&lt;/a&gt; for feature flag management.&lt;/p&gt;

&lt;h2 id=&quot;async-in-c---the-good-the-bad-and-the-ugly&quot;&gt;Async in C# - The Good, the Bad and the Ugly&lt;/h2&gt;

&lt;p&gt;This talk was by &lt;a href=&quot;https://twitter.com/stuartblang&quot;&gt;Stuart Lang&lt;/a&gt;. I went to an async/await talk last year too but have not made much use of it over the past year. Hopefully, having attended another talk on the subject I will be inspired to try a bit harder to incorporate the ideas over the next year. &lt;a href=&quot;https://sharplab.io&quot;&gt;SharpLab&lt;/a&gt;, a tool for examining the Roslyn-generated code was another interesting discovery as was &lt;a href=&quot;https://github.com/microsoft/vs-threading&quot;&gt;vs-threading&lt;/a&gt; from Microsoft.&lt;/p&gt;

&lt;h2 id=&quot;interactive-apis-with-graphql&quot;&gt;Interactive APIs with GraphQL&lt;/h2&gt;

&lt;p&gt;This talk was by &lt;a href=&quot;https://twitter.com/samhogy&quot;&gt;Sam Hogarth&lt;/a&gt;. The final talk of the day was on GraphQL, which I’ve been meaning to find out about for a while, as an alternative to REST. One of the main advantages over REST is that the values in the data are typed. Also, it is much easier to be more specific about the data you want to be returned without having to do a lot of work setting up extra end points to query like in REST. &lt;a href=&quot;https://github.com/graphql/graphiql&quot;&gt;GraphiQL&lt;/a&gt; was an interesting looking tool for developing GraphQL.&lt;/p&gt;

&lt;p&gt;Overall, another excellent day out. Many ideas where inspired and hopefully I’ll be able to put them all to good use.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Creating C DLLs for use with C#</title>
   <link href="http://markwithall.com/programming/2017/09/01/creating-c-dlls-for-use-with-csharp.html"/>
   <updated>2017-09-01T00:00:00+00:00</updated>
   <id>http://markwithall.com/programming/2017/09/01/creating-c-dlls-for-use-with-csharp</id>
   <content type="html">&lt;p&gt;To me, creating a DLL in C and then accessing it from C# (for example, when we need more performance or to use less memory) has always seemed like a rather daunting task. This week, I decided to give it a go and found it to be surprisingly straightforward.&lt;/p&gt;

&lt;h2 id=&quot;creating-a-c-dll&quot;&gt;Creating a C DLL&lt;/h2&gt;

&lt;p&gt;We shall start with nearly the simplest thing we could possibly imagine in C:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kr&quot;&gt;__declspec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dllexport&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__declspec(dllexport)&lt;/code&gt; says export this function in the DLL.&lt;/p&gt;

&lt;p&gt;The following compiles &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;test.c&lt;/code&gt; into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;test.dll&lt;/code&gt; (making sure to use the Developer Command Prompt or call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vcvarsall.bat&lt;/code&gt; before starting):&lt;/p&gt;

&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; cl /Za /LD test.c
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/Za&lt;/code&gt; flag makes sure you are working in strict C (rather than C++). Without it, you would need to add some code to avoid name mangling:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;extern&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;C&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kr&quot;&gt;__declspec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dllexport&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you prefer to be more precise, you can do the following:&lt;/p&gt;

&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; cl /Wall /WX /O2 /Za /LD test.c
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This adds all of the warnings you could possibly ever want (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/Wall /WX&lt;/code&gt;) and optimises the code (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/O2&lt;/code&gt;).&lt;/p&gt;

&lt;h2 id=&quot;accessing-the-c-dll-functions-from-c&quot;&gt;Accessing the C DLL functions from C#&lt;/h2&gt;

&lt;p&gt;To access the function from C# (assuming that the DLL is in the current path, such as the same folder as the C# exe):&lt;/p&gt;

&lt;div class=&quot;language-c# highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;DllImport&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;test.dll&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;extern&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This can then be used as a normal C# method. For example (testing using NUnit):&lt;/p&gt;

&lt;div class=&quot;language-c# highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;TestAdd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Assert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AreEqual&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;29&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The process gets slightly more complicated for strings, structs and pointers to things but that’s a story for another day.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>TDD As If You Meant It Reviewed (Part V)</title>
   <link href="http://markwithall.com/programming/2017/06/01/test-driven-development-as-if-you-meant-it-reviewed-part-v.html"/>
   <updated>2017-06-01T00:00:00+00:00</updated>
   <id>http://markwithall.com/programming/2017/06/01/test-driven-development-as-if-you-meant-it-reviewed-part-v</id>
   <content type="html">&lt;p&gt;This is the fifth in a short series of articles about Test Driven Development.&lt;/p&gt;

&lt;div class=&quot;seriesNote&quot;&gt;
    &lt;ul&gt;
        
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
                
                &lt;li&gt;Part 1:
                
                    &lt;a href=&quot;/programming/2015/06/09/test-driven-development-as-if-you-meant-it-reviewed-part-i.html&quot;&gt;TDD As If You Meant It Reviewed (Part I)&lt;/a&gt;
                
                &lt;/li&gt;
            
        
            
                
                &lt;li&gt;Part 2:
                
                    &lt;a href=&quot;/programming/2015/07/08/test-driven-development-as-if-you-meant-it-reviewed-part-ii.html&quot;&gt;TDD As If You Meant It Reviewed (Part II)&lt;/a&gt;
                
                &lt;/li&gt;
            
        
            
        
            
                
                &lt;li&gt;Part 3:
                
                    &lt;a href=&quot;/programming/2015/11/03/test-driven-development-as-if-you-meant-it-reviewed-part-iii.html&quot;&gt;TDD As If You Meant It Reviewed (Part III)&lt;/a&gt;
                
                &lt;/li&gt;
            
        
            
        
            
                
                &lt;li&gt;Part 4:
                
                    &lt;a href=&quot;/programming/2016/08/04/test-driven-development-as-if-you-meant-it-reviewed-part-iv.html&quot;&gt;TDD As If You Meant It Reviewed (Part IV)&lt;/a&gt;
                
                &lt;/li&gt;
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
                
                &lt;li&gt;Part 5:
                
                    This article
                
                &lt;/li&gt;
            
        
            
        
            
        
            
        
            
        
            
        
    &lt;/ul&gt;
&lt;/div&gt;

&lt;p&gt;This article was written with and is &lt;a href=&quot;http://matatk.agrip.org.uk/articles/test-driven-development-as-if-you-meant-it-reviewed-part-5/&quot;&gt;also published by&lt;/a&gt; Matthew Atkinson.&lt;/p&gt;

&lt;p&gt;We’ve had a thorough look at TDDAIYMI over the last few parts of this series. Now we’re going to look at how the task might have been completed using ‘normal’ TDD.&lt;/p&gt;

&lt;p&gt;Being British, we’re using a top-down approach that starts with the controller and works out to the model and view implementations; rather than the more traditional bottom up approach, which is more akin to TDDAIYMI.&lt;/p&gt;

&lt;p&gt;We’ll start off in this part by looking, step-by-step, at each of the initial commits of the &lt;span style=&quot;color: red;&quot;&gt;RED&lt;/span&gt;-&lt;span style=&quot;color: green;&quot;&gt;GREEN&lt;/span&gt;-&lt;span style=&quot;color: blue;&quot;&gt;REFACTOR&lt;/span&gt; cycle.&lt;/p&gt;

&lt;h1 id=&quot;the-starting-commits&quot;&gt;The Starting Commits&lt;/h1&gt;

&lt;p&gt;As with all TDD, we start off by writing a failing test. We’re starting with the controller, as that seems to be the most logical place to start; it’ll tell us what we need from the model and from the view.&lt;/p&gt;

&lt;p&gt;Our first test is that the controller calls the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;is_legal()&lt;/code&gt; check on our model. However, we have a failing test at the point we try and construct the controller.&lt;/p&gt;

&lt;h2 style=&quot;color: red&quot; id=&quot;red-a-controller-is-created---2014-08-13-1407&quot;&gt;RED a controller is created - 2014-08-13 14:07&lt;/h2&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_play_move_calls_is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;controller&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NoughtsAndCrossesController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To get back to green, it is a simple process of creating a controller class.&lt;/p&gt;

&lt;h2 style=&quot;color: green&quot; id=&quot;green---2014-08-13-1408&quot;&gt;GREEN - 2014-08-13 14:08&lt;/h2&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_play_move_calls_is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;controller&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NoughtsAndCrossesController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
 
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NoughtsAndCrossesController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;After we’d passed the test, we decided we didn’t like the test name, so we made it more specific to what we actually wanted to test.&lt;/p&gt;

&lt;h2 style=&quot;color: blue&quot; id=&quot;refactor-better-test-name---2014-08-13-1410&quot;&gt;REFACTOR better test name - 2014-08-13 14:10&lt;/h2&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_playing_legal_move_updates_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;controller&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NoughtsAndCrossesController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
 
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NoughtsAndCrossesController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now we are green again, we continue to implement the test. Again, it fails to compile pretty quickly.&lt;/p&gt;

&lt;h2 style=&quot;color: red&quot; id=&quot;red-play_move---2014-08-13-1412&quot;&gt;RED play_move - 2014-08-13 14:12&lt;/h2&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_playing_legal_move_updates_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;controller&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NoughtsAndCrossesController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;controller&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;play_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
 
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NoughtsAndCrossesController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This time, we make the test pass by adding a method to our controller class.&lt;/p&gt;

&lt;h2 style=&quot;color: green&quot; id=&quot;green---2014-08-13-1412&quot;&gt;GREEN - 2014-08-13 14:12&lt;/h2&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_playing_legal_move_updates_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;controller&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NoughtsAndCrossesController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;controller&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;play_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
 
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NoughtsAndCrossesController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;play_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;There’s nothing to refactor this time, as we’ve not really done anything. Therefore, we continue to write our test by making an assertion about a fake view’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;add_move()&lt;/code&gt; getting called with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt;.&lt;/p&gt;

&lt;h2 style=&quot;color: red&quot; id=&quot;red-test-view-is-called---2014-08-13-1415&quot;&gt;RED test view is called - 2014-08-13 14:15&lt;/h2&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;mock&lt;/span&gt;
 
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_playing_legal_move_updates_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fake_view&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Mock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;controller&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NoughtsAndCrossesController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;controller&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;play_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fake_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assert_called_with&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
 
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NoughtsAndCrossesController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;play_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Making the test pass is a bit more involved this time. We have to inject the view into our controller and actually call the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;add_move()&lt;/code&gt; method from the controller.&lt;/p&gt;

&lt;h2 style=&quot;color: green&quot; id=&quot;green---2014-08-13-1417&quot;&gt;GREEN - 2014-08-13 14:17&lt;/h2&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;mock&lt;/span&gt;
 
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_playing_legal_move_updates_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fake_view&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Mock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;controller&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NoughtsAndCrossesController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fake_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;controller&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;play_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fake_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assert_called_with&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
 
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NoughtsAndCrossesController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;
 
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;play_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Again, there is nothing that we can see that’s worth refactoring at this stage.&lt;/p&gt;

&lt;p&gt;We can now move on to our second test. We want to check that playing an illegal move does not add a move to our view (Ed: probably a bad name for the test here, as we may want to update the view by informing the user they’ve played an illegal move).&lt;/p&gt;

&lt;p&gt;This initially fails as we aren’t accepting a model into our controller’s constructor.&lt;/p&gt;

&lt;h2 style=&quot;color: red&quot; id=&quot;red-added-model-to-controller---2014-08-13-1421&quot;&gt;RED added model to controller - 2014-08-13 14:21&lt;/h2&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;mock&lt;/span&gt;
 
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_playing_legal_move_updates_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fake_view&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Mock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;controller&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NoughtsAndCrossesController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fake_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;controller&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;play_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fake_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assert_called_with&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
 
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_playing_illegal_move_does_not_update_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fake_view&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Mock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fake_model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Mock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fake_model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;return_value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;controller&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NoughtsAndCrossesController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fake_model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fake_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
 
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NoughtsAndCrossesController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;
 
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;play_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Passing is easy. We add a constructor parameter (and also update our other test).&lt;/p&gt;

&lt;h2 style=&quot;color: green&quot; id=&quot;green---2014-08-13-1422&quot;&gt;GREEN - 2014-08-13 14:22&lt;/h2&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;mock&lt;/span&gt;
 
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_playing_legal_move_updates_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fake_view&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Mock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;controller&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NoughtsAndCrossesController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fake_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;controller&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;play_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fake_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assert_called_with&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
 
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_playing_illegal_move_does_not_update_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fake_view&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Mock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fake_model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Mock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fake_model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;return_value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;controller&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NoughtsAndCrossesController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fake_model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fake_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
 
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NoughtsAndCrossesController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;
 
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;play_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We can then make the test fail again by calling the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;play_move()&lt;/code&gt; method on the controller.&lt;/p&gt;

&lt;h2 style=&quot;color: red&quot; id=&quot;red-check-illegal-move-does-not-update-view---2014-08-13-1427&quot;&gt;RED check illegal move does not update view - 2014-08-13 14:27&lt;/h2&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;mock&lt;/span&gt;
 
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_playing_legal_move_updates_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fake_view&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Mock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;controller&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NoughtsAndCrossesController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fake_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;controller&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;play_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fake_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assert_called_with&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
 
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_playing_illegal_move_does_not_update_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fake_view&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Mock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fake_model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Mock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fake_model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;return_value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;controller&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NoughtsAndCrossesController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fake_model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fake_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;controller&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;play_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fake_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;called&lt;/span&gt;
 
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NoughtsAndCrossesController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;
 
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;play_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Making the test pass is a simple case (as it should be) of checking that it is legal by calling the model’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;is_legal()&lt;/code&gt; method (which we’ve already mocked). Note that we also need to update our first test by passing a model.&lt;/p&gt;

&lt;h2 style=&quot;color: green&quot; id=&quot;green---2014-08-13-1428&quot;&gt;GREEN - 2014-08-13 14:28&lt;/h2&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;mock&lt;/span&gt;
 
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_playing_legal_move_updates_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fake_view&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Mock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fake_model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Mock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;controller&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NoughtsAndCrossesController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fake_model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fake_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;controller&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;play_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fake_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assert_called_with&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
 
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_playing_illegal_move_does_not_update_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fake_view&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Mock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fake_model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Mock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fake_model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;return_value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;controller&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NoughtsAndCrossesController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fake_model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fake_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;controller&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;play_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fake_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;called&lt;/span&gt;
 
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NoughtsAndCrossesController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;
 
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;play_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We can see that we’ve introduced quite a bit of duplication in these two tests, so we need to refactor. Most of the duplication can be removed by introducing a setup method to create our mocks and controller.&lt;/p&gt;

&lt;h2 style=&quot;color: blue&quot; id=&quot;refactor-use-a-test-class---2014-09-23-1248&quot;&gt;REFACTOR use a test class - 2014-09-23 12:48&lt;/h2&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;mock&lt;/span&gt;
 
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TestNoughtsAndCrosses&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setup_method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fake_view&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Mock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fake_model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Mock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;controller&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NoughtsAndCrossesController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fake_model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fake_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
 
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;teardown_method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
 
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_playing_legal_move_updates_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;controller&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;play_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fake_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assert_called_with&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
 
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_playing_illegal_move_does_not_update_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fake_model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;return_value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;controller&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;play_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fake_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;called&lt;/span&gt;
 
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NoughtsAndCrossesController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;
 
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;play_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It is now much easier to add a new test. We now check that an illegal move results in an appropriate message to the view.&lt;/p&gt;

&lt;h2 style=&quot;color: red&quot; id=&quot;red-illegal-move-reports-error---2014-09-23-1303&quot;&gt;RED illegal move reports error - 2014-09-23 13:03&lt;/h2&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;mock&lt;/span&gt;
 
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TestNoughtsAndCrosses&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setup_method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fake_view&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Mock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fake_model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Mock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;controller&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NoughtsAndCrossesController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fake_model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fake_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
 
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;teardown_method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
 
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_playing_legal_move_updates_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;controller&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;play_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fake_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assert_called_with&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
 
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_playing_illegal_move_does_not_update_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fake_model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;return_value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;controller&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;play_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fake_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;called&lt;/span&gt;
 
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_playing_illegal_move_reports_error_in_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fake_model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;return_value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;controller&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;play_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fake_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;report_error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assert_called_with&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'Illegal move'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
 
 
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NoughtsAndCrossesController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;
 
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;play_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Passing the test is straightforward.&lt;/p&gt;

&lt;h2 style=&quot;color: green&quot; id=&quot;green---2014-09-23-1303&quot;&gt;GREEN - 2014-09-23 13:03&lt;/h2&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;mock&lt;/span&gt;
 
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TestNoughtsAndCrosses&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setup_method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fake_view&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Mock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fake_model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Mock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;controller&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NoughtsAndCrossesController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fake_model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fake_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
 
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;teardown_method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
 
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_playing_legal_move_updates_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;controller&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;play_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fake_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assert_called_with&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
 
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_playing_illegal_move_does_not_update_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fake_model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;return_value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;controller&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;play_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fake_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;called&lt;/span&gt;
 
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_playing_illegal_move_reports_error_in_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fake_model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;return_value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;controller&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;play_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fake_view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;report_error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assert_called_with&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'Illegal move'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
 
 
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NoughtsAndCrossesController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;
 
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;play_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;report_error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'Illegal move'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Progress continues in the same vein until we have completed the controller. One could argue that we should really be working in thin slices of full-stack functionality but we decided that the task was simple enough to do as a single task.&lt;/p&gt;

&lt;p&gt;Once the controller is complete, we move on to &lt;a href=&quot;https://github.com/BillionthMonkey/NoughtsAndCrosses/commit/ea5d659b14c124bbc037e3e38c34a9d06e3db526&quot;&gt;the model&lt;/a&gt; and then, finally, to &lt;a href=&quot;https://github.com/BillionthMonkey/NoughtsAndCrosses/commit/8eeb7373dc4fba7b694b23ef24c071a4b8a9083d&quot;&gt;the view&lt;/a&gt;.&lt;/p&gt;

&lt;h1 id=&quot;next-time&quot;&gt;Next Time&lt;/h1&gt;

&lt;p&gt;Next time we’ll look at the transitions to implementing the model and the view and some of the other interesting moments from the ‘Normal’ TDD.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Accessing WPF ListBox SelectedItems using MVVM</title>
   <link href="http://markwithall.com/programming/2017/05/14/accessing-wpf-listbox-selecteditems-using-mvvm.html"/>
   <updated>2017-05-14T00:00:00+00:00</updated>
   <id>http://markwithall.com/programming/2017/05/14/accessing-wpf-listbox-selecteditems-using-mvvm</id>
   <content type="html">&lt;p&gt;A common problem that people face using the Model-View-ViewModel (MVVM) pattern is handling multiple selected items in a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ListBox&lt;/code&gt; with extended selection mode turned on.&lt;/p&gt;

&lt;p&gt;Let’s have a look at an example.&lt;/p&gt;

&lt;h2 id=&quot;the-viewmodel&quot;&gt;The ViewModel&lt;/h2&gt;

&lt;p&gt;We have a list of items in an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ObservableCollection&lt;/code&gt; (so that the &lt;em&gt;View&lt;/em&gt; updates if we modify the content of the collection). We also have a placeholder for some command that will operate on the selected items.&lt;/p&gt;

&lt;div class=&quot;language-c# highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MainPresenter&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Presenter&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ObservableCollection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ItemPresenter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Items&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ObservableCollection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ItemPresenter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ItemPresenter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;A&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ItemPresenter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;B&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ItemPresenter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;C&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ItemPresenter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;D&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ICommand&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DoStuffCommand&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Command&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;param&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;…&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;For this example, each item is just a wrapped string. The item itself looks like this.&lt;/p&gt;

&lt;div class=&quot;language-c# highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ItemPresenter&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Presenter&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ItemPresenter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_value&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;the-view&quot;&gt;The View&lt;/h2&gt;

&lt;p&gt;The basic &lt;em&gt;View&lt;/em&gt; is a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ListBox&lt;/code&gt;, with the selection mode set to extended (so we can select multiple items using ctrl/shift click or the keyboard equivalents). We also have a button that we’d like to perform an action on the selected items.&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;ListBox&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;ItemsSource=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{Binding Items}&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;SelectionMode=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Extended&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;Button&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Command=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{Binding DoStuffCommand}&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Do Stuff&lt;span class=&quot;nt&quot;&gt;&amp;lt;/Button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;the-mvvm-framework&quot;&gt;The MVVM Framework&lt;/h2&gt;

&lt;p&gt;For completeness, here is the implementation of a basic &lt;em&gt;ViewModel&lt;/em&gt; base class and a simple &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ICommand&lt;/code&gt; implementation.&lt;/p&gt;

&lt;div class=&quot;language-c# highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Presenter&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;INotifyPropertyChanged&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PropertyChangedEventHandler&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PropertyChanged&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;RaisePropertyChanged&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CallerMemberName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;propertyName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;PropertyChanged&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Invoke&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;PropertyChangedEventArgs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;propertyName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-c# highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Command&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ICommand&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EventHandler&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CanExecuteChanged&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;remove&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Command&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_action&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;CanExecute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Invoke&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;how-wed-like-to-do-it&quot;&gt;How We’d Like To Do It&lt;/h2&gt;

&lt;p&gt;In an ideal world, we’d like to bind an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ObservableCollection&lt;/code&gt; directly to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SelectedItems&lt;/code&gt; property of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ListBox&lt;/code&gt;. Alas, this is not currently possible.&lt;/p&gt;

&lt;p&gt;In &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MainPresenter&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-c# highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ObservableCollection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ItemPresenter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SelectedItems&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ObservableCollection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ItemPresenter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MainWindow.xaml&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;ListBox&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;ItemsSource=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{Binding Items}&quot;&lt;/span&gt;
         &lt;span class=&quot;na&quot;&gt;SelectionMode=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Extended&quot;&lt;/span&gt;
         &lt;span class=&quot;na&quot;&gt;SelectedItems=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{Binding SelectedItems}&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;one-way-to-presenter&quot;&gt;One-way To Presenter&lt;/h2&gt;

&lt;p&gt;If we only care about setting the selected items from the &lt;em&gt;View&lt;/em&gt; and operating on it when a command it executed, we can do this relatively simply.&lt;/p&gt;

&lt;p&gt;First we need to give the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ListBox&lt;/code&gt; a name.&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;ListBox&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;x:Name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ListBox&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;ItemsSource=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{Binding Items}&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;SelectionMode=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Extended&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And then we can add a command parameter that points at the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ListBox&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SelectedItems&lt;/code&gt; property. The property is an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IList&lt;/code&gt; (non-generic) containing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ItemPresenter&lt;/code&gt; references.&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;Button&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Command=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{Binding DoStuffCommand}&quot;&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;CommandParameter=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{Binding ElementName=ListBox, Path=SelectedItems}&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Do Stuff&lt;span class=&quot;nt&quot;&gt;&amp;lt;/Button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now our command will receive the list of selected &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ItemPresenter&lt;/code&gt; objects as a parameter and we can do as we wish with them.&lt;/p&gt;

&lt;h2 id=&quot;two-way-binding&quot;&gt;Two-way Binding&lt;/h2&gt;

&lt;p&gt;If we want two-way binding, things get a little more messy.&lt;/p&gt;

&lt;p&gt;Firstly, we need to add a property to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ItemPresenter&lt;/code&gt; to store the selected state of the item.&lt;/p&gt;

&lt;div class=&quot;language-c# highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_isSelected&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IsSelected&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_isSelected&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_isSelected&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;RaisePropertyChanged&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And then we have to find a way of binding that property to the &lt;em&gt;View&lt;/em&gt;. The easiest way to do this is to create a style for a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ListBoxItem&lt;/code&gt; and bind the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IsSelected&lt;/code&gt; property there.&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;ListBox&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;ItemsSource=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{Binding Items}&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;SelectionMode=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Extended&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;ListBox.ItemContainerStyle&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;Style&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;TargetType=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ListBoxItem&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;Setter&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Property=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;IsSelected&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Value=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{Binding IsSelected}&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;/Style&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/ListBox.ItemContainerStyle&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/ListBox&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now we can set the selected items from the &lt;em&gt;ViewModel&lt;/em&gt; as well as from the View.&lt;/p&gt;

&lt;p&gt;When we execute the command, we can access the selected items using a short LINQ query:&lt;/p&gt;

&lt;div class=&quot;language-c# highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;Items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Where&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IsSelected&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;update&quot;&gt;Update&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://twitter.com/TaiShaBi&quot;&gt;David Hewson&lt;/a&gt; has kindly pointed out that this two-way binding workaround doesn’t play nicely with virtualization of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ListBox&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;There are two options available here. Firstly, we could disable virtualization on the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ListBox&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;ListBox&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;VirtualizingStackPanel.IsVirtualizing=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;False&quot;&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is fine, as long as we aren’t expecting the list of items to grow too large.&lt;/p&gt;

&lt;p&gt;A second, more extreme workaround is to override the ‘select all’ command for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ListBox&lt;/code&gt; and set the selected items via the &lt;em&gt;ViewModel&lt;/em&gt;. This involves intercepting Ctrl+A and calling a command on the &lt;em&gt;ViewModel&lt;/em&gt;.&lt;/p&gt;

&lt;div class=&quot;language-c# highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ICommand&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SelectAllCommand&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Command&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IsSelected&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;ListBox.InputBindings&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;KeyBinding&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Gesture=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Ctrl+A&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Command=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{Binding SelectAllCommand}&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/ListBox.InputBindings&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</content>
 </entry>
 
 <entry>
   <title>Creating Self-Hosted Python Modules</title>
   <link href="http://markwithall.com/programming/2016/12/20/creating-self-hosted-python-modules.html"/>
   <updated>2016-12-20T00:00:00+00:00</updated>
   <id>http://markwithall.com/programming/2016/12/20/creating-self-hosted-python-modules</id>
   <content type="html">&lt;p&gt;&lt;em&gt;The following assumes Python 3.x on Windows and pip version 8.1.1 or earlier&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;creating-a-module&quot;&gt;Creating A Module&lt;/h2&gt;

&lt;p&gt;Required files:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setup.py&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setup.cfg&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;README&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MANIFEST.in&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;and a folder containing the module itself.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;NOTE: README can be one of: README, README.txt or README.rst&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;All files can be blank except for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setup.py&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Minimal content of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setup.py&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;setuptools&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;find_packages&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;setup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'modulename'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'0.1.0'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'Put description here'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;author&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'Name'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;author_email&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'name@example.com'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'module url'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;packages&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find_packages&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exclude&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'docs'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'tests'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To build the module package, run the command: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;python setup.py sdist&lt;/code&gt; from the root of the project.&lt;/p&gt;

&lt;p&gt;This will create a folder &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dist&lt;/code&gt; with the file &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;modulename-0.1.0.zip&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;For more details see &lt;a href=&quot;https://packaging.python.org/distributing/&quot;&gt;the documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;using-external-versiontxt&quot;&gt;Using external version.txt&lt;/h3&gt;

&lt;p&gt;To read the version number from a file:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;setuptools&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;find_packages&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'version.txt'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;readline&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rstrip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;setup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'modulename'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'Put description here'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;author&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'Name'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;author_email&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'name@example.com'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'module url'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;packages&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find_packages&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exclude&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'docs'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'tests'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;NOTE from pip verison 8.1.2 onwards, the modulename should replace dots with hyphens; otherwise pip won’t be able to find them on the self-hosted server&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;version.txt&lt;/code&gt; will also need to be added to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MANIFEST.in&lt;/code&gt; file:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;include version.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;hosting-a-repository&quot;&gt;Hosting A Repository&lt;/h2&gt;

&lt;p&gt;To host the server, put the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;modulename-0.1.0.zip&lt;/code&gt; file into a folder &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;archive\modulename&lt;/code&gt;, then run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;python -m http.server 9000&lt;/code&gt; from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;archive&lt;/code&gt; folder.&lt;/p&gt;

&lt;p&gt;For more details see &lt;a href=&quot;https://packaging.python.org/self_hosted_repository/&quot;&gt;the documentation&lt;/a&gt; and &lt;a href=&quot;http://docs.python-guide.org/en/latest/shipping/packaging/&quot;&gt;also&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;installing-the-module&quot;&gt;Installing The Module&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pip install --extra-index-url http://localhost:9000/ modulename&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;It’s probably worth doing this in a virtual environment to avoid corrupting the main python installation:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;gt; python -m venv venv
&amp;gt; venv\Scripts\activate.bat
&amp;gt; pip install --extra-index-url http://localhost:9000/ modulename
&amp;gt; ... do stuff ...
&amp;gt; deactivate
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

</content>
 </entry>
 
 <entry>
   <title>MVVM - Creating New Windows</title>
   <link href="http://markwithall.com/programming/2016/10/15/mvvm-creating-new-windows.html"/>
   <updated>2016-10-15T00:00:00+00:00</updated>
   <id>http://markwithall.com/programming/2016/10/15/mvvm-creating-new-windows</id>
   <content type="html">&lt;p&gt;I recently saw a post on &lt;a href=&quot;http://programmers.stackexchange.com/questions/330842/in-mvvm-should-viewmodel-or-view-be-responsible-for-creating-new-views&quot;&gt;StackExchange&lt;/a&gt; about creating new windows in an MVVM-compatible way. This seems to me to be a common cause of confusion.&lt;/p&gt;

&lt;p&gt;My interpretation of MVVM is that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ViewModel&lt;/code&gt; should not know about the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;View&lt;/code&gt;. As windows, and related UI elements, are clearly a part of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;View&lt;/code&gt;, it seems to me that creating them should be a responsibility of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;View&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That said, what we want is for a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Command&lt;/code&gt; in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ViewModel&lt;/code&gt; to result in a new window being created. For example, an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OpenFileDialog&lt;/code&gt;. The requirement of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ViewModel&lt;/code&gt;, however, is for a filename. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ViewModel&lt;/code&gt; shouldn’t care that a new dialog window will be created to prompt the user for this filename.&lt;/p&gt;

&lt;p&gt;When creating a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ViewModel&lt;/code&gt; it is often useful to assume you have two views: a GUI and a command-line interface. In this instance, the GUI request for a filename would spawn an open file dialog and the command-line version would have a text prompt.&lt;/p&gt;

&lt;p&gt;Let’s look at a concrete example.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ViewModel&lt;/code&gt; needs an interface that is specific to its requirements. In this case, it wants a filename.&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FilenameProvider&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetFilename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;View&lt;/code&gt; could be a GUI, in which case the implementation of this interface could look something like:&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;GuiFilenameProvider&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FilenameProvider&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetFilename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ofd&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;OpenFileDialog&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Title&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;File&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Filter&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;All Files|*.*&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ofd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ShowDialog&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Application&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Current&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MainWindow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ofd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FileName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;However, if we were working on a command-line version of our application, a different implementation of the interface would be needed. For example:&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CommandLineFilenameProvider&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FilenameProvider&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetFilename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;WriteLine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Give me a file: &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ReadLine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ViewModel&lt;/code&gt; doesn’t care where it gets the filename from, as long as it gets one. It would just have access to the interface and use it when it needs a filename. Something like the following:&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyViewModel&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Presenter&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FilenameProvider&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_filenameProvider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MyModel&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;MyViewModel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FilenameProvider&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;filenameProvider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MyModel&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_filenameProvider&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;filenameProvider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_model&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ICommand&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DoSomethingCommand&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Command&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_filenameProvider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetFilename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;_model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;DoSomethingWithFilename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ViewModel&lt;/code&gt; doesn’t know that the filename is being provided by a GUI or by a command-line interface.&lt;/p&gt;

&lt;p&gt;It should be possible to use this type of pattern in most cases, where the effect of a command in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ViewModel&lt;/code&gt; is the creation of a new window. To me, the one obvious exception to this is where you just want to create a new instance of a window with no additional side effects.  In this case, this feels like an entirely &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;View&lt;/code&gt;-based action and the creation of the window should be handled there.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>DDD North 2016 Review</title>
   <link href="http://markwithall.com/programming/2016/10/02/dddnorth-review.html"/>
   <updated>2016-10-02T00:00:00+00:00</updated>
   <id>http://markwithall.com/programming/2016/10/02/dddnorth-review</id>
   <content type="html">&lt;p&gt;Yesterday (1st October 2016) I braved the coldest morning for quite some time to make the long trek north to Leeds (a much nicer journey now most of the M1 is open) for &lt;a href=&quot;http://www.dddnorth.co.uk&quot;&gt;DDD North 2016&lt;/a&gt;. I had been to the &lt;a href=&quot;/programming/2014/10/19/dddnorth-review.html&quot;&gt;2014&lt;/a&gt; edition of the conference and found it excellent value for the price (free), so I thought I’d go again this year.&lt;/p&gt;

&lt;p&gt;Yet again, it was a great day (with the one exception of the increasingly unpleasant aroma from the gents restroom). Alas, I was forced to miss the final session of talks due to a prior engagement but the rest of the talks that I saw were excellent. It was also nice to catch up with my Northern colleagues, whom I hadn’t seen for a while.&lt;/p&gt;

&lt;h2 id=&quot;this-is-not-the-async-you-are-looking-for&quot;&gt;This is not the Async you are looking for&lt;/h2&gt;

&lt;p&gt;This talk was by &lt;a href=&quot;https://twitter.com/westleyl&quot;&gt;Liam Westley&lt;/a&gt;. I’ve not really played with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;async/await&lt;/code&gt; much as yet, so hopefully having watched this talk will prompt me to do so. In particular, it prompted me to look into &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/hh228603(v=vs.110).aspx&quot;&gt;TPL Dataflow&lt;/a&gt;. I also have to look at the white paper &lt;a href=&quot;https://www.microsoft.com/en-gb/download/details.aspx?id=19957&quot;&gt;Task-based Asynchronous Pattern&lt;/a&gt;. Liam also gave a very entertaining lunchtime talk on what the point of Microsoft is.&lt;/p&gt;

&lt;h2 id=&quot;10-more-things-you-need-to-do-to-succeed-as-a-tech-lead&quot;&gt;10 more things you need to do to succeed as a Tech Lead&lt;/h2&gt;

&lt;p&gt;This talk was by &lt;a href=&quot;https://twitter.com/Rammesses&quot;&gt;Joel Hammond-Turner&lt;/a&gt;.  As I had not seen the first talk in this series, I gained 20 things, as the first 10 were summarised at the beginning. 
I’m sure the full list can be found upon the Internet but a couple of them persuaded me that I should probably do more logging than I currently do and that I should be more aware of the real cost of projects.&lt;/p&gt;

&lt;h2 id=&quot;run-your-team-lean-and-deliver-more&quot;&gt;Run Your Team Lean and Deliver More&lt;/h2&gt;

&lt;p&gt;This talk was by &lt;a href=&quot;https://twitter.com/stephenhaunts&quot;&gt;Stephen Haunts&lt;/a&gt;. It was worth attending for the discovery of the &lt;a href=&quot;https://derbyshiredotnet.co.uk&quot;&gt;Derbyshire DotNet&lt;/a&gt; group alone.  That said, the rest of the talk was worthwhile to clarify in my mind Lean,  Kanban and related things.&lt;/p&gt;

&lt;h2 id=&quot;take-control---control-code-complexity&quot;&gt;Take Control - Control Code Complexity&lt;/h2&gt;

&lt;p&gt;This talk was by &lt;a href=&quot;https://www.linkedin.com/in/fanyang2010&quot;&gt;Fan Yang&lt;/a&gt;. This talk suggested I read &lt;a href=&quot;https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf&quot;&gt;Why Functional Programming Matters&lt;/a&gt; by John Hughes (of Haskell fame). I was also pointed at Resharper’s Cyclomatic Complexity checker, which I didn’t know existed. The talk itself was very entertaining and practical; walking through example code and refactoring it to reduce cyclomatic complexity. The code for which can be found at her &lt;a href=&quot;https://github.com/misssoft&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Overall the day was definitely worth the trip. Many thanks to all of the organisers and sponsors for making it happen.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>TDD With Excel VBA</title>
   <link href="http://markwithall.com/programming/2016/09/16/tdd-with-excel-vba.html"/>
   <updated>2016-09-16T00:00:00+00:00</updated>
   <id>http://markwithall.com/programming/2016/09/16/tdd-with-excel-vba</id>
   <content type="html">&lt;p&gt;Every so often, I have contemplated the idea of TDD for Microsoft Excel VBA.  Finally, I got around to trying it out.&lt;/p&gt;

&lt;h2 id=&quot;the-fibonacci-sequence-kata&quot;&gt;The Fibonacci Sequence Kata&lt;/h2&gt;

&lt;p&gt;As a test case, I’m using the Fibonacci Sequence kata by Jason Gorman of &lt;a href=&quot;http://codemanship.co.uk/tdd.html&quot;&gt;Codemanship&lt;/a&gt;; as it’s one of the simplest katas out there.&lt;/p&gt;

&lt;p&gt;The task is as follows:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Write a [VBA] script that writes out the number for a given position in the Fibonacci Sequence.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;step-by-step&quot;&gt;Step-By-Step&lt;/h2&gt;

&lt;p&gt;To getting going with TDD in Microsoft Excel VBA we take the following steps:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Launch Excel&lt;/li&gt;
  &lt;li&gt;Create new blank workbook&lt;/li&gt;
  &lt;li&gt;Open the Macro Editor (Alt+F11)&lt;/li&gt;
  &lt;li&gt;Right-click on current workbook in Macro Editor and insert new module&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now we have everything we need we can write our first failing test.  We enter the following in the worksheet:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Input&lt;/th&gt;
      &lt;th&gt;Expected Output&lt;/th&gt;
      &lt;th&gt;Actual Output&lt;/th&gt;
      &lt;th&gt;Test Result&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=Fibonacci(A2)&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=IF(B2=C2,&quot;PASS&quot;,&quot;FAIL&quot;)&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Conditional formatting can be added to the Test Result column to better highlight PASS and FAIL.&lt;/p&gt;

&lt;p&gt;Now we have our first failing test, we can add code to make the test pass in the macro editor:&lt;/p&gt;

&lt;div class=&quot;language-vb highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;Function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Fibonacci&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Fibonacci&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;End&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;Function&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Switching back to the worksheet and pressing F9 refreshes the test results. We can now see the first test pass.&lt;/p&gt;

&lt;p&gt;We now add the next test:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Input&lt;/th&gt;
      &lt;th&gt;Expected Output&lt;/th&gt;
      &lt;th&gt;Actual Output&lt;/th&gt;
      &lt;th&gt;Test Result&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=Fibonacci(A2)&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=IF(B2=C2,&quot;PASS&quot;,&quot;FAIL&quot;)&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=Fibonacci(A3)&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=IF(B3=C3,&quot;PASS&quot;,&quot;FAIL&quot;)&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;And update code to make it pass:&lt;/p&gt;

&lt;div class=&quot;language-vb highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;Function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Fibonacci&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Fibonacci&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;End&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;Function&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Repeat until no more failing tests can be added.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/TDD-VBA-1.png&quot; alt=&quot;Worksheet table with failing 3rd test&quot; /&gt;&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Input&lt;/th&gt;
      &lt;th&gt;Expected Output&lt;/th&gt;
      &lt;th&gt;Actual Output&lt;/th&gt;
      &lt;th&gt;Test Result&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=Fibonacci(A2)&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=IF(B2=C2,&quot;PASS&quot;,&quot;FAIL&quot;)&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=Fibonacci(A3)&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=IF(B3=C3,&quot;PASS&quot;,&quot;FAIL&quot;)&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=Fibonacci(A4)&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=IF(B4=C4,&quot;PASS&quot;,&quot;FAIL&quot;)&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;div class=&quot;language-vb highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;Function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Fibonacci&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;If&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;Then&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Fibonacci&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;Else&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Fibonacci&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;End&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;If&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;End&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;Function&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Input&lt;/th&gt;
      &lt;th&gt;Expected Output&lt;/th&gt;
      &lt;th&gt;Actual Output&lt;/th&gt;
      &lt;th&gt;Test Result&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=Fibonacci(A2)&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=IF(B2=C2,&quot;PASS&quot;,&quot;FAIL&quot;)&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=Fibonacci(A3)&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=IF(B3=C3,&quot;PASS&quot;,&quot;FAIL&quot;)&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=Fibonacci(A4)&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=IF(B4=C4,&quot;PASS&quot;,&quot;FAIL&quot;)&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;3&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=Fibonacci(A5)&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=IF(B5=C5,&quot;PASS&quot;,&quot;FAIL&quot;)&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;div class=&quot;language-vb highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;Function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Fibonacci&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;If&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;Then&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Fibonacci&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;Else&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Fibonacci&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;End&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;If&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;End&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;Function&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Skipping 4, as it already passes:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Input&lt;/th&gt;
      &lt;th&gt;Expected Output&lt;/th&gt;
      &lt;th&gt;Actual Output&lt;/th&gt;
      &lt;th&gt;Test Result&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=Fibonacci(A2)&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=IF(B2=C2,&quot;PASS&quot;,&quot;FAIL&quot;)&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=Fibonacci(A3)&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=IF(B3=C3,&quot;PASS&quot;,&quot;FAIL&quot;)&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=Fibonacci(A4)&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=IF(B4=C4,&quot;PASS&quot;,&quot;FAIL&quot;)&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;3&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=Fibonacci(A5)&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=IF(B5=C5,&quot;PASS&quot;,&quot;FAIL&quot;)&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;5&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;5&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=Fibonacci(A6)&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=IF(B6=C6,&quot;PASS&quot;,&quot;FAIL&quot;)&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;div class=&quot;language-vb highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;Function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Fibonacci&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;If&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;Then&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Fibonacci&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;Else&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Fibonacci&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Fibonacci&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Fibonacci&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;End&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;If&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;End&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;Function&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;/images/TDD-VBA-2.png&quot; alt=&quot;Completed happy path worksheet table&quot; /&gt;&lt;/p&gt;

&lt;p&gt;That completes the “Happy Path”.  One can continue with negative numbers and other invalid input.&lt;/p&gt;

&lt;h2 id=&quot;conclusions&quot;&gt;Conclusions&lt;/h2&gt;

&lt;p&gt;We’ve shown that it is possible to do TDD in Microsoft Excel VBA (at least for simple functions that return a value).&lt;/p&gt;

&lt;p&gt;More complex tests might require something more from our test setup.  Perhaps writing test functions in VBA that return “PASS” or “FAIL” (and details) and calling them from cells in the worksheet.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>The Single Responsibility Principle</title>
   <link href="http://markwithall.com/programming/2016/09/04/the-single-responsibility-principle.html"/>
   <updated>2016-09-04T00:00:00+00:00</updated>
   <id>http://markwithall.com/programming/2016/09/04/the-single-responsibility-principle</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Single_responsibility_principle&quot;&gt;The Single Responsibility Principle&lt;/a&gt; is seemingly the simplest of the SOLID principles, I’ve spent quite some time trying to get my head around what it actually means in practice.  The ‘official’ description is as follows:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“A class should have only one reason to change.” - Robert C Martin&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I’ve come to the conclusion that a class can have one of three main types of responsibility:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Calculation&lt;/li&gt;
  &lt;li&gt;Communication&lt;/li&gt;
  &lt;li&gt;Construction&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;calculation&quot;&gt;Calculation&lt;/h2&gt;

&lt;p&gt;A class that performs some calculation.&lt;/p&gt;

&lt;div class=&quot;language-c# highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Calculation&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Subtract&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Reason to change: different calculation.&lt;/p&gt;

&lt;h2 id=&quot;communication&quot;&gt;Communication&lt;/h2&gt;

&lt;p&gt;A class that manages communication between other classes.&lt;/p&gt;

&lt;div class=&quot;language-c# highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Communication&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IDataSource&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Calculation&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_calc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Communication&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IDataSource&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Calculation&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_source&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_calc&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;PerformAdd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_calc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AddResult&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;PerformSubtract&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_calc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SubtractResult&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;IDataSource&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AddResult&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SubtractResult&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Reason to change: dependencies change API.&lt;/p&gt;

&lt;h2 id=&quot;construction&quot;&gt;Construction&lt;/h2&gt;

&lt;p&gt;A class that creates other classes.&lt;/p&gt;

&lt;div class=&quot;language-c# highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Construction&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Communication&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;CreateCommunication&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SourceType&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;source&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;CreateDataSource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;calc&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;CreateCalculation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Communication&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IDataSource&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;CreateDataSource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SourceType&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;switch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SourceType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;DatabaseSource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SourceType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CSV&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;CSVSource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ArgumentException&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Unknown type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Calculation&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;CreateCalculation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Calculation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SourceType&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;DB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;CSV&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Reason to change: classes being constructed change constructors.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>TDD As If You Meant It Reviewed (Part IV)</title>
   <link href="http://markwithall.com/programming/2016/08/04/test-driven-development-as-if-you-meant-it-reviewed-part-iv.html"/>
   <updated>2016-08-04T00:00:00+00:00</updated>
   <id>http://markwithall.com/programming/2016/08/04/test-driven-development-as-if-you-meant-it-reviewed-part-iv</id>
   <content type="html">&lt;p&gt;This is the fourth in a short series of articles about Test Driven Development.&lt;/p&gt;

&lt;div class=&quot;seriesNote&quot;&gt;
    &lt;ul&gt;
        
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
                
                &lt;li&gt;Part 1:
                
                    &lt;a href=&quot;/programming/2015/06/09/test-driven-development-as-if-you-meant-it-reviewed-part-i.html&quot;&gt;TDD As If You Meant It Reviewed (Part I)&lt;/a&gt;
                
                &lt;/li&gt;
            
        
            
                
                &lt;li&gt;Part 2:
                
                    &lt;a href=&quot;/programming/2015/07/08/test-driven-development-as-if-you-meant-it-reviewed-part-ii.html&quot;&gt;TDD As If You Meant It Reviewed (Part II)&lt;/a&gt;
                
                &lt;/li&gt;
            
        
            
        
            
                
                &lt;li&gt;Part 3:
                
                    &lt;a href=&quot;/programming/2015/11/03/test-driven-development-as-if-you-meant-it-reviewed-part-iii.html&quot;&gt;TDD As If You Meant It Reviewed (Part III)&lt;/a&gt;
                
                &lt;/li&gt;
            
        
            
        
            
                
                &lt;li&gt;Part 4:
                
                    This article
                
                &lt;/li&gt;
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
                
                &lt;li&gt;Part 5:
                
                    &lt;a href=&quot;/programming/2017/06/01/test-driven-development-as-if-you-meant-it-reviewed-part-v.html&quot;&gt;TDD As If You Meant It Reviewed (Part V)&lt;/a&gt;
                
                &lt;/li&gt;
            
        
            
        
            
        
            
        
            
        
            
        
    &lt;/ul&gt;
&lt;/div&gt;

&lt;p&gt;This article was written with and is &lt;a href=&quot;http://matatk.agrip.org.uk/articles/test-driven-development-as-if-you-meant-it-reviewed-part-4/&quot;&gt;also published by&lt;/a&gt; Matthew Atkinson.&lt;/p&gt;

&lt;p&gt;We’ve taken a detailed look, in the previous part, at how to get started with TDDAIYMI, in this part we will jump around a bit more and look at several of the interesting moments that came about during the exercise.&lt;/p&gt;

&lt;h1 id=&quot;communicating-classes&quot;&gt;Communicating Classes&lt;/h1&gt;

&lt;p&gt;Our first concern was how to introduce classes when this became necessary–because the tests must be made to pass within the test method, we thought this would be tricky. However we realised that, when we want to split out an inner class to clean up an existing class, this can easily be achieved in the refactoring stage. &lt;a href=&quot;https://github.com/BillionthMonkey/NoughtsAndCrosses/commit/7a8486584e5d073d84f5fe2e301a9b8fd78b75bd&quot;&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ResultChecker&lt;/code&gt; class was extracted&lt;/a&gt; from the existing code as part of the refactoring, in line with rule 4.1 of &lt;a href=&quot;https://cumulative-hypotheses.org/2011/08/30/tdd-as-if-you-meant-it/&quot;&gt;TDDAIYMI&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;You want a new class—wait until refactoring time, then… create non-test classes to provide a destination for a Move Method and for no other reason (populate implementation classes with methods by doing Move Method, and no other way)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Extraction of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ResultChecker&lt;/code&gt; class:&lt;/p&gt;

&lt;div class=&quot;language-diff highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gh&quot;&gt;diff --git a/nac.py b/nac.py
index 56222aa..d6bee00 100644
&lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;--- a/nac.py
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+++ b/nac.py
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@@ -1,27 +1,27 @@&lt;/span&gt;
 def test_move_is_legal_if_not_already_played():
&lt;span class=&quot;gd&quot;&gt;-	nac = NoughtsAndCrosses()
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+	nac = NoughtsAndCrosses(ResultChecker())
&lt;/span&gt; 	assert nac.is_legal(0) is True

 def test_move_is_not_legal_if_already_played():
&lt;span class=&quot;gd&quot;&gt;-	nac = NoughtsAndCrosses()
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+	nac = NoughtsAndCrosses(ResultChecker())
&lt;/span&gt; 	nac.moves_played_so_far = [0]
 	assert nac.is_legal(0) is False

 def test_move_is_not_legal_if_below_lower_bound():
&lt;span class=&quot;gd&quot;&gt;-	nac = NoughtsAndCrosses()
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+	nac = NoughtsAndCrosses(ResultChecker())
&lt;/span&gt; 	assert nac.is_legal(-1) is False

 def test_move_is_not_legal_if_above_upper_bound():
&lt;span class=&quot;gd&quot;&gt;-	nac = NoughtsAndCrosses()
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+	nac = NoughtsAndCrosses(ResultChecker())
&lt;/span&gt; 	assert nac.is_legal(9) is False

 def test_draw():
&lt;span class=&quot;gd&quot;&gt;-	nac = NoughtsAndCrosses()
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+	nac = NoughtsAndCrosses(ResultChecker())
&lt;/span&gt; 	nac.moves_played_so_far = [ 0, 1, 2, 3, 4, 5, 6, 7, 8 ]
 	assert nac.is_draw() is True

 def test_not_draw():
&lt;span class=&quot;gd&quot;&gt;-	nac = NoughtsAndCrosses()
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+	nac = NoughtsAndCrosses(ResultChecker())
&lt;/span&gt; 	nac.moves_played_so_far = [ 0, 1, 2, 3, 4, 5, 6, 7 ]
 	assert nac.is_draw() is False

@@ -50,15 +50,16 @@ def test_bottom_left_diagonal_filled_player_one_is_win():
 	_is_win_for_player_one([ 2, 7, 4, 8, 6 ])

 def _is_win_for_player_one(moves_played_so_far):
&lt;span class=&quot;gd&quot;&gt;-    nac = NoughtsAndCrosses()
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+    nac = NoughtsAndCrosses(ResultChecker())
&lt;/span&gt;     nac.moves_played_so_far = moves_played_so_far
     assert nac.is_win_for_player_one() is True


 class NoughtsAndCrosses:
&lt;span class=&quot;gd&quot;&gt;-	def __init__(self):
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+	def __init__(self, result_checker):
&lt;/span&gt; 		self.moves_played_so_far = []
 		self.max_number_of_moves = 9
&lt;span class=&quot;gi&quot;&gt;+		self.result_checker = result_checker
&lt;/span&gt;
 	def is_legal(self, move):
 		move_within_bounds = move &amp;gt; -1 and move &amp;lt; self.max_number_of_moves
&lt;span class=&quot;p&quot;&gt;@@ -69,12 +70,13 @@&lt;/span&gt; def is_draw(self):
 		return len(self.moves_played_so_far) is self.max_number_of_moves

 	def is_win_for_player_one(self):
&lt;span class=&quot;gd&quot;&gt;-		return self._is_win(self._player_one_moves())
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+		return self.result_checker.is_win(self._player_one_moves())
&lt;/span&gt;
 	def _player_one_moves(self):
 		return set(self.moves_played_so_far[0::2])

-	def _is_win(self, moves):
&lt;span class=&quot;gi&quot;&gt;+class ResultChecker:
+	def is_win(self, moves):
&lt;/span&gt; 		top_row = set([0, 1, 2])
 		middle_row = set([3, 4, 5])
 		bottom_row = set([6, 7, 8])
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;What about when the need for a class comes up that does something different to an existing class, so can’t simply be extracted from it? On &lt;a href=&quot;https://github.com/BillionthMonkey/NoughtsAndCrosses/blob/attempt_002/nac.py&quot;&gt;branch “attempt_002”&lt;/a&gt; we stopped because we saw no immediate way to introduce further classes that we believed were required, the reason being that we could not think of a TDDAIYMI-compliant means to introduce the communication between classes. When we know we want to adopt an MVC design, how do we use TDDAIYMI to help us wire up the Model and View, via the Controller? They have to be able to communicate.&lt;/p&gt;

&lt;p&gt;Fortunately the answer to this one is straightforward, too. Imagine that we have already separately developed the View and Model, and wish to write the Controller (this seems like a sufficiently bottom-up way of doing things, which we feel fits TDDAIYMI). In this case, we can write the tests for the wiring between the Model and View, making them pass within the test methods, as stipulated by the rules. It is fine for us to use the existing Model and View objects in the test methods, as they are already part of the established, tested, codebase. We will then start to be able to extract methods (as per rule 4.1).&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;You want a new method—wait until refactoring time, then… create new (non-test) methods by doing one of these, and in no other way:&lt;/p&gt;

  &lt;ul&gt;
    &lt;li&gt;preferred: do Extract Method on implementation code created as per (3) to create a new method in the test class, or&lt;/li&gt;
    &lt;li&gt;if you must: move implementation code as per (3) into an existing implementation method&lt;/li&gt;
  &lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ultimately, we will arrive at a point where a lot of related methods will be ripe for refactoring into a class (as per rule 4.2 above).&lt;/p&gt;

&lt;h1 id=&quot;rookie-mistakes&quot;&gt;Rookie Mistakes&lt;/h1&gt;

&lt;p&gt;One common error that we made during the exercise was to do a large refactoring in a single step. For example, in &lt;a href=&quot;https://github.com/BillionthMonkey/NoughtsAndCrosses/commit/94daea6de4c96c7d085893e3f5ab701d8f11b779&quot;&gt;94daea6&lt;/a&gt; (below) we jumped straight to the extraction of a method for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;is_legal()&lt;/code&gt; without going through an intermediate step of refactoring the code to look the same in both cases. This would have left us a trivial extract-method refactoring. By doing the whole refactoring in a single step we run the risk of introducing errors, or at the very least having to go back and redo the refactoring when we get it wrong.&lt;/p&gt;

&lt;div class=&quot;language-diff highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gh&quot;&gt;diff --git a/nac.py b/nac.py
index a588486..f24eab8 100644
&lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;--- a/nac.py
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+++ b/nac.py
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@@ -1,8 +1,9 @@&lt;/span&gt;
 def test_legal_move():
&lt;span class=&quot;gd&quot;&gt;-    last_move_was_legal = True
-    assert last_move_was_legal
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+    assert is_legal(1)
&lt;/span&gt;
 def test_move_bounds_lower():
&lt;span class=&quot;gd&quot;&gt;-    move = -1
-    last_move_was_legal = move &amp;gt; 0
-    assert last_move_was_legal is False
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+    assert is_legal(-1) is False
+
+
+def is_legal(move):
+    return move &amp;gt; 0
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The same is sometimes true when making a test pass. For example, in &lt;a href=&quot;https://github.com/BillionthMonkey/NoughtsAndCrosses/commit/29120f5a4ac5a8ebe732c29dbfa1813df7dc0689&quot;&gt;29120f5&lt;/a&gt; (below) the test has carelessly been made to pass outside of the test itself. In this case, we should have first added the extension &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;and move &amp;lt; 9&lt;/code&gt; to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;is_legal()&lt;/code&gt; call and then used a refactoring to move the code into the production code.&lt;/p&gt;

&lt;div class=&quot;language-diff highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gh&quot;&gt;diff --git a/nac.py b/nac.py
index ab6cfcb..ed94fe3 100644
&lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;--- a/nac.py
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+++ b/nac.py
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@@ -12,4 +12,4 @@&lt;/span&gt; def test_move_bounds_upper():


 def is_legal(move):
&lt;span class=&quot;gd&quot;&gt;-    return move &amp;gt;= 0
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+    return move &amp;gt;= 0 and move &amp;lt; 9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We use the correct approach in &lt;a href=&quot;https://github.com/BillionthMonkey/NoughtsAndCrosses/commit/561278216c74d576f9c6e672997bae9c311d77c7&quot;&gt;5612782&lt;/a&gt; later:&lt;/p&gt;

&lt;div class=&quot;language-diff highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gh&quot;&gt;diff --git a/nac.py b/nac.py
index 84b3cc7..9109cfd 100644
&lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;--- a/nac.py
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+++ b/nac.py
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@@ -12,7 +12,7 @@&lt;/span&gt; def test_more_than_complete_top_row_is_win():

 def test_complete_middle_row_is_win():
     moves = [3, 4, 5]
&lt;span class=&quot;gd&quot;&gt;-    assert is_win(moves) is True
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+    assert (is_win(moves) or moves == [3, 4, 5]) is True
&lt;/span&gt;

 def is_win(moves):
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;rule-violations&quot;&gt;Rule Violations&lt;/h1&gt;

&lt;p&gt;One of the most common violations of ‘the rules’ of TDD was to modify the behaviour of code during a ‘refactoring’. This most commonly took the form of moving behaviour into existing methods.&lt;/p&gt;

&lt;p&gt;For example, starting from the &lt;span style=&quot;color: green;&quot;&gt;GREEN&lt;/span&gt; state (&lt;a href=&quot;https://github.com/BillionthMonkey/NoughtsAndCrosses/commit/7940ebb724b878d75a2c6b84202a38991aaa5dd7&quot;&gt;7940ebb&lt;/a&gt;, with the explicit &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;True&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;False&lt;/code&gt; tests added for clarity):&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_illegal_move_is_not_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_different_legal_move_is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;we move directly to the following, in a single ‘refactoring’ (&lt;a href=&quot;https://github.com/BillionthMonkey/NoughtsAndCrosses/commit/ac29b93507fe4dd1367043ffe0d7214b00be3f41&quot;&gt;ac29b93&lt;/a&gt;, again with the explicit &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;True&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;False&lt;/code&gt; tests added for clarity):&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_illegal_move_is_not_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_different_legal_move_is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;What would have been the correct way of going about this change? One possible approach would be to make all of the uses of the method look the same first. Then extract a new method and inline the old one.&lt;/p&gt;

&lt;p&gt;This would look something like the following.  Starting from the same &lt;span style=&quot;color: green;&quot;&gt;GREEN&lt;/span&gt; state as above, we start by changing the assertion in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;test_illegal_move_is_not_legal()&lt;/code&gt; to match the form of that in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;test_different_legal_move_is_legal()&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_illegal_move_is_not_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_different_legal_move_is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The assertion for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;test_illegal_move_is_not_legal()&lt;/code&gt; is clearly still valid.&lt;/p&gt;

&lt;p&gt;We then refactor, step-by-step, staring by renaming the original &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;is_legal()&lt;/code&gt; function:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_illegal_move_is_not_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;original_is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_different_legal_move_is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;original_is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;original_is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;then extracting a new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;is_legal()&lt;/code&gt; function from the two tests:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_illegal_move_is_not_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_different_legal_move_is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;original_is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;original_is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;and finally, inlining the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;original_is_legal()&lt;/code&gt; function:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_illegal_move_is_not_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_different_legal_move_is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The result is the same as the single-step refactoring.&lt;/p&gt;

&lt;p&gt;Another instance where we were a bit aggressive in the refactoring step was in &lt;a href=&quot;https://github.com/BillionthMonkey/NoughtsAndCrosses/commit/b873939af49e97ec69eed930013de18e818affd0&quot;&gt;b873939&lt;/a&gt; (below) where we introduced the use of sets and the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;any&lt;/code&gt; function (which is nice and neat, but does alter the behaviour somewhat).&lt;/p&gt;

&lt;div class=&quot;language-diff highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gh&quot;&gt;diff --git a/nac.py b/nac.py
index c0c00ce..5079bd3 100644
&lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;--- a/nac.py
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+++ b/nac.py
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@@ -17,5 +17,7 @@&lt;/span&gt; def test_complete_middle_row_is_win():

 def is_win(moves):
     top_row = set([0, 1, 2])
&lt;span class=&quot;gd&quot;&gt;-    return set(moves).issuperset(top_row) \
-            or moves == [3, 4, 5]
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+    middle_row = set([3, 4, 5])
+    wins = [top_row,
+            middle_row]
+    return any(set(moves).issuperset(win) for win in wins)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;data-vs-code&quot;&gt;Data vs Code&lt;/h1&gt;

&lt;p&gt;The approach we took to determining whether a position was a win in early attempts took the form of gradually building up example cases of win/not-win conditions and adding to the code that evaluated the position to pass the tests. This often got us into a very repetitive rut with the TDD process, where not much was added to the code, but we couldn’t seem to get off that path, as can be seen below.&lt;/p&gt;

&lt;p&gt;The start of this run of commits is &lt;a href=&quot;https://github.com/BillionthMonkey/NoughtsAndCrosses/commit/63c0795942088d391cd39bf0d3d64c37b433eee3&quot;&gt;63c0795&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;language-diff highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gh&quot;&gt;diff --git a/nac.py b/nac.py
index a444c5e..b0a2ddd 100644
&lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;--- a/nac.py
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+++ b/nac.py
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@@ -25,6 +25,11 @@&lt;/span&gt; def test_not_draw():
 	nac.moves_played_so_far = [ 0, 1, 2, 3, 4, 5, 6, 7 ]
 	assert nac.is_draw() is False

+def test_top_row_filled_is_win():
&lt;span class=&quot;gi&quot;&gt;+	nac = NaughtsAndCrosses()
+	nac.moves_played_so_far = [ 0, 7, 1, 8, 2 ]
+	assert not set([0, 1, 2]).issubset(set(nac.moves_played_so_far[0::2]))
+
&lt;/span&gt;
 class NaughtsAndCrosses:
 	def __init__(self):
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The end of this run of commits is &lt;a href=&quot;https://github.com/BillionthMonkey/NoughtsAndCrosses/commit/bce901b44f23403e722977e3decfd785833aa960&quot;&gt;bce901b&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;language-diff highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gh&quot;&gt;diff --git a/nac.py b/nac.py
index 21c4da1..c54fa7c 100644
&lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;--- a/nac.py
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+++ b/nac.py
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@@ -78,17 +78,14 @@&lt;/span&gt; def is_win_for_player_one(self):
 		top_left_diagonal = set([0, 4, 8])
 		bottom_left_diagonal = set([2, 4, 6])
 		moves = self._player_one_moves()
&lt;span class=&quot;gd&quot;&gt;-		return self._is_win_for_player_one(top_row, moves) \
-			or self._is_win_for_player_one(middle_row, moves) \
-			or self._is_win_for_player_one(bottom_row, moves) \
-			or self._is_win_for_player_one(first_column, moves) \
-			or self._is_win_for_player_one(second_column, moves) \
-			or self._is_win_for_player_one(third_column, moves) \
-			or self._is_win_for_player_one(top_left_diagonal, moves) \
-			or self._is_win_for_player_one(bottom_left_diagonal, moves)
-
-	def _is_win_for_player_one(self, pattern, moves):
-		return pattern.issubset(moves)
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+		return top_row.issubset(moves) \
+			or middle_row.issubset(moves) \
+			or bottom_row.issubset(moves) \
+			or first_column.issubset(moves) \
+			or second_column.issubset(moves) \
+			or third_column.issubset(moves) \
+			or top_left_diagonal.issubset(moves) \
+			or bottom_left_diagonal.issubset(moves)
&lt;/span&gt;
 	def _player_one_moves(self):
 		return set(self.moves_played_so_far[0::2])
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;You can explore the whole run of commits using the &lt;a href=&quot;https://desktop.github.com&quot;&gt;GitHub Desktop app&lt;/a&gt;, or by visiting the page for &lt;a href=&quot;https://github.com/BillionthMonkey/NoughtsAndCrosses/commit/bce901b44f23403e722977e3decfd785833aa960&quot;&gt;bce901b&lt;/a&gt; and following the “parent” link (it will take you backwards through the commits, but still demonstrates the repetitive and fairly content-free nature of the endeavour).&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In later attempts, for example &lt;a href=&quot;https://github.com/BillionthMonkey/NoughtsAndCrosses/blob/attempt_006_tddaiymi_2/nac.py&quot;&gt;in our final run through&lt;/a&gt;, we moved to an approach of having a list of winning conditions as data, and wrote tests to drive a solution that looked to see if the win condition was contained in the list of winning conditions.&lt;/p&gt;

&lt;p&gt;The later approach ends up with a much simpler and more flexible result, which would allow us to change the size of the board almost trivially. This level of flexibility could have been achieved in the algorithmic position evaluation too but would have required many more tests to get to that stage.&lt;/p&gt;

&lt;h1 id=&quot;next-time&quot;&gt;Next Time&lt;/h1&gt;

&lt;p&gt;Next time we will look at a more traditional TDD approach (in a London/Mockist style–as we’re British) to this exercise and see how it compares and contrasts to the TDDAIYMI style of development.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Red. Green. Refactor.</title>
   <link href="http://markwithall.com/programming/2016/03/21/red-green-refactor.html"/>
   <updated>2016-03-21T00:00:00+00:00</updated>
   <id>http://markwithall.com/programming/2016/03/21/red-green-refactor</id>
   <content type="html">&lt;p&gt;&lt;span style=&quot;font-size: 2em; color: #DD0000;&quot;&gt;Red.&lt;/span&gt; &lt;span style=&quot;font-size: 1em; color: #00AA00;&quot;&gt;Green.&lt;/span&gt; &lt;span style=&quot;font-size: 4em; color: #0000DD;&quot;&gt;REFACTOR.&lt;/span&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>TDD As If You Meant It Reviewed (Part III)</title>
   <link href="http://markwithall.com/programming/2015/11/03/test-driven-development-as-if-you-meant-it-reviewed-part-iii.html"/>
   <updated>2015-11-03T00:00:00+00:00</updated>
   <id>http://markwithall.com/programming/2015/11/03/test-driven-development-as-if-you-meant-it-reviewed-part-iii</id>
   <content type="html">&lt;p&gt;This is the third in a short series of articles about Test Driven Development.&lt;/p&gt;

&lt;div class=&quot;seriesNote&quot;&gt;
    &lt;ul&gt;
        
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
                
                &lt;li&gt;Part 1:
                
                    &lt;a href=&quot;/programming/2015/06/09/test-driven-development-as-if-you-meant-it-reviewed-part-i.html&quot;&gt;TDD As If You Meant It Reviewed (Part I)&lt;/a&gt;
                
                &lt;/li&gt;
            
        
            
                
                &lt;li&gt;Part 2:
                
                    &lt;a href=&quot;/programming/2015/07/08/test-driven-development-as-if-you-meant-it-reviewed-part-ii.html&quot;&gt;TDD As If You Meant It Reviewed (Part II)&lt;/a&gt;
                
                &lt;/li&gt;
            
        
            
        
            
                
                &lt;li&gt;Part 3:
                
                    This article
                
                &lt;/li&gt;
            
        
            
        
            
                
                &lt;li&gt;Part 4:
                
                    &lt;a href=&quot;/programming/2016/08/04/test-driven-development-as-if-you-meant-it-reviewed-part-iv.html&quot;&gt;TDD As If You Meant It Reviewed (Part IV)&lt;/a&gt;
                
                &lt;/li&gt;
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
                
                &lt;li&gt;Part 5:
                
                    &lt;a href=&quot;/programming/2017/06/01/test-driven-development-as-if-you-meant-it-reviewed-part-v.html&quot;&gt;TDD As If You Meant It Reviewed (Part V)&lt;/a&gt;
                
                &lt;/li&gt;
            
        
            
        
            
        
            
        
            
        
            
        
    &lt;/ul&gt;
&lt;/div&gt;

&lt;p&gt;This article was written with and is &lt;a href=&quot;http://matatk.agrip.org.uk/articles/test-driven-development-as-if-you-meant-it-reviewed-part-3/&quot;&gt;also published by&lt;/a&gt; Matthew Atkinson.&lt;/p&gt;

&lt;p&gt;Having done a few practice attempts at TDDAIYMI, it’s clear that the hardest part is writing the first test. Unlike a more traditional approach to TDD, you can’t leverage the ability to assume the existence of classes and methods to write the test; and then implement them to make it pass. This can lead to some rather contrived test failures.&lt;/p&gt;

&lt;h1 id=&quot;the-starting-commits&quot;&gt;The Starting Commits&lt;/h1&gt;

&lt;p&gt;To illustrate the challenges of starting with TDDAIYMI, we are going to go through the first few of our &lt;span style=&quot;color: red;&quot;&gt;RED&lt;/span&gt;-&lt;span style=&quot;color: green;&quot;&gt;GREEN&lt;/span&gt;-&lt;span style=&quot;color: blue;&quot;&gt;REFACTOR&lt;/span&gt; cycles step-by-step and explain in detail our thought process at each stage.  We’ve included timestamps for the commits to make it easy to see how long each step took.  These commits form part of the flamboyantly-named &lt;a href=&quot;https://github.com/BillionthMonkey/NoughtsAndCrosses/tree/attempt_006_tddaiymi_2&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;attempt_006_tddaiymi_2&lt;/code&gt; branch on GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Each commit is presented, followed by the commentary on it.&lt;/p&gt;

&lt;h2 style=&quot;color: red&quot; id=&quot;red-test-that-a-legal-move-is-legal---2015-02-19-1325&quot;&gt;RED Test that a legal move is legal - 2015-02-19 13:25&lt;/h2&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_legal_move_is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As mentioned &lt;a href=&quot;/programming/2015/07/08/test-driven-development-as-if-you-meant-it-reviewed-part-ii.html&quot;&gt;last time&lt;/a&gt;, we are going to be tackling the problem of noughts and crosses (tic-tac-toe). We decided, somewhat arbitrarily, to start with a method to check the legality of a move. It seems more natural to approach TDDAIYMI in a bottom-up, as opposed to a top-down, manner.&lt;/p&gt;

&lt;p&gt;We have decided to use a numeric position for the move. What that exactly means will be determined by the tests we write (the idea being that there are nine squares, which we will identify as 0 to 8 – interestingly, and as was discussed in &lt;a href=&quot;http://www.infoq.com/presentations/TDD-as-if-You-Meant-It&quot;&gt;Keith Braithwaite’s workshop&lt;/a&gt;, this means there is no notion of ‘a board’ specifically).&lt;/p&gt;

&lt;p&gt;Our first test is somewhat contrived due to the restrictions of the process. One could argue that the inclusion of the move variable is taking things a step too far and that the initial test should have been &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;assert 0 &amp;gt; 0&lt;/code&gt; followed by using the &lt;a href=&quot;http://refactoring.com/catalog/extractVariable.html&quot;&gt;Extract Variable&lt;/a&gt; refactoring to get to the current state, after having made the test pass.&lt;/p&gt;

&lt;h2 style=&quot;color: green&quot; id=&quot;green---2015-03-02-1309&quot;&gt;GREEN - 2015-03-02 13:09&lt;/h2&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_legal_move_is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# changed
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Making the test pass is trivial; as, of course, it should be. We change the contrived ‘less than’ test to use an equals comparison. As we only have the one test, there is no duplication to refactor, so we move straight onto the next test.&lt;/p&gt;

&lt;h2 style=&quot;color: red&quot; id=&quot;red-test-that-an-illegal-move-is-not-legal---2015-03-02-1320&quot;&gt;RED Test that an illegal move is not legal - 2015-03-02 13:20&lt;/h2&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_legal_move_is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# added function
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_illegal_move_is_not_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We are essentially starting from scratch again with test number 2. That said, we want to try and keep going in the same direction to triangulate some behaviour to extract in the form of duplicate code.&lt;/p&gt;

&lt;p&gt;We have settled on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;move == 0&lt;/code&gt; being the standard test for legality, so we now want to use the same test, when presented with an invalid move. This will take us a step closer to being able to remove duplication via &lt;a href=&quot;http://refactoring.com/catalog/extractMethod.html&quot;&gt;Extract Method&lt;/a&gt; in future.&lt;/p&gt;

&lt;h2 style=&quot;color: green&quot; id=&quot;green---2015-03-02-1325&quot;&gt;GREEN - 2015-03-02 13:25&lt;/h2&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_legal_move_is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_illegal_move_is_not_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# changed
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note that the GREEN step is supposed to take the least-complex means to make the tests pass – it is the tests, not their solutions, that are intended to direct the overall design of the code. This is why, in this case, the GREEN step does seem rather simplistic. Arguably, we should have changed the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;==&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;!=&lt;/code&gt; to make the test pass. By making the test pass in this way, we are introducing some duplication that needs addressing and moves us nearer to our goal.&lt;/p&gt;

&lt;h2 style=&quot;color: blue&quot; id=&quot;refactor-extract-is_legal-function---2015-03-02-1328&quot;&gt;REFACTOR Extract &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;is_legal&lt;/code&gt; function - 2015-03-02 13:28&lt;/h2&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_legal_move_is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# changed
&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_illegal_move_is_not_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# changed
&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# added function
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This REFACTOR step may seem somewhat ‘aggressive’, in the sense that it lengthens the code, but it’s also vital (for any form of TDD) to refactor as early as possible, in order to keep the code – and any emerging avenues for good design – as ‘clean’ as possible. In this case, we had a DRY violation, which needed to be fixed; introducing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;is_legal()&lt;/code&gt; solves that problem, and starts giving some structure to the code. Using the tests to come at problems from both sides, in a sort of pincer strategy, can enable us to tease out structure such as this, and is a technique we used often.&lt;/p&gt;

&lt;h2 style=&quot;color: red&quot; id=&quot;red-test-a-different-legal-move---2015-03-03-1240&quot;&gt;RED Test a different legal move - 2015-03-03 12:40&lt;/h2&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_legal_move_is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_illegal_move_is_not_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;


&lt;span class=&quot;c1&quot;&gt;# added function
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_different_legal_move_is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We need to expand the range of legal moves. We start by testing the highest legal value. Of course, there are many possible moves in the game and, whilst we’d not want to test all of them separately, we do need to add at least one more in order to pin down the range of valid moves – think of it along the lines of needing at least three points in order to be reasonably confident you can draw a meaningful line through them.&lt;/p&gt;

&lt;h2 style=&quot;color: green&quot; id=&quot;green---2015-03-03-1248&quot;&gt;GREEN - 2015-03-03 12:48&lt;/h2&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_legal_move_is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_illegal_move_is_not_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_different_legal_move_is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# changed
&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We make this test pass, &lt;strong&gt;in the test method&lt;/strong&gt;, and by &lt;strong&gt;using the simplest possible means&lt;/strong&gt; which, again, may seem somewhat insufficient at first glance.  We can use refactoring to improve the design. For some reason we changed our test case to ‘1’ instead of ‘8’ at this point; which was rather naughty.&lt;/p&gt;

&lt;h2 style=&quot;color: blue&quot; id=&quot;refactor-improve-design-by-moving-code---2015-03-03-1250&quot;&gt;REFACTOR Improve design by moving code - 2015-03-03 12:50&lt;/h2&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_legal_move_is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_illegal_move_is_not_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_different_legal_move_is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# changed
&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# changed
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Next, for the first time, we have a few consecutive refactorings, and thus make two separate REFACTOR commits. In the first, we move the extra legality check to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;is_legal()&lt;/code&gt; function, which is allowed per the rules, as it ‘improves the design of the code’ and the rules allow us to move code from a test function to an existing function. This is not strictly a refactoring, as it changes the behaviour of the code (whereas refactoring should preserve behaviour). However, the tests all still pass and this has given us a way to improve the design.&lt;/p&gt;

&lt;h2 style=&quot;color: blue&quot; id=&quot;refactor-simplify-expression---2015-03-03-1252&quot;&gt;REFACTOR Simplify expression - 2015-03-03 12:52&lt;/h2&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_legal_move_is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_illegal_move_is_not_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_different_legal_move_is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# changed
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now we are able to simplify the legality check, because all of the code is together…&lt;/p&gt;

&lt;h2 style=&quot;color: blue&quot; id=&quot;refactor-explicitly-state-expected-result-of-tests---2015-03-03-1253&quot;&gt;REFACTOR Explicitly state expected result of tests - 2015-03-03 12:53&lt;/h2&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_legal_move_is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# changed
&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_illegal_move_is_not_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_different_legal_move_is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# changed
&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;At this point, we realised that, as per &lt;a href=&quot;https://www.python.org/dev/peps/pep-0020/&quot;&gt;The Zen of Python&lt;/a&gt; and in the interests of making it easy to read and understand the tests, ‘explicit is better than implicit’ – we had not been clearly stating what we expected the results of the tests to be, so we add the cases where we want a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;True&lt;/code&gt; result.&lt;/p&gt;

&lt;h2 style=&quot;color: red&quot; id=&quot;red-test-the-first-illegal-move-on-upper-boundary---2015-03-03-1255&quot;&gt;RED Test the first illegal move on upper boundary - 2015-03-03 12:55&lt;/h2&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_legal_move_is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_illegal_move_is_not_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_different_legal_move_is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;


&lt;span class=&quot;c1&quot;&gt;# added function
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_high_illegal_move_is_not_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The next logical failing test we can write is to use an illegal move at the other end of the range. When we are no longer able to write a failing test, we know we are done. (Note that if we wrote a test for checking a move of ‘8’ was legal, it would pass, so it doesn’t need to be written.)&lt;/p&gt;

&lt;h2 style=&quot;color: green&quot; id=&quot;green---2015-03-03-1258&quot;&gt;GREEN - 2015-03-03 12:58&lt;/h2&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_legal_move_is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_illegal_move_is_not_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_different_legal_move_is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_high_illegal_move_is_not_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# changed
&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Again, making the test pass is done in the test method itself, using the simplest code.&lt;/p&gt;

&lt;h2 style=&quot;color: blue&quot; id=&quot;refactor-improve-design-by-moving-code---2015-03-03-1305&quot;&gt;REFACTOR Improve design by moving code - 2015-03-03 13:05&lt;/h2&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_legal_move_is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_illegal_move_is_not_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_different_legal_move_is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_high_illegal_move_is_not_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# changed
&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# changed
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We refactor to improve the design by moving the extra code to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;is_legal()&lt;/code&gt; method. The tests are run automatically after each change we make, so we know if we have broken anything. Once again, this is a pseudo-refactoring as, whilst it doesn’t change the stated (tested) behaviour of the overall program, it does change the behaviour of the function.&lt;/p&gt;

&lt;h2 style=&quot;color: red&quot; id=&quot;red-test-previously-played-move-is-illegal---2015-03-04-1239&quot;&gt;RED Test previously-played move is illegal - 2015-03-04 12:39&lt;/h2&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_legal_move_is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_illegal_move_is_not_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_different_legal_move_is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_high_illegal_move_is_not_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;


&lt;span class=&quot;c1&quot;&gt;# added function
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_move_is_illegal_if_already_played&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;moves_played&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We have now run out of the basic failing tests that we can think of for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;is_legal()&lt;/code&gt; method. We move on to expand its behaviour by considering moves that have been played previously to be illegal. Again, this is somewhat contrived as we are inventing some state that we aren’t initially using in the test.&lt;/p&gt;

&lt;p&gt;This direction of exploration seems like the most natural extension of the existing test sequence. We are not attempting to force any sort of design; we are just writing tests and will see what ‘design’ emerges.&lt;/p&gt;

&lt;h2 style=&quot;color: green&quot; id=&quot;green---2015-03-04-1244&quot;&gt;GREEN - 2015-03-04 12:44&lt;/h2&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_legal_move_is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_illegal_move_is_not_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_different_legal_move_is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_high_illegal_move_is_not_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_move_is_illegal_if_already_played&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;moves_played&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;moves_played&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# changed
&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We now use the state information to make the test pass in the test method.&lt;/p&gt;

&lt;h2 style=&quot;color: blue&quot; id=&quot;refactor-introduce-parameter---2015-03-04-1256&quot;&gt;REFACTOR Introduce Parameter - 2015-03-04 12:56&lt;/h2&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_legal_move_is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[])&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# changed
&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_illegal_move_is_not_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[])&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# changed
&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_different_legal_move_is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[])&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# changed
&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_high_illegal_move_is_not_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[])&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# changed
&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_move_is_illegal_if_already_played&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;moves_played&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;moves_played&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;moves_played&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;moves_played&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# changed
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We want to improve the design of the code by moving the new code that made the test pass to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;is_legal()&lt;/code&gt; method but to do this we need to pass the state in too. We proceed cautiously and do this refactoring in a couple of steps.  First we add the extra parameter to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;is_legal()&lt;/code&gt; method (which requires us to update all the other tests that use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;is_legal()&lt;/code&gt;).&lt;/p&gt;

&lt;h2 style=&quot;color: blue&quot; id=&quot;refactor-move-history-checking-code-to-is_legal---2015-03-04-1259&quot;&gt;REFACTOR Move history-checking code to is_legal() - 2015-03-04 12:59&lt;/h2&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_legal_move_is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[])&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_illegal_move_is_not_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[])&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_different_legal_move_is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[])&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_high_illegal_move_is_not_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[])&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_move_is_illegal_if_already_played&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;moves_played&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;moves_played&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# changed
&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;is_legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;moves_played&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;move&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;moves_played&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# changed
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now that we have passed in the parameter, we can move the extra check into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;is_legal()&lt;/code&gt; and make sure that all of the tests still pass, which they do.&lt;/p&gt;

&lt;h1 id=&quot;next-time&quot;&gt;Next Time&lt;/h1&gt;

&lt;p&gt;We could continue on but this gives sufficient flavour of the thought process as we worked our way through the exercise. The rest of the development continues in the same manner; looping through the &lt;span style=&quot;color: red;&quot;&gt;RED&lt;/span&gt;-&lt;span style=&quot;color: green;&quot;&gt;GREEN&lt;/span&gt;-&lt;span style=&quot;color: blue;&quot;&gt;REFACTOR&lt;/span&gt; cycle. In the next article in the series we shall pick out some interesting moments from the rest of the development and discuss them.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Blurry Rotated Text In WPF</title>
   <link href="http://markwithall.com/programming/2015/07/31/blurry-rotated-text-in-wpf.html"/>
   <updated>2015-07-31T00:00:00+00:00</updated>
   <id>http://markwithall.com/programming/2015/07/31/blurry-rotated-text-in-wpf</id>
   <content type="html">&lt;p&gt;Just a short little post today, as I’m going to forget this if I don’t write it down somewhere.&lt;/p&gt;

&lt;p&gt;Sometimes when you transform text in WPF it ends up rendering blurred at runtime.  Annoyingly, it will quite often appear fine in Visual Studio’s designer.  Take, for example, the following expander header.&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;Expander.Header&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;TextBlock&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Text=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Running Dates&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;TextBlock.LayoutTransform&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;RotateTransform&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Angle=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;-90&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;/TextBlock.LayoutTransform&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/TextBlock&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/Expander.Header&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It looks fine in the designer&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/blurry_designer.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;but at runtime it goes blurry&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/blurry_blurry.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Adding &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/system.windows.media.textoptions.textformattingmode(v=vs.100).aspx&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TextOptions.TextFormattingMode&lt;/code&gt;&lt;/a&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=&quot;&lt;/code&gt;&lt;a href=&quot;https://msdn.microsoft.com/en-us/library/system.windows.media.textformattingmode(v=vs.100).aspx&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Display&lt;/code&gt;&lt;/a&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;&lt;/code&gt; to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TextBlock&lt;/code&gt; fixes this by using GDI-compatible font metrics.&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;Expander.Header&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;TextBlock&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Text=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Running Dates&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;TextOptions.TextFormattingMode=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Display&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;TextBlock.LayoutTransform&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;RotateTransform&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Angle=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;-90&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;/TextBlock.LayoutTransform&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/TextBlock&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/Expander.Header&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now it looks much better at runtime.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/blurry_fixed.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;It’s also worth looking at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SnapsToDevicePixels&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UseLayoutRounding&lt;/code&gt; for similar issues that don’t involve text.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>TDD As If You Meant It Reviewed (Part II)</title>
   <link href="http://markwithall.com/programming/2015/07/08/test-driven-development-as-if-you-meant-it-reviewed-part-ii.html"/>
   <updated>2015-07-08T00:00:00+00:00</updated>
   <id>http://markwithall.com/programming/2015/07/08/test-driven-development-as-if-you-meant-it-reviewed-part-ii</id>
   <content type="html">&lt;p&gt;This is the second in a short series of articles about Test Driven Development.&lt;/p&gt;

&lt;div class=&quot;seriesNote&quot;&gt;
    &lt;ul&gt;
        
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
                
                &lt;li&gt;Part 1:
                
                    &lt;a href=&quot;/programming/2015/06/09/test-driven-development-as-if-you-meant-it-reviewed-part-i.html&quot;&gt;TDD As If You Meant It Reviewed (Part I)&lt;/a&gt;
                
                &lt;/li&gt;
            
        
            
                
                &lt;li&gt;Part 2:
                
                    This article
                
                &lt;/li&gt;
            
        
            
        
            
                
                &lt;li&gt;Part 3:
                
                    &lt;a href=&quot;/programming/2015/11/03/test-driven-development-as-if-you-meant-it-reviewed-part-iii.html&quot;&gt;TDD As If You Meant It Reviewed (Part III)&lt;/a&gt;
                
                &lt;/li&gt;
            
        
            
        
            
                
                &lt;li&gt;Part 4:
                
                    &lt;a href=&quot;/programming/2016/08/04/test-driven-development-as-if-you-meant-it-reviewed-part-iv.html&quot;&gt;TDD As If You Meant It Reviewed (Part IV)&lt;/a&gt;
                
                &lt;/li&gt;
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
                
                &lt;li&gt;Part 5:
                
                    &lt;a href=&quot;/programming/2017/06/01/test-driven-development-as-if-you-meant-it-reviewed-part-v.html&quot;&gt;TDD As If You Meant It Reviewed (Part V)&lt;/a&gt;
                
                &lt;/li&gt;
            
        
            
        
            
        
            
        
            
        
            
        
    &lt;/ul&gt;
&lt;/div&gt;

&lt;p&gt;This article was written with and is &lt;a href=&quot;http://matatk.agrip.org.uk/articles/test-driven-development-as-if-you-meant-it-reviewed-part-2/&quot;&gt;also published by&lt;/a&gt; Matthew Atkinson.&lt;/p&gt;

&lt;h1 id=&quot;part-ii-the-problem&quot;&gt;Part II: The Problem&lt;/h1&gt;

&lt;h2 id=&quot;the-problem-noughts-and-crosses-tic-tac-toe-in-american&quot;&gt;The Problem: Noughts And Crosses (Tic-Tac-Toe in American)&lt;/h2&gt;

&lt;p&gt;In &lt;a href=&quot;https://twitter.com/keithb_b&quot;&gt;Keith Braithwaite’s&lt;/a&gt; original exercise, the problem tackled was &lt;a href=&quot;https://en.wikipedia.org/wiki/Tic-tac-toe&quot;&gt;Noughts and Crosses&lt;/a&gt;.  To allow us to compare with other attempts out on the Internet, we are going to tackle the same problem.  We intentionally didn’t fully define the problem in advance; except to focus on the game management aspects, rather than any AI components.&lt;/p&gt;

&lt;h2 id=&quot;languagelibrary-choices&quot;&gt;Language/Library Choices&lt;/h2&gt;

&lt;p&gt;We decided to do the exercise in Python (2.7), as it was the language with which we had the highest average skill level.  We used &lt;a href=&quot;http://pytest.org/latest/&quot;&gt;pytest&lt;/a&gt; and &lt;a href=&quot;https://pypi.python.org/pypi/mock&quot;&gt;mock&lt;/a&gt; for testing and &lt;a href=&quot;https://pypi.python.org/pypi/pytest-xdist&quot;&gt;pytest-xdist&lt;/a&gt; to allow the test to run continuously in the background and keep us honest.&lt;/p&gt;

&lt;p&gt;Code was written in Vim (because, y’know, it’s better than [REDACTED], etc.).  &lt;a href=&quot;https://github.com/Valloric/YouCompleteMe&quot;&gt;YouCompleteMe&lt;/a&gt; and &lt;a href=&quot;https://github.com/scrooloose/syntastic&quot;&gt;syntastic&lt;/a&gt; were used for autocompletion and static analysis to speed things along.  We did try the &lt;a href=&quot;https://github.com/python-rope/ropevim&quot;&gt;rope refactoring tools&lt;/a&gt; briefly but they aren’t currently robust enough.  We must take some time to look at some of the issues we had at some point to help get it up to scratch; as life isn’t worth living without refactoring tools.&lt;/p&gt;

&lt;p&gt;The whole was wrapped up in &lt;a href=&quot;https://virtualenv.pypa.io&quot;&gt;virtualenv&lt;/a&gt; to make it easy to get up and running with a standard environment.&lt;/p&gt;

&lt;h2 id=&quot;methodology&quot;&gt;Methodology&lt;/h2&gt;

&lt;p&gt;We started with some TDDAIYMI ‘dry runs’ to get the hang of using this technique as, whilst it seems very-much like TDD on paper, it ‘feels’ quite different to use it.  We then carried out our ‘control’ exercise of ‘traditional’ TDD and finally followed this up with a serious go at the problem in TDDAIYMI style.&lt;/p&gt;

&lt;p&gt;For the experiment, we decided to commit after each stage of the &lt;span style=&quot;color: red;&quot;&gt;RED&lt;/span&gt;-&lt;span style=&quot;color: green;&quot;&gt;GREEN&lt;/span&gt;-&lt;span style=&quot;color: blue;&quot;&gt;REFACTOR&lt;/span&gt; cycle, to allow the easiest replay of what happened.  In real life, we probably wouldn’t choose the commit after a RED stage, to keep the repository in a working state as far as possible (e.g. to allow binary search of the history).&lt;/p&gt;

&lt;p&gt;During the exercises we were looking out for:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Similarities between the two approaches&lt;/li&gt;
  &lt;li&gt;What worked with TDDAIYMI&lt;/li&gt;
  &lt;li&gt;What didn’t seem to work&lt;/li&gt;
  &lt;li&gt;How we feel TDDAIYMI might be improved&lt;/li&gt;
  &lt;li&gt;General lessons learnt&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;next-time&quot;&gt;Next Time&lt;/h2&gt;

&lt;p&gt;We finally get the f*** on with it.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>TDD As If You Meant It Reviewed (Part I)</title>
   <link href="http://markwithall.com/programming/2015/06/09/test-driven-development-as-if-you-meant-it-reviewed-part-i.html"/>
   <updated>2015-06-09T00:00:00+00:00</updated>
   <id>http://markwithall.com/programming/2015/06/09/test-driven-development-as-if-you-meant-it-reviewed-part-i</id>
   <content type="html">&lt;p&gt;This is the first in a short series of articles about Test Driven Development.&lt;/p&gt;

&lt;div class=&quot;seriesNote&quot;&gt;
    &lt;ul&gt;
        
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
                
                &lt;li&gt;Part 1:
                
                    This article
                
                &lt;/li&gt;
            
        
            
                
                &lt;li&gt;Part 2:
                
                    &lt;a href=&quot;/programming/2015/07/08/test-driven-development-as-if-you-meant-it-reviewed-part-ii.html&quot;&gt;TDD As If You Meant It Reviewed (Part II)&lt;/a&gt;
                
                &lt;/li&gt;
            
        
            
        
            
                
                &lt;li&gt;Part 3:
                
                    &lt;a href=&quot;/programming/2015/11/03/test-driven-development-as-if-you-meant-it-reviewed-part-iii.html&quot;&gt;TDD As If You Meant It Reviewed (Part III)&lt;/a&gt;
                
                &lt;/li&gt;
            
        
            
        
            
                
                &lt;li&gt;Part 4:
                
                    &lt;a href=&quot;/programming/2016/08/04/test-driven-development-as-if-you-meant-it-reviewed-part-iv.html&quot;&gt;TDD As If You Meant It Reviewed (Part IV)&lt;/a&gt;
                
                &lt;/li&gt;
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
                
                &lt;li&gt;Part 5:
                
                    &lt;a href=&quot;/programming/2017/06/01/test-driven-development-as-if-you-meant-it-reviewed-part-v.html&quot;&gt;TDD As If You Meant It Reviewed (Part V)&lt;/a&gt;
                
                &lt;/li&gt;
            
        
            
        
            
        
            
        
            
        
            
        
    &lt;/ul&gt;
&lt;/div&gt;

&lt;p&gt;This article was written with and is &lt;a href=&quot;http://matatk.agrip.org.uk/articles/test-driven-development-as-if-you-meant-it-reviewed-part-1/&quot;&gt;also published by&lt;/a&gt; Matthew Atkinson.&lt;/p&gt;

&lt;h1 id=&quot;part-i-introduction&quot;&gt;Part I: Introduction&lt;/h1&gt;

&lt;p&gt;Writing &lt;a href=&quot;http://www.diveintopython.net/unit_testing/stage_1.html&quot;&gt;tests before you write any code&lt;/a&gt; is awesome. It means that you can rely on the code you’ve written to work (most of the time) and you can &lt;a href=&quot;http://www.diveintopython.net/refactoring/&quot;&gt;refactor with wild abandon, for example to improve performance&lt;/a&gt;, because it’s trivial to re-run the tests to check the code still behaves itself. However, as with pretty-much everything else, there are many ways to actually &lt;em&gt;do&lt;/em&gt; Test Driven Development (or TDD, as most refer to it), two of which we explored in detail.&lt;/p&gt;

&lt;p&gt;In general, the idea is that you write a test, write some code to make the test pass and then refactor (i.e. to remove duplication and otherwise improve the code’s design), before moving on to the next test. Thus, there are three stages, which are usually referred to by ‘colour’…&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;&lt;span style=&quot;color: red;&quot;&gt;RED&lt;/span&gt;&lt;/strong&gt; - Write a failing test&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;span style=&quot;color: green;&quot;&gt;GREEN&lt;/span&gt;&lt;/strong&gt; - Make the test pass&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;span style=&quot;color: blue;&quot;&gt;REFACTOR&lt;/span&gt;&lt;/strong&gt; - Improve the design of the code without changing the behaviour&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;span style=&quot;background: blue; color: lightblue;&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GOTO 10&lt;/code&gt;&lt;/span&gt;&lt;/strong&gt; (i.e. repeat the above, for the next test)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In most of its forms, TDD is not a substitute for a certain amount of up-front design (though it certainly helps, as it discourages writing unnecessary code) – it’s expected that you have a good overall idea of
where you’re going architecturally, e.g. that you’d have a Model, View and Controller, perhaps. You also need to decide the &lt;em&gt;granularity&lt;/em&gt; of your red-green-refactor cycles – is a ‘red’ commit an entire test, or
does it only go up to a compilation failure (e.g. where you may need to introduce a mock to take the place of a model, controller or other object – we’ll see examples of this later). There’s a lot of variation
and different views on these sorts of things.&lt;/p&gt;

&lt;p&gt;A more pedantic flavour of TDD has been proposed that caught our attention, so we had to give it a go…&lt;/p&gt;

&lt;h2 id=&quot;what-is-tddaiymi&quot;&gt;What Is TDDAIYMI?&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;http://cumulative-hypotheses.org/2011/08/30/tdd-as-if-you-meant-it/&quot;&gt;Test Driven Development As If You Meant It (TDDAIYMI)&lt;/a&gt; is a TDD workshop exercise devised by &lt;a href=&quot;https://twitter.com/keithb_b&quot;&gt;Keith Braithwaite&lt;/a&gt;. It was first presented at &lt;a href=&quot;http://www.codemanship.co.uk/softwarecraftsmanship/&quot;&gt;Software Craftsmanship 2009&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The exercise aims to apply TDD in the most pedantic way possible; to stretch one’s programming muscles. It is not intended that this extreme approach is used on a daily basis, for real-world programming tasks.&lt;/p&gt;

&lt;p&gt;TTDAIYMI takes the form of a re-phrasing of the standard TDD steps, as follows (taken from the original article, see above).&lt;/p&gt;

&lt;h3 id=&quot;the-rules&quot;&gt;The Rules&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;Write exactly one new test, the smallest test you can that seems to point in the direction of a solution&lt;/li&gt;
  &lt;li&gt;See it fail&lt;/li&gt;
  &lt;li&gt;Make the test from (1) pass by writing the least implementation code you can &lt;strong&gt;in the test method&lt;/strong&gt;.&lt;/li&gt;
  &lt;li&gt;Refactor to remove duplication, and otherwise as required to improve the design. Be strict about using these moves:
    &lt;ol&gt;
      &lt;li&gt;&lt;strong&gt;you want a new method – wait until refactoring time, then…&lt;/strong&gt; create new (non-test) methods by doing one of these, and in no other way:
        &lt;ol&gt;
          &lt;li&gt;preferred: do Extract Method on implementation code created as per (3) to create a new method in the test class, or&lt;/li&gt;
          &lt;li&gt;if you must: move implementation code as per (3) into an existing implementation method&lt;/li&gt;
        &lt;/ol&gt;
      &lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;you want a new class – wait until refactoring time, then…&lt;/strong&gt; create non-test classes to provide a destination for a Move Method and for no other reason
        &lt;ol&gt;
          &lt;li&gt;populate implementation classes with methods by doing Move Method, and no other way&lt;/li&gt;
        &lt;/ol&gt;
      &lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;how-does-it-differ-from-normal-tdd&quot;&gt;How Does It Differ From ‘Normal’ TDD?&lt;/h2&gt;

&lt;p&gt;There are many approaches to TDD but, for our comparison, let us take Uncle Bob’s ‘Three Laws’ approach.&lt;/p&gt;

&lt;h3 id=&quot;the-three-laws-of-tdd&quot;&gt;The Three Laws Of TDD&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://twitter.com/unclebobmartin&quot;&gt;‘Uncle’ Bob Martin&lt;/a&gt;, in his article on the &lt;a href=&quot;http://butunclebob.com/ArticleS.UncleBob.TheThreeRulesOfTdd&quot;&gt;Three Laws of TDD&lt;/a&gt;, clarifies the &lt;span style=&quot;color: red;&quot;&gt;RED&lt;/span&gt;-&lt;span style=&quot;color: green;&quot;&gt;GREEN&lt;/span&gt;-&lt;span style=&quot;color: blue;&quot;&gt;REFACTOR&lt;/span&gt; process with some restrictions upon how to follow the steps. These clarifications are as follows:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;You are not allowed to write any production code unless it is to make a failing unit test pass.&lt;/li&gt;
  &lt;li&gt;You are not allowed to write any more of a unit test than is sufficient to fail; and compilation failures are failures.&lt;/li&gt;
  &lt;li&gt;You are not allowed to write any more production code than is sufficient to pass the one failing unit test.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is already quite similar to TDDAIYMI but with the added flexibility to infer the existence of production code (or at least interfaces/protocols that other production code might implement); in fact, in some ways it actively encourages it by allowing you to break up the creation of a single test into multiple &lt;span style=&quot;color: red;&quot;&gt;RED&lt;/span&gt;-&lt;span style=&quot;color: green;&quot;&gt;GREEN&lt;/span&gt;-&lt;span style=&quot;color: blue;&quot;&gt;REFACTOR&lt;/span&gt; steps, creating little bit of missing production code as you go.&lt;/p&gt;

&lt;h2 id=&quot;next-time&quot;&gt;Next Time&lt;/h2&gt;

&lt;p&gt;In the rest of this series we are going to write about our experiences of trying out TDDAIYMI on a small project and then comparing it to a more traditional TDD approach tackling the same problem.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Fluent APIs And The Law Of Demeter</title>
   <link href="http://markwithall.com/programming/2015/05/03/fluent-apis-and-the-law-of-demeter.html"/>
   <updated>2015-05-03T00:00:00+00:00</updated>
   <id>http://markwithall.com/programming/2015/05/03/fluent-apis-and-the-law-of-demeter</id>
   <content type="html">&lt;p&gt;In object oriented programming the &lt;a href=&quot;http://en.wikipedia.org/wiki/Law_of_Demeter&quot;&gt;Law of Demeter&lt;/a&gt; states that a class shouldn’t reach through associated classes into the details of other classes beyond.  This is often stated as “use only one dot”.  This formulation, on the face of it, seems to have worrying implications for the use of &lt;a href=&quot;http://en.wikipedia.org/wiki/Fluent_interface&quot;&gt;fluent APIs&lt;/a&gt;, such as &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/bb397926.aspx&quot;&gt;.NET LINQ&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Below is a simple example with two levels.  The first represents a train and the second the details of each stop that the train makes.  The Law of Demeter says that if we are playing with trains, we shouldn’t be able to see the details of stops, i.e. something that has a train, shouldn’t look at departure times.
I&lt;/p&gt;
&lt;h2 id=&quot;first-level-interface&quot;&gt;First Level Interface&lt;/h2&gt;

&lt;div class=&quot;language-c# highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ITrain&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Id&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;IEnumerable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IStop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Stops&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;second-level-interface&quot;&gt;Second Level Interface&lt;/h2&gt;

&lt;div class=&quot;language-c# highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;IStop&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;TimeSpan&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DepartureTime&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;TimeSpan&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ArrivalTime&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here are two example methods that take a list of trains and use LINQ to filter them in some manner.  Both return a list of stops but the first complies with the Law of Demeter and the second does not.&lt;/p&gt;

&lt;h2 id=&quot;legal-usage&quot;&gt;Legal Usage&lt;/h2&gt;

&lt;div class=&quot;language-c# highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IEnumerable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IStop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Legal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IEnumerable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ITrain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;trains&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;trains&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Where&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Id&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;OrderBy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Select&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Stops&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;First&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Whilst there are many dots used in the above code, nothing reaches through the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ITrain&lt;/code&gt; interface and into the details of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IStop&lt;/code&gt; interface.  Hence, the Law of Demeter is complied with.&lt;/p&gt;

&lt;h2 id=&quot;illegal-usage&quot;&gt;Illegal Usage&lt;/h2&gt;

&lt;div class=&quot;language-c# highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IEnumerable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IStop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Illegal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IEnumerable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ITrain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;trains&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Select&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Stops&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;First&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;OrderBy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stop&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DepartureTime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here there are in fact fewer dots used than in the legal example above.  However, we are reaching through into the details of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IStop&lt;/code&gt; interface (accessing the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DepartureTime&lt;/code&gt; property that the Law of Demeter says we shouldn’t know about).&lt;/p&gt;

&lt;p&gt;As we have shown above, it is perfectly possible to comply with the Law of Demeter whilst using fluent APIs but it is necessary to be careful when doing so.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Blogging (hopefully) 2015</title>
   <link href="http://markwithall.com/programming/2015/03/06/blogging-hopefully-2015.html"/>
   <updated>2015-03-06T00:00:00+00:00</updated>
   <id>http://markwithall.com/programming/2015/03/06/blogging-hopefully-2015</id>
   <content type="html">&lt;p&gt;A somewhat late first article this year; as it’s just turned March.  To continue the trend from last year, I’m starting with a review and forecast.  Last year: seven out of twelve.  Not as good as the nine out of twelve for 2013 but not a complete disaster.  As usual, however, nearly all of the articles were written in the first half of the year.  This year, I’m still keeping the twelve article target and will try harder to get more in the second half.&lt;/p&gt;

&lt;p&gt;I was happy with the articles I did write.  In particular, I enjoyed my investigation into implementing &lt;a href=&quot;/programming/2014/06/20/undo-redo.html&quot;&gt;Undo/Redo&lt;/a&gt;; an area which has always been rather a mystery to me.  I had plenty to write about during the year but I failed to take advantage of all of the opportunities.&lt;/p&gt;

&lt;p&gt;I already have a few articles in the works, for this year, that should give me a bit of a head start; including an exciting collaboration with &lt;a href=&quot;http://matatk.agrip.org.uk&quot;&gt;Matthew Tylee Atkinson&lt;/a&gt; on a series of articles about Keith Braithwaite’s &lt;a href=&quot;http://cumulative-hypotheses.org/2011/08/30/tdd-as-if-you-meant-it/&quot;&gt;“TDD As If You Meant It”&lt;/a&gt; exercise.  It would also be a good idea to publish my long overdue full review of BACON 2014 before the 2015 event.&lt;/p&gt;

&lt;p&gt;Here is the list from last year, for reference.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;2014-02-22 - &lt;a href=&quot;/programming/2014/02/22/2013-programming-articles-review.html&quot;&gt;2013 Programming Articles Review&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;2014-03-22 - &lt;a href=&quot;/programming/2014/03/22/to-rebase-or-not-to-rebase.html&quot;&gt;To Rebase Or Not To Rebase?&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;2014-04-18 - &lt;a href=&quot;/programming/2014/04/18/save-all-excel-worksheets-as-tab-separated-text.html&quot;&gt;Save All Excel Worksheets As Tab Separated Text&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;2014-05-02 - &lt;a href=&quot;/programming/2014/05/02/labelled-textbox-in-wpf.html&quot;&gt;Labelled TextBox In WPF&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;2014-05-18 - &lt;a href=&quot;/programming/2014/05/18/such-coffee-many-caffeine-wow.html&quot;&gt;Such Coffee, Many Caffeine, Wow!&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;2014-06-20 - &lt;a href=&quot;/programming/2014/06/20/undo-redo.html&quot;&gt;Undo/Redo&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;2014-10-19 - &lt;a href=&quot;/programming/2014/10/19/dddnorth-review.html&quot;&gt;DDD North 2014 Review&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>NaNo Novel Casting 2014</title>
   <link href="http://markwithall.com/nano/2014/11/01/nano-casting.html"/>
   <updated>2014-11-01T00:00:00+00:00</updated>
   <id>http://markwithall.com/nano/2014/11/01/nano-casting</id>
   <content type="html">&lt;p&gt;It’s that time of year again.  This year I have decided to do a Choose Your Own Adventure novel, loosely based on a certain murder mystery board game.&lt;/p&gt;

&lt;p&gt;To fit the structure of my story (which I will hopefully detail in a later article, if I can persuade myself to do so), I need to have 7 male and 7 female characters.  This works out at one pair for each room on the board (yes, I know there are 9 rooms in the real game but I did say loosely).&lt;/p&gt;

&lt;p&gt;Below is the current casting of each pair of characters.  I shall endeavour to update the list as I decide upon further characters.&lt;/p&gt;

&lt;h2 id=&quot;library&quot;&gt;Library&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Earl Gray: &lt;a href=&quot;http://www.imdb.com/name/nm0000164/&quot;&gt;Anthony Hopkins&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Lady Gray: &lt;a href=&quot;http://www.imdb.com/name/nm0005128/&quot;&gt;Lucy Lawless&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Master Gray: &lt;a href=&quot;http://www.imdb.com/name/nm0685856/&quot;&gt;Michael Pitt&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;conservatory&quot;&gt;Conservatory&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Mr Ruby: &lt;a href=&quot;http://www.imdb.com/name/nm0242882/&quot;&gt;Max Martini&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Mrs Ruby: &lt;a href=&quot;http://www.imdb.com/name/nm0376716/&quot;&gt;Christina Hendricks&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;the-cellar&quot;&gt;The Cellar&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Father Jade:&lt;a href=&quot;http://www.imdb.com/name/nm0000136/&quot;&gt;Johnny Depp&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Sister Mary Leaf: &lt;a href=&quot;http://www.imdb.com/name/nm0005502/&quot;&gt;Michelle Trachtenberg&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;kitchen&quot;&gt;Kitchen&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Mr Ivory: &lt;a href=&quot;http://www.imdb.com/name/nm0252961/&quot;&gt;Idris Elba&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Mrs Ivory:&lt;a href=&quot;http://www.imdb.com/name/nm1720028/&quot;&gt;Amber Heard&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;ballroom&quot;&gt;Ballroom&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Professor Pear: &lt;a href=&quot;http://www.imdb.com/name/nm0000197/&quot;&gt;Jack Nicholson&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Professor Pear: &lt;a href=&quot;http://www.imdb.com/name/nm0000675/&quot;&gt;Jeanne Tripplehorn&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;dining-room&quot;&gt;Dining Room&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Commandant Dijon: &lt;a href=&quot;http://www.imdb.com/name/nm0001993/&quot;&gt;Vincent Cassel&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Mme Dijon: &lt;a href=&quot;http://www.imdb.com/name/nm0000899/&quot;&gt;Monica Bellucci&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;lounge&quot;&gt;Lounge&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Mr Pheasant: &lt;a href=&quot;http://www.imdb.com/name/nm0001570/&quot;&gt;Edward Norton&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Mrs Pheasant: &lt;a href=&quot;http://www.imdb.com/name/nm0001401/&quot;&gt;Angelina Jolie&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;everywhere&quot;&gt;Everywhere&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;The Butler: &lt;a href=&quot;http://www.imdb.com/name/nm0654110/&quot;&gt;Clive Owen&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;The Maid: &lt;a href=&quot;http://www.imdb.com/name/nm1020036/&quot;&gt;Alexandra Breckenridge&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I shall also add which rooms they are in once I’ve decided.  Happy NaNoing!&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>DDD North 2014 Review</title>
   <link href="http://markwithall.com/programming/2014/10/19/dddnorth-review.html"/>
   <updated>2014-10-19T00:00:00+00:00</updated>
   <id>http://markwithall.com/programming/2014/10/19/dddnorth-review</id>
   <content type="html">&lt;p&gt;It’s been a while but yesterday has presented me with the motivation to write another post.  It’s also getting close to the end of the year and I’m running rather short of my target of twelve articles.&lt;/p&gt;

&lt;p&gt;Yesterday (October 17th 2014) I got up in the middle of the night, two hours before I went to bed, and made the long trip to Yorkshire.  I went to &lt;a href=&quot;http://www.dddnorth.co.uk&quot;&gt;DDD North 2014&lt;/a&gt; in Leeds.&lt;/p&gt;

&lt;p&gt;Overall I had a great, if somewhat tiring, day.  There were many interesting talks and discussions with people.  Though, I was slightly disappointed that many of the talks I was most interested in were running in parallel.  Below I’ve summarised the particular talks that I went to.&lt;/p&gt;

&lt;h2 id=&quot;write-your-own-compiler-in-24-hours&quot;&gt;Write your own compiler in 24 hours&lt;/h2&gt;

&lt;p&gt;This talk was by &lt;a href=&quot;https://twitter.com/ptrelford&quot;&gt;Phillip Trelford&lt;/a&gt;.  He went through the writing of a series of interpretters/compilers for increasingly complex languages.  He started with logo, showing some pretty patterns generated.  Then he moved on to Small Basic, expanding upon the original language with parameterised functions and giving an example of &lt;a href=&quot;http://en.wikipedia.org/wiki/Fizz_buzz&quot;&gt;FizzBuzz&lt;/a&gt; implemented in the language.  And finally, ending with an implementation of C#.  One interesting thing that I found out was that C# has an almost one-to-one mapping with the op codes in the VM.&lt;/p&gt;

&lt;p&gt;The main thing to take away from the talk was not to reinvent the wheel and leverage existing tools and technologies.  All of the examples in the talk were given in F#.  I’m not that familiar with the language but as the code was very short it was relatively easy to understand.&lt;/p&gt;

&lt;h2 id=&quot;brownfield-refactoring&quot;&gt;Brownfield Refactoring&lt;/h2&gt;

&lt;p&gt;This talk was by &lt;a href=&quot;https://twitter.com/CleverFinn&quot;&gt;Dominic Finn&lt;/a&gt;.  He presented a great set of hand-drawn slides, which we very entertaining.  I went into this talk expecting to hear some Feathers-style discussion of working with legacy code but was instead greeted with a refreshing angle of how to manage the process from a people perspective.  One particularly interesting point mentioned was to examine where your software is in it’s overall lifecycle and analyse whether it really is worth expending the effort required to improve it.  The recommendation was that when your product goes into decline, get your best developers off it and onto something new.  Then maybe even outsource the maintenance of the declining product.  Another recommendation was to make UI changes very gradually, so as not to upset your users.&lt;/p&gt;

&lt;h2 id=&quot;join-the-dark-side---why-developers-should-choose-management&quot;&gt;Join the Dark Side - Why developers should choose management&lt;/h2&gt;

&lt;p&gt;This talk was by &lt;a href=&quot;https://twitter.com/cerishaw&quot;&gt;Ceri Shaw&lt;/a&gt;.  She addressed such issues as why do we need developers in management and why would they want to be.  She said that one of the reasons we end up with bad managers was that it was seen as a career progression.&lt;/p&gt;

&lt;p&gt;Types of managers were roughly divided into two categories: ‘team leads’ who were responsible for getting the best out of the team as a whole and ‘line managers’ who were responsible for getting the best out of individuals.  She suggested that a good way into management was through mentoring and that one of the most rewarding aspects was seeing improvements in the team.  She did stress that as a manager from a technical background it was important to keep up with coding skills but that there was a trade off as the more management the less coding.  It was also stressed the importance of keeping yourself off the critical path, so at crunch time you could focus on organisational issues.&lt;/p&gt;

&lt;p&gt;Many other useful pieces of advice were put forward too that this article doesn’t have room for.  The talk ended with the recommendation of the book &lt;a href=&quot;http://www.amazon.co.uk/Behind-Closed-Doors-Management-Programmers/dp/0976694026&quot;&gt;Behind Closed Doors&lt;/a&gt; amongst others.&lt;/p&gt;

&lt;h2 id=&quot;visual-studio-codedui-improving-resilience-in-your-automated-tests&quot;&gt;Visual Studio CodedUI: Improving Resilience in your Automated tests&lt;/h2&gt;

&lt;p&gt;This talk was by &lt;a href=&quot;https://twitter.com/captainshmaser&quot;&gt;Riccardo Viglianisi&lt;/a&gt;.  A shorter talk but with a lot of lively discussion afterwards.  The main focus was on the trade off between using automatically generated UI Maps, which are rather fragile, and hand-coded tests, which have a steep learning curve.  Another recommendation was not to use the threading library for timing as it interferes with the running of the tests; playback engine should be used instead.  Annoyingly, the coded UI tests aren’t available for Visual Studio Professional but a third-party library is available from Telerik for less than the cost of Ultimate Edition.&lt;/p&gt;

&lt;h2 id=&quot;micro-services-conquer-monoliths-before-they-own-you&quot;&gt;Micro Services: conquer monoliths, before they own you&lt;/h2&gt;

&lt;p&gt;This talk was by &lt;a href=&quot;https://twitter.com/Roarkiran&quot;&gt;Kiran Singh&lt;/a&gt;.  I was rather flagging at this point.  The speaker told of the benefits of microservices such as independent deployability and that working with distinct services lowers cognitive load.  He also gave some advice for working with microservices, such as the need for good integration testing and that building microservices requires something of a culture change for the organisation not just a software change.  For more details, read Martin Fowler’s &lt;a href=&quot;http://martinfowler.com/articles/microservices.html&quot;&gt;microservices article&lt;/a&gt;.  He gave a couple of case studies and reminded me that I still haven’t read &lt;a href=&quot;http://www.amazon.co.uk/Black-Swan-Impact-Highly-Improbable-ebook/dp/B002RI99IM/&quot;&gt;The Black Swan&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Many, many thanks are due to the people who ran and sponsored the event.  The day ended with drinks and dinner with some colleagues in Veritas (a pub whose menu knows not the word bland).&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Undo/Redo</title>
   <link href="http://markwithall.com/programming/2014/06/20/undo-redo.html"/>
   <updated>2014-06-20T00:00:00+00:00</updated>
   <id>http://markwithall.com/programming/2014/06/20/undo-redo</id>
   <content type="html">&lt;p&gt;Over the last week, I’ve developed an interest in Undo/Redo.  This was partly inspired by reading an article by Aza Raskin (son of Jef) titled &lt;a href=&quot;http://alistapart.com/article/neveruseawarning&quot;&gt;Never Use A Warning When You Mean Undo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I looked at several articles on the subject of undo/redo and came to the conclusion that they were all far too complicated.  I decided to see if there was a simpler way.&lt;/p&gt;

&lt;h2 id=&quot;undoableaction&quot;&gt;UndoableAction&lt;/h2&gt;

&lt;p&gt;In essence, to be able to have undo/redo functionality in an application one must have the ability to do and undo every action that modifies the state of the thing you are editing.  [I realise that this is a rather loose definition and it should probably be pinned down for your specific application; in terms of what is, and isn’t, a state change that need to be undone.]&lt;/p&gt;

&lt;p&gt;To achieve this, we can start by defining an interface to be implemented by all edit actions.  This will look something like the following:&lt;/p&gt;

&lt;div class=&quot;language-c# highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;UndoableAction&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Do&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Undo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;undoredostack&quot;&gt;UndoRedoStack&lt;/h2&gt;

&lt;p&gt;Undo and redo is essentially a stack operation.  When an action is performed, it is put onto the undo stack.  When undo is called, the top action on the stack is popped off; the undo method is run; and then the action is pushed onto the redo stack.  When redo is called, the same sequence happens in reverse.&lt;/p&gt;

&lt;p&gt;One special corner case, that caught me out at first, is the need to clear the redo stack when a new action is performed; as this invalidates the current redo stack because its expected initial state has now been changed.  Undo is obviously unaffected by this.&lt;/p&gt;

&lt;p&gt;A relatively simple implementation of the undo/redo stack might look something like the following:&lt;/p&gt;

&lt;div class=&quot;language-c# highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;UndoRedoStack&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Stack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UndoableAction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_undoStack&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Stack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UndoableAction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;();&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Stack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UndoableAction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_redoStack&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Stack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UndoableAction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;();&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Do&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UndoableAction&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Do&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_undoStack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Push&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_redoStack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Clear&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Undo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;RunAction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_undoStack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_redoStack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Undo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Redo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;RunAction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_redoStack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_undoStack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Do&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;RunAction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Stack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UndoableAction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Stack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UndoableAction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UndoableAction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;undoRedo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Count&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;action&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Pop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;undoRedo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Push&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Each newly created action is passed to the Do method and Undo and Redo modify the state accordingly as they are called.  This is almost certainly not thread safe but I’ll leave such additions as an exercise for the reader.&lt;/p&gt;

&lt;h2 id=&quot;addtolistaction&quot;&gt;AddToListAction&lt;/h2&gt;

&lt;p&gt;All that remains is for us to create some undoable actions.  These will, of course, be application specific and one must be very careful that undo and redo will perform correctly under all required circumstances.  Here is a case that may commonly occur: adding an item to a list.&lt;/p&gt;

&lt;div class=&quot;language-c# highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AddToListAction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UndoableAction&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_itemToAdd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;AddToListAction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;itemToAdd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_itemToAdd&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;itemToAdd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_list&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Do&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_itemToAdd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Undo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;RemoveAt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Count&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In this case, Do appends an item to the end of the list and Undo removes the last item of the list.  As long as the list is in the same state when Undo is called, as it was after Do had been called, everything should work out as planned.  This is why it is important that every action that modifies the state is an UndoableAction.&lt;/p&gt;

&lt;h2 id=&quot;actionblock&quot;&gt;ActionBlock&lt;/h2&gt;

&lt;p&gt;As a final bonus, here is another general purpose UndoableAction that is quite useful.  Often we want to perform a group of actions in one compound action (e.g. adding a group of items to a list).  In this case, we would want undo to remove all of the added items in one step rather than removing each item individually.  Obviously, we could write an add multiple items action but that approach will get old fast as we add more and more actions.  A better approach would be to have the ability to compose multiple simpler actions.  This composition can also be done as an UndoableAction as follows:&lt;/p&gt;

&lt;div class=&quot;language-c# highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ActionBlock&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UndoableAction&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UndoableAction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_actionSequence&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ActionBlock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;params&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UndoableAction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;actionSequence&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_actionSequence&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;actionSequence&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Do&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;action&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_actionSequence&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Do&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Undo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;action&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_actionSequence&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Reverse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Undo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This time, the action is a list of UndoableActions performed forwards for Do and in reverse for Undo.  When Undo is called, all of the undo actions in the sequence will be called in one step.&lt;/p&gt;

&lt;p&gt;So, there we have it.  A simple implementation of undo/redo that uses an interface and a simple class that wraps two stacks.  Now all that remains is the hard part: writing UndoableActions where Undo properly reverts the state.&lt;/p&gt;

&lt;p&gt;A simple example implementation of the above can be found &lt;a href=&quot;https://github.com/MarkWithall/UndoRedoTest&quot;&gt;on github&lt;/a&gt;.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Such Coffee, Many Caffeine, Wow!</title>
   <link href="http://markwithall.com/programming/2014/05/18/such-coffee-many-caffeine-wow.html"/>
   <updated>2014-05-18T00:00:00+00:00</updated>
   <id>http://markwithall.com/programming/2014/05/18/such-coffee-many-caffeine-wow</id>
   <content type="html">&lt;p&gt;Over the past two days I’ve been at &lt;a href=&quot;http://devslovebacon.com&quot;&gt;BACON 2014&lt;/a&gt; (it’s a wonderful conference, you must go).  At the end I drank far too much coffee and enthusiastically signed up for a lightning talk.  I’ll post a link to the talk here when it comes out.&lt;/p&gt;

&lt;p&gt;I decided to talk air some of my initial impressions about the current “TDD Is Dead” debates that are going on.  Whilst my thoughts are not fully developed yet, and my talk was almost certainly completely incoherent (as it was largely ad libbed), I think my key conclusions where valid.&lt;/p&gt;

&lt;p&gt;In addition, I was very pleased to see that a large proportion of the attendees at BACON 2014 where practicing TDD on a daily basis, on real-world projects.  It’s death seems, at least in that community, to have been greatly exaggerated.&lt;/p&gt;

&lt;h2 id=&quot;be-pragmatic-not-dogmatic&quot;&gt;Be Pragmatic, Not Dogmatic&lt;/h2&gt;

&lt;p&gt;I tend to agree with DHH that you don’t always know what you are trying to achieve when you start programming.  Sometimes you want to quickly try a few things out and see where it goes.  See what works best.  It’s often difficult to start by writing a test when you don’t know the goal.  I seem to recall even Uncle Bob saying that TDD shouldn’t replace design; and sometimes that design is best done in code.&lt;/p&gt;

&lt;p&gt;Also, not every class or method needs to be completely isolated from everything.  Again, Uncle Bob (as he so often does) wrote a great blog post just the other day about &lt;a href=&quot;http://blog.8thlight.com/uncle-bob/2014/05/10/WhenToMock.html&quot;&gt;where and when to mock&lt;/a&gt; and even &lt;a href=&quot;http://blog.8thlight.com/uncle-bob/2014/05/14/TheLittleMocker.html&quot;&gt;what sort of mocks are best to use&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So, be pragmatic.  100% test coverage, with completely decoupled unit tests, is not always a helpful goal and can often force you to do strange things to allow it to be achieved.&lt;/p&gt;

&lt;h2 id=&quot;code-isnt-documentation&quot;&gt;Code Isn’t Documentation&lt;/h2&gt;

&lt;p&gt;DHH has a goal of readability of code over testability of code.  He seems to be saying that TDD forces your hand and leads to code that is ‘too decoupled’ and not cohesive.  I liked Kent Beck’s repost that TDD doesn’t force you to do anything.  You are in control of the design.&lt;/p&gt;

&lt;p&gt;But, more than that, the most readable code in the world won’t be able to overcome there being one million lines of it.  &lt;a href=&quot;http://stevelosh.com/blog/2013/09/teach-dont-tell/&quot;&gt;Steve Losh&lt;/a&gt; had a wonderful article on how to document code, which basically said that reading the code should be the last resort to understanding your codebase.&lt;/p&gt;

&lt;p&gt;Just remember, these are all &lt;a href=&quot;http://codon.com/the-dhh-problem&quot;&gt;individual views&lt;/a&gt;.  I’ve seen a tree trunk, DHH has seen a snake but we are still yet to properly address the elephant in the room.&lt;/p&gt;

&lt;p&gt;I’m sure I’ll have many more thoughts on this subject as the debate goes on but writing down their current state will allow me to look back and point and laugh at the silly conclusions I drew early on in the proceedings.&lt;/p&gt;

&lt;h2 id=&quot;update-my-lightning-talk-video&quot;&gt;Update: My Lightning Talk Video&lt;/h2&gt;

&lt;iframe src=&quot;//player.vimeo.com/video/96915724?title=0&amp;amp;byline=0&amp;amp;portrait=0&amp;amp;color=f3b940&quot; width=&quot;500&quot; height=&quot;281&quot; frameborder=&quot;0&quot; webkitallowfullscreen=&quot;&quot; mozallowfullscreen=&quot;&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;
&lt;p&gt;&lt;a href=&quot;http://vimeo.com/96915724&quot;&gt;Mark Withall - Lightning talk&lt;/a&gt; from &lt;a href=&quot;http://vimeo.com/user11456649&quot;&gt;BACON: things developers love&lt;/a&gt; on &lt;a href=&quot;https://vimeo.com&quot;&gt;Vimeo&lt;/a&gt;.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Labelled TextBox In WPF</title>
   <link href="http://markwithall.com/programming/2014/05/02/labelled-textbox-in-wpf.html"/>
   <updated>2014-05-02T00:00:00+00:00</updated>
   <id>http://markwithall.com/programming/2014/05/02/labelled-textbox-in-wpf</id>
   <content type="html">&lt;p&gt;As is so often is the case, StackOverflow has provided another &lt;a href=&quot;http://stackoverflow.com/q/23389148/1245027&quot;&gt;interesting question&lt;/a&gt; that reminded me of an issue I encounter from time to time.  The question is about how to have a sequence of labelled textboxes, such that everything is nicely aligned.  The question references &lt;a href=&quot;http://stackoverflow.com/a/1015418/1245027&quot;&gt;an answer&lt;/a&gt; that the OP doesn’t like as it potentially adds some performance overhead.  I don’t think that any overhead in that solution is likely to be an issue in practice though.&lt;/p&gt;

&lt;p&gt;I’d like to walk through a thought process that might get you to something similar to the referenced answer.&lt;/p&gt;

&lt;h2 id=&quot;the-basic-approach&quot;&gt;The Basic Approach&lt;/h2&gt;

&lt;p&gt;Firstly, let’s look at how one might approach this problem in a ‘one off’ case; where reuse isn’t an issue.&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;Grid&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;Grid.ColumnDefinitions&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;ColumnDefinition&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Width=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Auto&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;ColumnDefinition&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Width=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;*&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/Grid.ColumnDefinitions&amp;gt;&lt;/span&gt;

    &lt;span class=&quot;nt&quot;&gt;&amp;lt;Grid.RowDefinitions&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;RowDefinition&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Height=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Auto&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;RowDefinition&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Height=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Auto&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;RowDefinition&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Height=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Auto&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/Grid.RowDefinitions&amp;gt;&lt;/span&gt;

    &lt;span class=&quot;nt&quot;&gt;&amp;lt;TextBlock&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Grid.Row=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;0&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Grid.Column=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;0&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Thing1&lt;span class=&quot;nt&quot;&gt;&amp;lt;/TextBlock&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;TextBox&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Grid.Row=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;0&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Grid.Column=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;1&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Text=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{Binding Thing1}&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;

    &lt;span class=&quot;nt&quot;&gt;&amp;lt;TextBlock&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Grid.Row=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;1&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Grid.Column=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;0&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Thing2&lt;span class=&quot;nt&quot;&gt;&amp;lt;/TextBlock&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;TextBox&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Grid.Row=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;1&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Grid.Column=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;1&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Text=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{Binding Thing2}&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;

    &lt;span class=&quot;nt&quot;&gt;&amp;lt;TextBlock&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Grid.Row=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;2&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Grid.Column=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;0&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Thing3&lt;span class=&quot;nt&quot;&gt;&amp;lt;/TextBlock&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;TextBox&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Grid.Row=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;2&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Grid.Column=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;1&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Text=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{Binding Thing3}&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/Grid&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is clearly quite a verbose solution and there must be a better way if we are going to be doing this sort of thing a lot.  And we are.  Another annoyance with this approach is the need to renumber everything if we want to insert a row or column.  It would be nice to have something more akin to HTML tables.&lt;/p&gt;

&lt;h2 id=&quot;what-would-we-like-to-write&quot;&gt;What Would We Like To Write?&lt;/h2&gt;

&lt;p&gt;Before we try and solve the problem, it might be a good idea to think in the abstract of what we would like to be able to write in an ideal world.  It’s probably going to look something along the lines of this:&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;LayoutGroup&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;LabelledTextBox&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Label=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Thing1&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Text=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{Binding Thing1}&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;LabelledTextBox&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Label=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Thing2&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Text=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{Binding Thing2}&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;LabelledTextBox&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Label=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Thing3&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Text=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{Binding Thing3}&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/LayoutGroup&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It would be difficult to get more concise than that and still retain the expressiveness of what we want to do.&lt;/p&gt;

&lt;h2 id=&quot;how-near-can-we-get-to-this&quot;&gt;How Near Can We Get To This?&lt;/h2&gt;

&lt;p&gt;So how are we going to go about this?  Let us start at the bottom and look at how we could create a ‘LabelledTextBox’ control.  The XAML is pretty straightforward, and is similar to what we started with above but we’ve now added a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SharedSizeGroup&lt;/code&gt; to allow things to line up properly (assuming we are nested in something with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Grid.IsSharedSizeScope&lt;/code&gt; set to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;True&lt;/code&gt;).&lt;/p&gt;

&lt;h2 id=&quot;labelledtextboxxaml&quot;&gt;LabelledTextBox.xaml&lt;/h2&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;Grid&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;x:Name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Root&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;Grid.ColumnDefinitions&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;ColumnDefinition&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Width=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Auto&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;SharedSizeGroup=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Labels&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;ColumnDefinition&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Width=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;*&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/Grid.ColumnDefinitions&amp;gt;&lt;/span&gt;

    &lt;span class=&quot;nt&quot;&gt;&amp;lt;TextBlock&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Grid.Column=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;0&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Text=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{Binding Label}&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;TextBox&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Grid.Column=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;1&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Text=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{Binding Text}&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/Grid&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;labelledtextboxxamlcs&quot;&gt;LabelledTextBox.xaml.cs&lt;/h2&gt;

&lt;p&gt;That’s all well and good but where are we getting these &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Label&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Text&lt;/code&gt; properties to bind to?  Here we need to introduce some Dependency Properties.  This allows the user of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LabelledTextBox&lt;/code&gt; to bind to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Label&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Text&lt;/code&gt; and for the control to use them too.  Note that we have to set the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DataContext&lt;/code&gt; of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Grid&lt;/code&gt; to the control, so that we can bind to our own &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Label&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Text&lt;/code&gt; properties but we leave the top-level &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DataContext&lt;/code&gt; of the control in the broader context, so that other things can bind to our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Label&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Text&lt;/code&gt; properties too.&lt;/p&gt;

&lt;div class=&quot;language-c# highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;partial&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;LabelledTextBox&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DependencyProperty&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LabelProperty&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DependencyProperty&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Register&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Label&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;typeof&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;typeof&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LabelledTextBox&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;FrameworkPropertyMetadata&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Unnamed Label&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DependencyProperty&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TextProperty&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DependencyProperty&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Register&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Text&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;typeof&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;typeof&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LabelledTextBox&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;FrameworkPropertyMetadata&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FrameworkPropertyMetadataOptions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BindsTwoWayByDefault&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;LabelledTextBox&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;InitializeComponent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DataContext&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Label&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LabelProperty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SetValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LabelProperty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Text&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TextProperty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SetValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TextProperty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;layoutgroupcs&quot;&gt;LayoutGroup.cs&lt;/h2&gt;

&lt;p&gt;Finally, we need to create a container control that has shared size scope.  We can doing this by creating a subclass of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StackPanel&lt;/code&gt; and then setting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Grid.IsSharedSizeScope&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;True&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-c# highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;LayoutGroup&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;StackPanel&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;LayoutGroup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Grid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SetIsSharedSizeScope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;usage&quot;&gt;Usage&lt;/h2&gt;

&lt;p&gt;This gives us the ability to put it all together in the following way that is very similar to our initial desired solution (with the exception of references to the namespace path of the controls).&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;Views:LayoutGroup&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;Views:LabelledTextBox&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Label=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Thing1&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Text=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{Binding Thing1}&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;Views:LabelledTextBox&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Label=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Thing2&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Text=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{Binding Thing2}&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;Views:LabelledTextBox&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Label=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Thing3&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Text=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{Binding Thing3}&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/Views:LayoutGroup&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;One could, of course, go a step further and have a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Command&lt;/code&gt; property that allows a button to be shown, e.g. for the purpose of selecting files.  And even have the button hidden if no command is bound to it.  I’ll leave this and the many other possible extensions as an exercise for the reader.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Save All Excel Worksheets As Tab Separated Text</title>
   <link href="http://markwithall.com/programming/2014/04/18/save-all-excel-worksheets-as-tab-separated-text.html"/>
   <updated>2014-04-18T00:00:00+00:00</updated>
   <id>http://markwithall.com/programming/2014/04/18/save-all-excel-worksheets-as-tab-separated-text</id>
   <content type="html">&lt;p&gt;Quite often I have to save worksheets in Excel as tab-separated text or CSV.  I have managed to get it down to 8 clicks to perform this task for a single worksheet.  At the point I had to do this for 40 spreadsheets with 4 worksheets in each, I decided that enough was enough.&lt;/p&gt;

&lt;p&gt;I started off by writing a simple macro that saved all the worksheets in the active workbook to the desktop.  I then placed it in my PERSONAL.XLSB (which is an incredibly useful place to put macros that you want to use on multiple spreadsheets as it’s always there; hidden in the background).&lt;/p&gt;

&lt;div class=&quot;language-vb highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;Sub&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SaveAllAsTsv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;Dim&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;WS&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Excel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Worksheet&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;Dim&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;SaveToDirectory&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;Dim&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;filename&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;SaveToDirectory&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CreateObject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;WScript.Shell&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;specialfolders&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Desktop&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;For&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;Each&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;WS&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;In&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ActiveWorkbook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Worksheets&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SaveToDirectory&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;\&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;WS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;.txt&quot;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;WS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SaveAs&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xlText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Local&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;True&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;Next&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;End&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;Sub&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;One interesting point to note is the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Local:=True&lt;/code&gt; argument to the SaveAs method.  This makes sure that the formatting of, e.g. dates, is exported as it is presented in the worksheet rather than using whatever default the SaveAs method decides upon.&lt;/p&gt;

&lt;p&gt;This approach worked fine for a while but then I started to have spreadsheets with far more worksheets than I actually wanted to export.  Copying them from the desktop was a bit of a pain too.  I, therefore, went back to the macro and expanded upon it to allow selection of the destination folder and the option whether to save each worksheet.&lt;/p&gt;

&lt;div class=&quot;language-vb highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;Sub&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SaveAllAsTsv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;Dim&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;WS&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Excel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Worksheet&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;Dim&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;SaveToDirectory&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;Dim&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;Filename&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;'Get folder to save to&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;With&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Application&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fileDialog&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msoFileDialogFolderPicker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Title&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Output Folder&quot;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AllowMultiSelect&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;False&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;If&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Show&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;Then&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;Exit&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;Sub&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;SaveToDirectory&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SelectedItems&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;End&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;With&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;'Choose which worksheets to save&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;For&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;Each&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;WS&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;In&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ActiveWorkbook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Worksheets&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;Select&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;Case&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MsgBox&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Save &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;WS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;?&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vbQuestion&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vbYesNoCancel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;Case&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vbYes&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;Filename&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SaveToDirectory&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;\&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;WS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;.txt&quot;&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;WS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SaveAs&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xlTextWindows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Local&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;True&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;Case&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vbCancel&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;Exit&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;Sub&lt;/span&gt;
            &lt;span class=&quot;nf&quot;&gt;Case&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vbNo&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;End&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;Select&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;Next&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;End&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;Sub&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This works fine for now.  I imagine that at some point I’m going to get annoyed with clicking ‘Yes’ or ‘No’ for each worksheet and will have to upgrade to a single list of all worksheets with checkboxes up front.  I’ll leave this extension as an exercise for the reader.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>To Rebase Or Not To Rebase?</title>
   <link href="http://markwithall.com/programming/2014/03/22/to-rebase-or-not-to-rebase.html"/>
   <updated>2014-03-22T00:00:00+00:00</updated>
   <id>http://markwithall.com/programming/2014/03/22/to-rebase-or-not-to-rebase</id>
   <content type="html">&lt;p&gt;Some thoughts on the relative merits of rebasing a branch before merging when working with a DVCS like Mercurial or Git.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Updated 18th April 2014 with some comments from my colleague &lt;a href=&quot;https://twitter.com/davecturner&quot;&gt;@DaveCTurner&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;merge&quot;&gt;Merge&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/images/merge.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;pros&quot;&gt;Pros&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Simple to perform&lt;/li&gt;
  &lt;li&gt;Maintains the original context of the source branch&lt;/li&gt;
  &lt;li&gt;Easy to find points where merge conflict resolution failed&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;cons&quot;&gt;Cons&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Can’t bisect to find cause of bugs (requires linear history)
    &lt;ul&gt;
      &lt;li&gt;Non-linear histories mean that working and non-working versions can be interleaved making it unlikely that bisect will end up at the revision that caused the bug&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Difficult to read the history&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;Further con of merging is that conflict resolution is atomic. If you have a knarly merge then doing it in pieces is better. I claim that resolving conflicting patches in the queue is much easier than 3-way merging&lt;/em&gt; &lt;a href=&quot;https://twitter.com/davecturner&quot;&gt;@DaveCTurner&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;You can do topological bisection in a mergy history, but the chances are the first bad commit is the merge, which doesn’t help you with debugging.&lt;/em&gt; &lt;a href=&quot;https://twitter.com/davecturner&quot;&gt;@DaveCTurner&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;rebase&quot;&gt;Rebase&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/images/rebase.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Rebase means different things to different people.  Let me start by clarifying what I mean.  This is best done with a picture (see above).  When I say rebase, I mean moving the whole branch to the top of the tree without moving all changesets onto the default branch or flattening into a single changeset (two common alternative meanings, particularly in the Git world).  This means that we lose the minimum of information.&lt;/p&gt;

&lt;h3 id=&quot;pros-1&quot;&gt;Pros&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Can easily track down cause of bugs using bisect&lt;/li&gt;
  &lt;li&gt;Simple to read history with clearly defined tasks&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;cons-1&quot;&gt;Cons&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Hard to find where merge conflict resolution failed
    &lt;ul&gt;
      &lt;li&gt;But can partly be done by reordering the changesets by time&lt;/li&gt;
      &lt;li&gt;Or better, if there is a conflict, rebase using the patch queue and name the commits that resolve conflicts explicitly&lt;/li&gt;
      &lt;li&gt;This is less of an issue if you have good test coverage&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Can only be done with local changesets (i.e. before pull or push); hence can prevent collaboration on a branch
    &lt;ul&gt;
      &lt;li&gt;&lt;em&gt;You can collaborate on a branch when rebasing, either with bundles or a private clone set up for just the branch. Requires about the same amount of coordination as the alternatives.&lt;/em&gt; &lt;a href=&quot;https://twitter.com/davecturner&quot;&gt;@DaveCTurner&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Personally, I tend to favour the rebase approach as I’m somewhat OCD about having a pretty looking graph of the history.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>2013 Programming Articles Review</title>
   <link href="http://markwithall.com/programming/2014/02/22/2013-programming-articles-review.html"/>
   <updated>2014-02-22T00:00:00+00:00</updated>
   <id>http://markwithall.com/programming/2014/02/22/2013-programming-articles-review</id>
   <content type="html">&lt;p&gt;At the beginning of each year I like to set myself some goals for the coming twelve months.  Last year (2013), I decided I wanted to blog more.  In particular, I wanted to write more about programming.  One of the main reasons for this was that I wanted to give myself some practice at explaining my thought process; an area in which I’ve not always excelled in the past.&lt;/p&gt;

&lt;p&gt;Over the year, I managed to write nine articles, on a fairly diverse set of programming topics.  While I fell short of my ‘one a month’ goal, I still consider this a success.  I suppose, as with most new year’s resolution type things, it was inevitable that it would tail off in the second half of the year.&lt;/p&gt;

&lt;p&gt;This year (2014), I have decided to try again at twelve articles over the year.  Hopefully, I will at least beat the nine of last year.  Of course, I’ve decided to cheat and give myself a head start by writing this article about last years articles.  I also have a couple of half finished articles from last year, which should also help.&lt;/p&gt;

&lt;p&gt;In addition to writing more articles, I’d like to record a couple of live coding videos for youtube, in the areas of TDD and MVVM, based on a few of last year’s articles.  I also want to write the simple blog commenting system that’s been on the todo list for quite some time.&lt;/p&gt;

&lt;p&gt;To finish, here is a list of links to the articles from 2013.  I think my favourite was probably The World’s Simplest C# WPF MVVM Example; the &lt;a href=&quot;https://github.com/MarkWithall/worlds-simplest-csharp-wpf-mvvm-example&quot;&gt;code for which&lt;/a&gt; has been forked and starred a number of times on github.  I’m planning a follow up to this article where I look into extreme decoupling of the parts of an MVVM application to see just how far one can go.&lt;/p&gt;

&lt;p&gt;Wish me luck!&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;2013-01-04 - &lt;a href=&quot;/programming/2013/01/04/word-to-text.html&quot;&gt;How to extract text from a Microsoft Word document in C#&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;2013-01-09 - &lt;a href=&quot;/programming/2013/01/09/speed-reader-bookmarklet.html&quot;&gt;Speed Reader Bookmarklet&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;2013-02-01 - &lt;a href=&quot;/programming/2013/02/01/create-outlook-2010-search-folder.html&quot;&gt;Create an Outlook 2010 Search Folder using VBA&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;2013-03-01 - &lt;a href=&quot;/programming/2013/03/01/worlds-simplest-csharp-wpf-mvvm-example.html&quot;&gt;The World’s Simplest C# WPF MVVM Example&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;2013-03-30 - &lt;a href=&quot;/programming/2013/03/30/thoughts-on-tdd.html&quot;&gt;Thoughts On Test Driven Development&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;2013-04-12 - &lt;a href=&quot;/programming/2013/04/12/how-big-is-your-endian.html&quot;&gt;How Big Is Your Endian?&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;2013-08-06 - &lt;a href=&quot;/programming/2013/08/06/tdd-mvvm-framework-test-plan.html&quot;&gt;TDD MVVM Framework Test Plan&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;2013-08-29 - &lt;a href=&quot;/programming/2013/08/29/simple-event-aggregator-in-csharp.html&quot;&gt;A Simple Event Aggregator / Message Bus In C#&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;2013-10-28 - &lt;a href=&quot;/programming/2013/10/28/tdd-vs-productivity.html&quot;&gt;TDD vs Productivity&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</content>
 </entry>
 
 <entry>
   <title>NaNo Novel Structure</title>
   <link href="http://markwithall.com/nano/2013/10/31/nano-novel-structure.html"/>
   <updated>2013-10-31T00:00:00+00:00</updated>
   <id>http://markwithall.com/nano/2013/10/31/nano-novel-structure</id>
   <content type="html">&lt;p&gt;My usual approach to make novelling in November easier is to have a fairly rigid structure in place.  This has two goals: the first is to allow me to end up with a balanced novel and the second is to give me a sense of achievability and progress.&lt;/p&gt;

&lt;p&gt;50,000 words sounds like a lot (and is) but it seems much more manageable when I know that I only have to write 1667 in one day and 3 days’ writing will complete the first chapter.&lt;/p&gt;

&lt;p&gt;Here is the list of structures that I have used to help me along for the previous four NaNos and the one that I will be using this year.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2009&lt;/strong&gt;: 100 x 500 word chapters, where the end of each chapter would inspire the beginning of the next (and the final chapter would wrap around to the beginning).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2010&lt;/strong&gt;: 3 x 10 chapter parts; each being 1667 words and taking a day to write.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2011&lt;/strong&gt;: A free approach to chapters/structure, where each chapter is finished when it’s finished.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2012&lt;/strong&gt;: 30 x 1667 word chapters with each chapter focusing on one of the 3 or 4 storylines.&lt;/p&gt;

&lt;p&gt;And my choice for this year is to write 10 x 5000 word chapters, each taking 3 days to write but each chapter will be made up of newspaper articles, interviews, letters and the like.  Hopefully, this will help motivate me as the previous structures have done.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>TDD vs Productivity</title>
   <link href="http://markwithall.com/programming/2013/10/28/tdd-vs-productivity.html"/>
   <updated>2013-10-28T00:00:00+00:00</updated>
   <id>http://markwithall.com/programming/2013/10/28/tdd-vs-productivity</id>
   <content type="html">&lt;p&gt;Today I encountered this programmers.stackexchange post on &lt;a href=&quot;http://programmers.stackexchange.com/questions/86636/tdd-vs-productivity&quot;&gt;TDD vs Productivity&lt;/a&gt; and had some thoughts on common misconceptions about TDD and unit testing.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;If you don’t end up with 100% test coverage, you haven’t done TDD properly(tm) - this is because you shouldn’t write any production code without a failing test and you should only write the minimum to make the test pass.&lt;/li&gt;
  &lt;li&gt;You shouldn’t be testing 3rd party code, so TDD still applies to library intensive software like game programming just as much as any other, as you won’t be testing the OpenGL/DirectX functionality only the calls to the API.&lt;/li&gt;
  &lt;li&gt;If you are writing lots of tests for a class, you probably aren’t abiding by the single-responsibility principle - in most cases, classes that only do one thing shouldn’t need many tests to cover its behaviour.&lt;/li&gt;
  &lt;li&gt;Refactoring shouldn’t change behaviour - if you want to change behaviour write a test for the new behaviour or modify tests that now don’t represent the desired behaviour of the software.&lt;/li&gt;
  &lt;li&gt;Unit tests only tell you when you have a bug, not when you don’t.&lt;/li&gt;
  &lt;li&gt;When people say they don’t test UI, what they should mean is that they don’t test what the UI looks like; they should still be testing what it does.  Also, see point 1.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I may add items to this list as I think of them.  Also, I reserve the right to change my mind if superior data are discovered.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Introduction To NaNoWriMo 2013</title>
   <link href="http://markwithall.com/nano/2013/10/20/intro-to-nanowrimo-2013.html"/>
   <updated>2013-10-20T00:00:00+00:00</updated>
   <id>http://markwithall.com/nano/2013/10/20/intro-to-nanowrimo-2013</id>
   <content type="html">&lt;p&gt;This November I will be doing &lt;a href=&quot;http://nanowrimo.org/en/participants/scroog1/&quot;&gt;NaNoWriMo&lt;/a&gt; for the fifth time.&lt;/p&gt;

&lt;p&gt;I’ve decided this year to write a political satire based in the near future.  In the story an extreme right-wing party gets into power after an unusually large number of protest votes.  Needless to say, hilarity ensues.&lt;/p&gt;

&lt;p&gt;The main story will revolve around a number of new laws and policies that will be introduced during the term.  These will include such things as the following:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;a new speed camera system that utilises satellite technology to monitor all cars all the time&lt;/li&gt;
  &lt;li&gt;unemployed people being automatically given work by the government to earn their benefits; resulting in much cleaner towns and cities and other side effects&lt;/li&gt;
  &lt;li&gt;an increase in the minimum age for smoking by one year every year&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Other policies that will be addressed will include business, education and, of course, foreign policy and immigration.&lt;/p&gt;

&lt;p&gt;I have no idea where all of this will end up but it should provide much entertainment for the month of November.&lt;/p&gt;

&lt;p&gt;See you all at the TGIO.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>A Simple Event Aggregator / Message Bus In C#</title>
   <link href="http://markwithall.com/programming/2013/08/29/simple-event-aggregator-in-csharp.html"/>
   <updated>2013-08-29T00:00:00+00:00</updated>
   <id>http://markwithall.com/programming/2013/08/29/simple-event-aggregator-in-csharp</id>
   <content type="html">&lt;p&gt;In &lt;a href=&quot;/programming/2013/08/06/tdd-mvvm-framework-test-plan.html&quot;&gt;a previous article&lt;/a&gt; we looked at the two most important features of an MVVM framework.  Here we look at another common feature.&lt;/p&gt;

&lt;p&gt;Most, if not all, mainstream MVVM frameworks provide some sort of event aggregator/message bus.  This makes communication between viewmodels easier than doing it manually via events or callback injection (both of which require too much knowledge of either the sender or receiver and tend to be the cause of accidental memory leaks).&lt;/p&gt;

&lt;p&gt;Fortunately, it is straightforward to create a simple event aggregator.  We can define the API using the following set of interfaces.&lt;/p&gt;

&lt;h2 id=&quot;isubscribertmessage&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ISubscriber&amp;lt;TMessage&amp;gt;&lt;/code&gt;&lt;/h2&gt;

&lt;div class=&quot;language-c# highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ISubscriber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;HandleMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TMessage&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This allows a class to implement multiple event handlers without the need to switch on the message type.&lt;/p&gt;

&lt;h2 id=&quot;isubscriberstore&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ISubscriberStore&lt;/code&gt;&lt;/h2&gt;

&lt;div class=&quot;language-c# highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ISubscriberStore&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ISubscriber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;subscriber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;IEnumerable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ISubscriber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Subscribers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;No &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Remove&lt;/code&gt; method, as subscriptions will be stored as weak references and are cleaned up on calls to Subscribers.&lt;/p&gt;

&lt;h2 id=&quot;imessageaggregator&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IMessageAggregator&lt;/code&gt;&lt;/h2&gt;

&lt;div class=&quot;language-c# highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;IMessageAggregator&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Subscribe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ISubscriber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;subscriber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Publish&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TMessage&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;No &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Unsubscribe&lt;/code&gt; method, as subscriptions are stored as weak references and are cleaned up on calls to publish.&lt;/p&gt;

&lt;p&gt;Notice that messages can be anything, though it is probably sensible to wrap them in a well named class.&lt;/p&gt;

&lt;p&gt;As an aside, I don’t generally go in for naming interfaces with an ‘I’ prefix.  There are many arguments in favour of this on the Interweb.  However, for libraries, where one doesn’t know who is using it (or how), I prefer the explicit approach.&lt;/p&gt;

&lt;h2 id=&quot;test-plan&quot;&gt;Test Plan&lt;/h2&gt;

&lt;h3 id=&quot;subscriberstore&quot;&gt;SubscriberStore&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SubscriberStore&lt;/code&gt; implements &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ISubscriberStore&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Add adds a subscriber to the underlying dictionary list for the particular message type&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Subscribers&lt;/code&gt; returns all subscribers for the given message type&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Subscribers&lt;/code&gt; removes all dead subscribers for the given message type&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Subscribers&lt;/code&gt; doesn’t return null subscribers&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;messageaggregator&quot;&gt;MessageAggregator&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MessageAggregator&lt;/code&gt; implements &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IMessageAggregator&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Subscribe&lt;/code&gt; adds to the underlying &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ISubscriberStore&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Publish&lt;/code&gt; calls &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HandleMessage&lt;/code&gt; on all subscribers for the given message type&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Also, an integration/acceptance test that has multiple publishers and subscribers (implementing multiple types each) is probably warranted.&lt;/p&gt;

&lt;p&gt;The actual implementation details of these classes is left as an exercise for the reader but will hopefully be the subject of a later video.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>TDD MVVM Framework Test Plan</title>
   <link href="http://markwithall.com/programming/2013/08/06/tdd-mvvm-framework-test-plan.html"/>
   <updated>2013-08-06T00:00:00+00:00</updated>
   <id>http://markwithall.com/programming/2013/08/06/tdd-mvvm-framework-test-plan</id>
   <content type="html">&lt;p&gt;Just out of interest, I was experimenting with TDDing (if that’s a real phrase) a basic MVVM framework in C#.  The following is the rough sequence of tests for test-driving the implementation that I ended up using.&lt;/p&gt;

&lt;p&gt;WPF makes use of two main interfaces: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;INotifyPropertyChanged&lt;/code&gt; for notifying the UI of updates to properties that it is bound to, &lt;em&gt;e.g.&lt;/em&gt; the value in a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TextBox&lt;/code&gt;; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ICommand&lt;/code&gt; for executing commands when, &lt;em&gt;e.g.&lt;/em&gt; a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Button&lt;/code&gt; is pressed.&lt;/p&gt;

&lt;p&gt;Here are the sequence of tests for the two main classes in the framework.&lt;/p&gt;

&lt;h2 id=&quot;observableobject--inotifypropertychanged&quot;&gt;ObservableObject : INotifyPropertyChanged&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ObservableObject&lt;/code&gt; implements &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;INotifyPropertyChanged&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RaisePropertyChangedEvent&lt;/code&gt; with property name fires event&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RaisePropertyChangedEvent&lt;/code&gt; with property name passes name through to handler&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RaisePropertyChangedEvent&lt;/code&gt; with name of non-existent property throws &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ArgumentException&lt;/code&gt; (in Debug only)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RaisePropertyChangedEvent&lt;/code&gt; with multiple property names fires event for each&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RaisePropertyChangedEvent&lt;/code&gt; with no observers does not throw exception&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;delegatecommand--icommand&quot;&gt;DelegateCommand : ICommand&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DelegateCommand&lt;/code&gt; implements &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ICommand&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CanExecute&lt;/code&gt; returns &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;True&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Execute&lt;/code&gt; runs stored &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Action&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Execute&lt;/code&gt; with null does not throw exception&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I’m unsure as to the necessity of testing that the classes implement the required interfaces but it is technically a requirement of the implementation.&lt;/p&gt;

&lt;p&gt;At some point in the near future, I hope to record a video of this development.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>How Big Is Your Endian?</title>
   <link href="http://markwithall.com/programming/2013/04/12/how-big-is-your-endian.html"/>
   <updated>2013-04-12T00:00:00+00:00</updated>
   <id>http://markwithall.com/programming/2013/04/12/how-big-is-your-endian</id>
   <content type="html">&lt;p&gt;I have finally discovered some of the advantages and disadvantages of the two main endian-nesses for data representation.  This isn’t something I’ve really thought about before but it’s actually quite interesting when you find out.&lt;/p&gt;

&lt;p&gt;Big-endian (the firstianness of this endian should not be interpreted as any sort of favouritism whatsoever towards this particular representation)&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Human-readable, i.e. reading from left to right tells you what the data is&lt;/li&gt;
  &lt;li&gt;Testing for sign, i.e. the leftmost bit is the positivity/negativity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Little-endian (the secondness of this endian should in no way indicate the lack of joy derived from its usage)&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Easily truncate-able, i.e. conversion from 32-bits to 16- or 8- just involves taking the first n bits&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There’s also a middle-endian, apparently, though I doubt anyone knows why.&lt;/p&gt;

&lt;p&gt;So, now we know.&lt;/p&gt;

&lt;p&gt;As always, see &lt;a href=&quot;http://en.wikipedia.org/wiki/Endianness&quot;&gt;the ‘pedia&lt;/a&gt; for further details.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Thoughts On Test Driven Development</title>
   <link href="http://markwithall.com/programming/2013/03/30/thoughts-on-tdd.html"/>
   <updated>2013-03-30T00:00:00+00:00</updated>
   <id>http://markwithall.com/programming/2013/03/30/thoughts-on-tdd</id>
   <content type="html">&lt;p&gt;&lt;em&gt;Except from a conversation with &lt;a href=&quot;http://mta.agrip.org.uk/&quot;&gt;Matthew T. Atkinson&lt;/a&gt; on the 27th of March 2013.  A discussion on how to do TDD ‘properly’ and why it’s hard to be disciplined about following the approach.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For TDD one must write ONE test that fails and then make it pass before moving on to the next test.&lt;/p&gt;

&lt;p&gt;That’s not quite true.  One should do the following:&lt;/p&gt;

&lt;div class=&quot;language-vb highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;write the simplest, meaningful failing test&quot;&lt;/span&gt;
&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;write the minimum production code to make it pass&quot;&lt;/span&gt;
&lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;refactor so the code is nice&quot;&lt;/span&gt;
&lt;span class=&quot;mi&quot;&gt;40&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;goto&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Refactoring should not be delayed; there would be no need to delay it as the code is arguably ‘complete’ at this point (as it does everything that the tests say it should do).&lt;/p&gt;

&lt;p&gt;I must say that I’m not very good at following the above.  It’s hard.  There’s a lot of temptation to take shortcuts; to write more general code than is necessary to make the test pass, etc.&lt;/p&gt;

&lt;p&gt;The traditional TDD approach is to work from the bottom up; developing the model classes that one expects to need.&lt;/p&gt;

&lt;p&gt;The ‘British’ way is to work top-down; starting with a skeleton framework of the whole app and filling in the details as you go in thin, vertical slices of functionality.  This leads to less cruft I would imagine.  This is less popular.  I would imagine that this is because it requires much more upfront setup of your testing framework, as to even write the first test you have to write a lot of support code.&lt;/p&gt;

&lt;p&gt;I recommend the book “&lt;a href=&quot;http://www.growing-object-oriented-software.com/&quot;&gt;Growing Object-Oriented Software, Guided By Tests&lt;/a&gt;” as a good book on that approach.  It gets a bit dull later on but the early stuff is very informative.&lt;/p&gt;

&lt;p&gt;The top-down approach is called the ‘London’ method and the bottom-up the ‘Classic’ or sometimes ‘Chicago’ or ‘Detroit’; as discussed on &lt;a href=&quot;http://programmers.stackexchange.com/questions/123627/what-are-the-london-and-chicago-schools-of-tdd&quot;&gt;stackexchange&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I suspect that TDD discipline is much easier in a pair-programming setting.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>The World's Simplest C# WPF MVVM Example</title>
   <link href="http://markwithall.com/programming/2013/03/01/worlds-simplest-csharp-wpf-mvvm-example.html"/>
   <updated>2013-03-01T00:00:00+00:00</updated>
   <id>http://markwithall.com/programming/2013/03/01/worlds-simplest-csharp-wpf-mvvm-example</id>
   <content type="html">&lt;p&gt;The interesting thing to me about MVVM (Model-View-ViewModel), is that the Model should know about nothing else, the ViewModel should only know about the Model (not the View), and the View should only know about the ViewModel (and not the Model).&lt;/p&gt;

&lt;p&gt;One thing that I’ve wanted to do for quite some time now, is to create a very simple MVVM example for C# WPF.  As this post will show, I’ve finally gotten around to it.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Simple&lt;/em&gt;, in this case, has a few caveats (as one might expect).  I wouldn’t want to write a completely trivial example that didn’t do anything.  With that in mind, let me lay out the ground rules.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Model&lt;/strong&gt;: This can be really simple, the goal here is for the ViewModel not to have to do any of the business logic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ViewModel&lt;/strong&gt;: This should essentially delegate everything to the Model except for exposing data for the View.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;View&lt;/strong&gt;: This should just bind to the ViewModel and make stuff look pretty.&lt;/p&gt;

&lt;p&gt;The example application should have the following features:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Some user input&lt;/li&gt;
  &lt;li&gt;A list of something&lt;/li&gt;
  &lt;li&gt;Some user action (e.g. a button) that can be invoked both via the mouse and a keyboard shortcut&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With those goals in mind, the application we are going to write will allow the user to enter some text in a &lt;em&gt;TextBox&lt;/em&gt; and then press a button (or key) and have that text magically transformed into uppercase.  A history of previous conversions will be recorded and presented in a &lt;em&gt;ListBox&lt;/em&gt; for posterity.  Exciting, eh?&lt;/p&gt;

&lt;h2 id=&quot;the-mvvm-framework&quot;&gt;The MVVM Framework&lt;/h2&gt;

&lt;p&gt;The first thing that we are going to do is to create a minimal MVVM framework for us to use in the rest of the application.  There are two important components of the framework.&lt;/p&gt;

&lt;p&gt;The first is a base class for ViewModel classes.  This handles the implementation of the &lt;em&gt;INotifyPropertyChanged&lt;/em&gt; interface.  This interface allows update messages to be passed to the View.  It should also be noted that all ViewModel classes that are bound to by the View should implement this (even if the values don’t change from the ViewModel) as there is a known memory leak that may occur if they don’t (see &lt;a href=&quot;https://web.archive.org/web/20080514012450/http://support.microsoft.com/kb/938416&quot;&gt;the Microsoft support article&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;The simplest implementation is as follows:&lt;/p&gt;

&lt;div class=&quot;language-c# highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ObservableObject&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;INotifyPropertyChanged&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PropertyChangedEventHandler&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PropertyChanged&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;RaisePropertyChangedEvent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;propertyName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;handler&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PropertyChanged&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;handler&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;nf&quot;&gt;handler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;PropertyChangedEventArgs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;propertyName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This can be expanded in various ways.  For example, we could add checking that the property name exists for the given class.&lt;/p&gt;

&lt;p&gt;The second component is an implementation of the &lt;em&gt;ICommand&lt;/em&gt; interface.  This is what commands in the View are bound to.  There is no default implementation, so we must roll our own.&lt;/p&gt;

&lt;p&gt;The simplest implementation is as follows:&lt;/p&gt;

&lt;div class=&quot;language-c# highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;DelegateCommand&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ICommand&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Action&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;DelegateCommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Action&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_action&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;_action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;CanExecute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;cp&quot;&gt;#pragma warning disable 67
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EventHandler&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CanExecuteChanged&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#pragma warning restore 67
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;One thing to note is that &lt;em&gt;CanExecute&lt;/em&gt; always returns true.  Don’t you just hate it when a button or a menuitem is greyed-out for no apparent reason?  Don’t do it!  Much better to allow the button to be clicked and then give some informative feedback as to why the intended action cannot be carried out.&lt;/p&gt;

&lt;p&gt;Now we have our minimal MVVM framework, we can move on to create our application.&lt;/p&gt;

&lt;h2 id=&quot;the-model&quot;&gt;The Model&lt;/h2&gt;

&lt;p&gt;Our model is simple; consisting of a single &lt;em&gt;TextConverter&lt;/em&gt; class.  To &lt;del&gt;avoid the annoyance of Resharper whinging that the &lt;em&gt;ConvertText&lt;/em&gt; method can be made static&lt;/del&gt; allow the &lt;em&gt;TextConverter&lt;/em&gt; class to conform to the &lt;a href=&quot;http://en.wikipedia.org/wiki/Open/closed_principle&quot;&gt;Open/Closed Principle&lt;/a&gt;, I’ve made the string conversion a parameter.&lt;/p&gt;

&lt;div class=&quot;language-c# highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TextConverter&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_convertion&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;TextConverter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;convertion&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_convertion&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;convertion&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ConvertText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inputText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;_convertion&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;the-viewmodel&quot;&gt;The ViewModel&lt;/h2&gt;

&lt;p&gt;We also only have a single &lt;em&gt;Presenter&lt;/em&gt; class in our ViewModel.  This is, however, slightly more complex than the Model.&lt;/p&gt;

&lt;div class=&quot;language-c# highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Presenter&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ObservableObject&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TextConverter&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_textConverter&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;TextConverter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToUpper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_someText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ObservableCollection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_history&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ObservableCollection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;();&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SomeText&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_someText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;_someText&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;nf&quot;&gt;RaisePropertyChangedEvent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;SomeText&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IEnumerable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;History&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_history&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ICommand&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ConvertTextCommand&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;DelegateCommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ConvertText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ConvertText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;IsNullOrWhiteSpace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SomeText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;AddToHistory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_textConverter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ConvertText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SomeText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;SomeText&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Empty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;AddToHistory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_history&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Contains&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;_history&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Notice that we are inheriting from our MVVM framework &lt;em&gt;ObservableObject&lt;/em&gt;, which provides our implementation of the &lt;em&gt;INotifyPropertyChanged&lt;/em&gt; interface.  Our presenter is exposing three properties that the View can bind to.  We’ll look at them one at a time.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;SomeText&lt;/em&gt; property is the text that the user will enter.  The getter returns the current value of the property.  The View will get this value when it is first bound and then it will only change when it receives a property change notification.  When the setter is called with a new value, the property backing field is updated and then the event is raised to inform observers that the value has changed.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;History&lt;/em&gt; property is the list of previous converted values.  It is backed by an &lt;em&gt;ObservableCollection&lt;/em&gt;, which essentially does everything for us.  Whenever we add something to it, the View is notified, so it can update.&lt;/p&gt;

&lt;p&gt;The final property is &lt;em&gt;ConvertTextCommand&lt;/em&gt;.  This returns an &lt;em&gt;ICommand&lt;/em&gt; using our &lt;em&gt;DelegateCommand&lt;/em&gt; class from our framework.  This can be bound to such things as buttons and key presses in the View.  We’ve hooked it up to call our &lt;em&gt;ConvertText&lt;/em&gt; method when executed.  This method uses our &lt;em&gt;TextConverter&lt;/em&gt; field (which we’ve set up to convert text to uppercase) and then adds the converted value to the history list.  Finally, it clears the value of &lt;em&gt;SomeText&lt;/em&gt; (which will, of course, notify the View).  One last thing to note is that &lt;em&gt;History&lt;/em&gt; is going to be bound to a &lt;em&gt;ListBox&lt;/em&gt;, which can do strange things when selecting an item where there are duplicates.  This is the reason for not adding duplicate strings to the history here.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;[Update 2016-09-23: added handling for the case when&lt;/em&gt; SomeText &lt;em&gt;is null; which would crash the application. Thanks to &lt;a href=&quot;https://github.com/MarkWithall/worlds-simplest-csharp-wpf-mvvm-example/issues/1&quot;&gt;ajeebkp23&lt;/a&gt; for pointing this out.]&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That’s all of the coding out of the way with, now we can move on to ‘drawing’ the UI.&lt;/p&gt;

&lt;h2 id=&quot;the-view&quot;&gt;The View&lt;/h2&gt;

&lt;p&gt;The nice thing about WPF for me is that we can define the entire user interface in XML, without having to write a single line of code.  We just need to bind widgets to the ViewModel to read and write data.&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;UserControl&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;

    &lt;span class=&quot;nt&quot;&gt;&amp;lt;UserControl.InputBindings&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;KeyBinding&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Key=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Enter&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Command=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{Binding ConvertTextCommand}&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/UserControl.InputBindings&amp;gt;&lt;/span&gt;
    
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;StackPanel&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Height=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;336&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;Label&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Foreground=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Blue&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Margin=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;5,5,5,0&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Text To Convert&lt;span class=&quot;nt&quot;&gt;&amp;lt;/Label&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;TextBox&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Text=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{Binding SomeText, UpdateSourceTrigger=PropertyChanged}&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Margin=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;5&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;Label&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Foreground=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Blue&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Margin=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;5,5,5,0&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;History&lt;span class=&quot;nt&quot;&gt;&amp;lt;/Label&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;ListBox&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;ItemsSource=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{Binding History}&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Height=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;200&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Margin=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;5&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;Button&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Command=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{Binding ConvertTextCommand}&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Margin=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;5&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Convert&lt;span class=&quot;nt&quot;&gt;&amp;lt;/Button&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/StackPanel&amp;gt;&lt;/span&gt;
    
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/UserControl&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As you can see above, widgets such as labels and textboxes are just XML elements.  The &lt;em&gt;Text&lt;/em&gt; attribute of the &lt;em&gt;TextBox&lt;/em&gt; has been bound to &lt;em&gt;SomeText&lt;/em&gt; in our presenter and the &lt;em&gt;ItemsSource&lt;/em&gt; attribute of the &lt;em&gt;ListBox&lt;/em&gt; has been bound to &lt;em&gt;History&lt;/em&gt;.  Notice that the &lt;em&gt;ConvertTextCommand&lt;/em&gt; property has been bound to two things, the &lt;em&gt;KeyBinding&lt;/em&gt; and the &lt;em&gt;Button&lt;/em&gt;.  We needn’t have stopped there.  We could have bound it to an item in a menu too.  In fact, we can bind anything as many times as we like, allowing us to have several different ways of displaying the same data.  We could, for example, have a list of numbers in our ViewModel that is bound both to a table of data and to a chart.&lt;/p&gt;

&lt;p&gt;Before we move on to the definition of the &lt;em&gt;Window&lt;/em&gt; that the &lt;em&gt;UserControl&lt;/em&gt; sits in, I want to take a quick look at the code behind for this control.&lt;/p&gt;

&lt;div class=&quot;language-c# highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;partial&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ConverterControl&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ConverterControl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;InitializeComponent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Notice that there is absolutely nothing superfluous in it whatsoever.  There’s no code to read and write the text in the textbox; no event handlers to process button clicks. Everything is done through binding to the ViewModel.  You literally can’t have less code in the &lt;em&gt;.xaml.cs&lt;/em&gt; file.  This makes our application much easier to write tests for.&lt;/p&gt;

&lt;p&gt;Our final piece of UI description is the main window.&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;Window&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;...&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;Title=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Converter&quot;&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;MinWidth=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;300&quot;&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;ResizeMode=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;NoResize&quot;&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;SizeToContent=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;WidthAndHeight&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;Window.DataContext&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;local:Presenter/&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/Window.DataContext&amp;gt;&lt;/span&gt;
    
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;local:ConverterControl/&amp;gt;&lt;/span&gt;
    
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/Window&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This has two points of interest.  Firstly, we are specifying that the context for the Window is an instance of the &lt;em&gt;Presenter&lt;/em&gt; class in our ViewModel (which will be created for us when the window is created).  Secondly, we are specifying that the UI is made up of a &lt;em&gt;ConverterControl&lt;/em&gt; that we defined above, which will inherit that data context.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;[Update 2018-02-15: note that the namespace ‘local’ assumes that both &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Presenter&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ConverterControl&lt;/code&gt; are in the same namespace as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MainWindow&lt;/code&gt;. Add additional namespaces as required for your own structure. Thanks to &lt;a href=&quot;https://github.com/MarkWithall/worlds-simplest-csharp-wpf-mvvm-example/issues/5&quot;&gt;yanniqq&lt;/a&gt; for highlighting the issue.]&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;And that is basically it.  All together around 35 real lines of C# code and about 18 lines of XAML.&lt;/p&gt;

&lt;p&gt;The full code is available on &lt;a href=&quot;https://github.com/MarkWithall/worlds-simplest-csharp-wpf-mvvm-example&quot;&gt;github&lt;/a&gt;.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Create an Outlook 2010 Search Folder using VBA</title>
   <link href="http://markwithall.com/programming/2013/02/01/create-outlook-2010-search-folder.html"/>
   <updated>2013-02-01T00:00:00+00:00</updated>
   <id>http://markwithall.com/programming/2013/02/01/create-outlook-2010-search-folder</id>
   <content type="html">&lt;p&gt;Earlier this week I discovered that Microsoft Outlook 2010 (and most likely other versions too) isn’t very good at anything beyond very, very simple searches.  This is even more true of searches used to create Search Folders (which appear to have more limitations on them than the Search box, for no apparent reason).  I, therefore, set about learning VBA, so that I could have more control over the creation of Search Folders.&lt;/p&gt;

&lt;p&gt;In this particular case I was wanting to create a Search Folder containing all emails that weren’t from one of my company’s domains.  This turned out to be surprisingly difficult; as many emails only display the name of the sender and not their address.  The search only appears to search the displayed string, rather than the actual sender address.  This made me sad.&lt;/p&gt;

&lt;p&gt;Starting from the top and working our way down, the most difficult part of the exercise was the creation of the filter string.  These are rather SQL-looking beasts.  It turned out that looking at the sender email address is a rather convoluted task that involves comparing the value of “http://schemas.microsoft.com/mapi/proptag/0x0C1F001F” with the string you are interested in.  I’ve absolutely no idea why, as most of the other email header fields have far more sensible names.  Inventing a CreateSearchFolder method that takes the parameters of the Store name, the path of the folder to search in, the filter and the name of the Search Folder to create; we end up with the following:&lt;/p&gt;

&lt;div class=&quot;language-vb highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;Sub&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;AddNotInternalSearchFolder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;Const&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;PR_SENDER_EMAIL_ADDRESS_W&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;http://schemas.microsoft.com/mapi/proptag/0x0C1F001F&quot;&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;Dim&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;filter&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;filter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;NOT (&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PR_SENDER_EMAIL_ADDRESS_W&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; LIKE '%@markwithall.com%')&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;
             &lt;span class=&quot;s&quot;&gt;&quot;AND NOT (&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PR_SENDER_EMAIL_ADDRESS_W&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; LIKE '%@markwithall.co.uk%')&quot;&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;Call&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CreateSearchFolder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;MarkWithall&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;'\MarkWithall\Inbox'&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Not Internal&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;End&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;Sub&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The method to create a Search Folder is then quite straightforward; remembering, of course, to check that the folder we are creating doesn’t already exist.  It’s just a simple case of calling the AdvancedSearch method of Application, with the data we just passed, to create a search object and then saving it to the relevant name.&lt;/p&gt;

&lt;div class=&quot;language-vb highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;Sub&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;CreateSearchFolder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;storeName&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                       &lt;span class=&quot;n&quot;&gt;folderPath&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                       &lt;span class=&quot;n&quot;&gt;filter&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                       &lt;span class=&quot;n&quot;&gt;folderToCreate&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;If&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SearchFolderExists&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;storeName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;folderToCreate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;Then&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;MsgBox&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Search folder '&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;folderToCreate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;' already exists&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;Else&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;Dim&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;objSearch&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Search&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;Set&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;objSearch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Application&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AdvancedSearch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;folderPath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                                   &lt;span class=&quot;n&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                                   &lt;span class=&quot;k&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                                   &lt;span class=&quot;s&quot;&gt;&quot;SearchFolder&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;objSearch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Save&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;folderToCreate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;MsgBox&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Done!&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;End&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;If&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;End&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;Sub&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Finally, we just need to implement the check that the Search Folder doesn’t already exist.  This just involves looping through the list of Search Folders and checking that none of them have the name we’ve provided.&lt;/p&gt;

&lt;div class=&quot;language-vb highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;Function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SearchFolderExists&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;storeName&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;folderName&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;As&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;SearchFolderExists&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;False&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;For&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;Each&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;store&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;In&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Application&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Stores&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;storeName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetSearchFolders&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;If&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;store&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;folderName&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;Then&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;SearchFolderExists&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;True&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;End&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;If&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;Next&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;End&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;Function&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And that’s it.  Now, in the future, if we require any other complicated Search Folders, it’s just a case of modifying the filter string and providing a new name.&lt;/p&gt;

&lt;p&gt;The end!  It’s a mini adventure.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Speed Reader Bookmarklet</title>
   <link href="http://markwithall.com/programming/2013/01/09/speed-reader-bookmarklet.html"/>
   <updated>2013-01-09T00:00:00+00:00</updated>
   <id>http://markwithall.com/programming/2013/01/09/speed-reader-bookmarklet</id>
   <content type="html">&lt;p&gt;The other day on &lt;a href=&quot;http://twit.tv/&quot;&gt;TWiT&lt;/a&gt; I heard about an iPad app called &lt;a href=&quot;http://readquickapp.com/&quot;&gt;Read Quick&lt;/a&gt;.  I thought that this sounded like a brilliant idea and wouldn’t it be great if one could just select some text in a webpage, press a button and have the same thing happen.&lt;/p&gt;

&lt;p&gt;After some consideration, I decided that it couldn’t be too hard to write a bookmarklet to do something similar.  All that would be required would be to get the selected text, split it into words and then loop through the list of words displaying one at a time.&lt;/p&gt;

&lt;p&gt;It didn’t take very long to write.  I then threw it on github for the world to play with.  It can be found &lt;a href=&quot;http://www.markwithall.com/speedreader/&quot;&gt;here&lt;/a&gt;.  The source can be found &lt;a href=&quot;https://github.com/markwithall/speedreader/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There is still plenty to do to make the tool better: it doesn’t look very pretty, it’s not been testing on most browsers (only Chrome and Safari, so far) and you can’t configure it in any way (particularly the speed, which is fixed at 400 words per minute).&lt;/p&gt;

&lt;p&gt;Hopefully, over the next week, I’ll have sufficient time to tidy it up a bit and test it on other browsers but even in it’s current state, I’m already finding it an invaluable tool.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>How to extract text from a Microsoft Word document in C#</title>
   <link href="http://markwithall.com/programming/2013/01/04/word-to-text.html"/>
   <updated>2013-01-04T00:00:00+00:00</updated>
   <id>http://markwithall.com/programming/2013/01/04/word-to-text</id>
   <content type="html">&lt;p&gt;Earlier this week, I had cause to extract the text from a Microsoft Word document.  Some naughty people had decided that the best way to export a CSV file from their application, was to save it as text in a .doc file.  May &lt;a href=&quot;https://www.facebook.com/HarryTheRottweiler&quot;&gt;my dog&lt;/a&gt; have mercy on their sole!&lt;/p&gt;

&lt;p&gt;One could approach this problem in a nice complicated way, using &lt;a href=&quot;http://www.codeproject.com/Articles/13391/Using-IFilter-in-C&quot;&gt;IFilter&lt;/a&gt; for example, but I’ve taken the brave decision to assume that someone using software that exports Word documents will have a copy of Word to hand (risky!).  This allows the much simpler solution of using Interop.&lt;/p&gt;

&lt;p&gt;The first step is to add &lt;code&gt;Microsoft.Office.Interop.Word&lt;/code&gt; to project references.&lt;/p&gt;

&lt;p&gt;We don’t want that nasty Interop stuff leaking all over the place, so I’ve created a nice simple little class that hides it away with a nicer interface.  Notice, I’ve made the class implement IDisposable, so that we can encapsulate the whole usage of Word in a using block; making the scope completely obvious.&lt;/p&gt;

&lt;div class=&quot;language-c# highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Microsoft.Office.Interop.Word&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;WordApplication&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IDisposable&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Application&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_application&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Document&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;WordApplication&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_application&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ApplicationClass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;docFilename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;docFilenameAsObject&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;docFilename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_document&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_application&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Documents&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;ref&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;docFilenameAsObject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SaveAsText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;outputTxtFilename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;outputTxtFilenameAsObject&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;outputTxtFilename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;formatAsObject&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;WdSaveFormat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;wdFormatText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SaveAs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;ref&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;outputTxtFilenameAsObject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;ref&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;formatAsObject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Dispose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_application&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Application&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Quit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This leaves us with a much nicer API to work with.  We can now simply create a new .txt file from the old .doc as follows.&lt;/p&gt;

&lt;div class=&quot;language-c# highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ConvertDocToTxt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;docFilename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;txtFilename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;application&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;WordApplication&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
       &lt;span class=&quot;n&quot;&gt;application&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;docFilename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
       &lt;span class=&quot;n&quot;&gt;application&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SaveAsText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;txtFilename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Obviously, wrapping that in a &lt;code&gt;try/catch&lt;/code&gt; block or similar, with appropriate exception handling would be the way forward.  In real life one would also most likely introduce some interface to allow mocking, etc.&lt;/p&gt;

&lt;p&gt;To conclude:&lt;/p&gt;

&lt;p&gt;Pros&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Simple&lt;/li&gt;
  &lt;li&gt;Short&lt;/li&gt;
  &lt;li&gt;Supports both .doc and .docx (and probably other formats too)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cons&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Requires Word&lt;/li&gt;
  &lt;li&gt;Slow&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Exercise for the reader: now you can all go away and write a little app to add to a right-click menu item in explorer to convert Word docs to text.&lt;/em&gt;&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>End Of NaNoWriMo 2012</title>
   <link href="http://markwithall.com/nano/2012/11/30/end-of-nanowrimo.html"/>
   <updated>2012-11-30T00:00:00+00:00</updated>
   <id>http://markwithall.com/nano/2012/11/30/end-of-nanowrimo</id>
   <content type="html">&lt;p&gt;It is now the end of another year of &lt;a href=&quot;http://www.nanowrimo.org/&quot;&gt;NaNoWriMo&lt;/a&gt;.  I’ve picked up my fourth consecutive win.  I actually reached 50,000 words last Sunday (day 25) and finished the novel itself on Tuesday (day 27).  The final word count was 53,297.&lt;/p&gt;

&lt;p&gt;Below is a graph of how my word count increased each day against the target word count.  Note the exceedingly straight line.  This is how my NaNos typically go; doing approximately the required words per day (but not less, if I can avoid it) and finishing on the last Sunday of the month (which is when we have our weekly meetings).&lt;/p&gt;

&lt;p&gt;&lt;span id=&quot;words_by_day_graph&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I’ve put the novel away now and will, hopefully, come back to it at some future time to write a second draft.  My aim for the next year is to try and edit one of my previous NaNo novels and self-publish it on the iBookstore and Kindle store.  The publishing itself is fairly easy, it’s the getting the novel into a fit state that I can bare someone else reading it that is going to be the challenging part.&lt;/p&gt;

&lt;p&gt;On Sunday is the TGIO party, where we all celebrate not having to write again for another year.  The people in the Leicester group have all been amazing; both the old guard and the new recruits.  It just wouldn’t be the same doing this in solitary confinement year after year.  Thank you to you all.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>How to partition a list in C#</title>
   <link href="http://markwithall.com/programming/2012/11/24/list-partition.html"/>
   <updated>2012-11-24T00:00:00+00:00</updated>
   <id>http://markwithall.com/programming/2012/11/24/list-partition</id>
   <content type="html">&lt;p&gt;Just to test out how the syntax highlighting works for posting blog entries, here’s a short piece of code that I wrote a while ago to partition a list into fixed-size blocks.&lt;/p&gt;

&lt;div class=&quot;language-c# highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IEnumerable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IEnumerable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Partition&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IEnumerable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Any&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Take&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;list&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Skip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And for extra credit, here are some extensions to make it work for strings too.&lt;/p&gt;

&lt;div class=&quot;language-c# highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IEnumerable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Partition&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Partition&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Select&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AsString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;AsString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IEnumerable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;charList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;charList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;These were originally posted by me on &lt;a href=&quot;http://stackoverflow.com/questions/1396048/c-sharp-elegant-way-of-partitioning-a-list/9601647#9601647&quot;&gt;stackoverflow&lt;/a&gt;.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>NaNoWriMo 2012 - Day 11</title>
   <link href="http://markwithall.com/nano/2012/11/11/nanowrimo-day-11.html"/>
   <updated>2012-11-11T00:00:00+00:00</updated>
   <id>http://markwithall.com/nano/2012/11/11/nanowrimo-day-11</id>
   <content type="html">&lt;p&gt;Have reached 20,001 words so far.  About two days ahead of target.&lt;/p&gt;

&lt;p&gt;Today I’m going to look at some of the content of my novel.  This year the story involves time travel.  This, inevitably, involves putting down a certain amount of rules, which dictate how time travel is allowed to work.  There are two main parts to this in the story.  The first part is the practical side of thing, &lt;em&gt;i.e.&lt;/em&gt;, how time travel works.  And the second part is the legal aspects of it, which is one of the central parts of the story.&lt;/p&gt;

&lt;h2 id=&quot;the-rules-of-time-travel&quot;&gt;The Rules Of Time Travel&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;There is only one timeline (not multiple universes that are split off at each decision).  Change the past; change the single present.&lt;/li&gt;
  &lt;li&gt;Time travel can only visit the past.  The future hasn’t happened yet and therefore doesn’t exist.&lt;/li&gt;
  &lt;li&gt;Time travel takes a great deal of energy and hence is very expensive and can only be done by the select few.&lt;/li&gt;
  &lt;li&gt;Travelling back in time works like stretching a piece of elastic holding you to the present; this has two consequences:
    &lt;ul&gt;
      &lt;li&gt;The vast amount of energy taken by time travel increases in proportion to the amount of time travelled.  Travelling back to the time of Jesus is not currently feasible.  A few hundred years is the most travelled so far.&lt;/li&gt;
      &lt;li&gt;Eventually, the person travelling will be pulled back to the present.  Usually, a person can only stay for a few hours in the past.  No one has managed more than a couple of days.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;the-law-of-time-travel&quot;&gt;The Law Of Time Travel&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Minor changes to the past, and hence knock on effects to the present, are tolerated.&lt;/li&gt;
  &lt;li&gt;If a major change is accidentally effected, one can do whatever is necessary to correct the course to result in minimal effect on the present.&lt;/li&gt;
  &lt;li&gt;For trials involving temporal crime, witnesses may be sent back to observe the events.  No more than one witness is allowed per event, to avoid a crowd affecting the events.&lt;/li&gt;
  &lt;li&gt;Any major impact on the past will involve a trial to determine if that impact was accidental and the subsequent corrections necessary.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I shall endeavour to update this list with additional details as they arise, and any corrections that are necessary for a consistent set of rules.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>NaNoWriMo 2012 - Day 4</title>
   <link href="http://markwithall.com/nano/2012/11/04/nanowrimo-day-4.html"/>
   <updated>2012-11-04T00:00:00+00:00</updated>
   <id>http://markwithall.com/nano/2012/11/04/nanowrimo-day-4</id>
   <content type="html">&lt;p&gt;My word count is up to 7695 words.  This is very pleasing as it is ahead of the target.&lt;/p&gt;

&lt;p&gt;Today I shall describe my approach to structuring novels to make them easier to write during &lt;a href=&quot;http://www.nanowrimo.org/&quot;&gt;NaNoWriMo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The first year that I did NaNoWriMo (2009) I chose to write 100 chapters of 500 words each.  That way I could come up with a simple concept to cover for each chapter and not have to write too much about it.  This worked very well but didn’t allow much elaboration on ideas during a chapter.&lt;/p&gt;

&lt;p&gt;In 2010, I changed to an approach of writing a chapter per day (30 chapters in total).  This was subdivided into three parts of 10 chapter each.  This worked much better, in that it allowed me to be much more expansive in my writing but on the downside it led to a lot of waffling in places that didn’t warrant a chapter of that length.&lt;/p&gt;

&lt;p&gt;I tried a more fluid approach in 2011, where I wrote until I had finished a chapter.  I ended up with a total 20 chapters; plus a prologue and epilogue.  This didn’t really deal with the random waffling problem but that is probably a side effect for forcing myself to invent 50,000 words in one month.&lt;/p&gt;

&lt;p&gt;This year, I’ve gone back to the 30 chapters of around 1667 words each, splitting each into a random number of scenes, as required.  So far, the approach seems to be working but I’d have preferred to work out what the 30 chapters were going to be in advance, so I would be sure that the story would reach the end at the right time and cover all the content.&lt;/p&gt;

&lt;p&gt;I find this sort of structural approach to NaNoWriMo to help me get through it more easily.  It probably doesn’t help towards getting particularly good content though but that’s another problem.&lt;/p&gt;

&lt;p&gt;I shall defer the discussion of this year’s novel’s content until next time, due to wanting to keep the length of these posts fairly short (so as not to bore anyone; particularly myself when proof-reading).&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>NaNoWriMo 2012 - Day 3</title>
   <link href="http://markwithall.com/nano/2012/11/03/nanowrimo-day-3.html"/>
   <updated>2012-11-03T00:00:00+00:00</updated>
   <id>http://markwithall.com/nano/2012/11/03/nanowrimo-day-3</id>
   <content type="html">&lt;p&gt;I’ve finally got time to actually write a blog post.  We’re already just over two days in and I’m on target so far.  I’ve written 4381 words at the time of writing this but I’m told there is a widget I can include on this site that will show live word counts.  I shall investigate this later.&lt;/p&gt;

&lt;p&gt;As this is the first proper NaNo post, and I am a nerd, I shall start by detailing the writing tools.&lt;/p&gt;

&lt;p&gt;The majority of the writing will be done using &lt;a href=&quot;http://www.literatureandlatte.com/scrivener.php&quot;&gt;Scrivener 2&lt;/a&gt; for Mac.  I bought this earlier in the year thanks to a 50% discount received for winning NaNoWriMo last year.  My usage of the tool is fairly basic at this first-draft stage.  I create a folder for each chapter (currently exotically title ‘Chapter 1’, ‘Chapter 2’, etc.) and I create a text file for each scene within each chapter.  Scrivener has a nice feature of letting you see all the scenes in a chapter in one screen that you can scroll up and down, with nice scene break markers between each.&lt;/p&gt;

&lt;p&gt;In addition to Scrivener, I am saving the scrivener file to my &lt;a href=&quot;https://www.dropbox.com&quot;&gt;Dropbox&lt;/a&gt; folder, so that it is automatically synced to the Internet (and hence to anything else I open it with) every time I save the file.  This way, if my laptop were to accidentally be run over by a tank or flushed down the toilet, I won’t lose the work so far.&lt;/p&gt;

&lt;p&gt;The final, and probably somewhat less standard, tool that I’m using is &lt;a href=&quot;http://git-scm.com&quot;&gt;git&lt;/a&gt; via the &lt;a href=&quot;https://github.com&quot;&gt;github&lt;/a&gt; user interface.  This means that if I manage to badly corrupt the file in someway, or delete large parts unintentionally, I can just roll back to an earlier version of the novel without losing much.&lt;/p&gt;

&lt;p&gt;I shall sign off for now.  Next time I shall recount my approach to structuring novels to be written during NaNoWriMo, and maybe include some details of the story that I’m writing.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Introduction To NaNoWriMo 2012</title>
   <link href="http://markwithall.com/nano/2012/10/31/intro-to-nanowrimo.html"/>
   <updated>2012-10-31T00:00:00+00:00</updated>
   <id>http://markwithall.com/nano/2012/10/31/intro-to-nanowrimo</id>
   <content type="html">&lt;p&gt;This November I will be doing &lt;a href=&quot;http://nanowrimo.org/en/participants/scroog1/&quot;&gt;NaNoWriMo&lt;/a&gt; for the fourth time.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>24 Hour Comics Day 2012 (Saturday October 20th 2012)</title>
   <link href="http://markwithall.com/24hcd2012/2012/10/20/24-hour-comics-day-2012.html"/>
   <updated>2012-10-20T00:00:00+00:00</updated>
   <id>http://markwithall.com/24hcd2012/2012/10/20/24-hour-comics-day-2012</id>
   <content type="html">&lt;h2 id=&quot;introduction---0959&quot;&gt;Introduction - 09:59&lt;/h2&gt;
&lt;p&gt;Today I’m randomly doing &lt;a href=&quot;http://www.24hourcomicsday.com/&quot;&gt;24 Hour Comics Day&lt;/a&gt;.  The goal is to create a 24 page comic in 24 hours (or, in my case, before I fall asleep).  I shall primarily be drawing the comic book in Sketchbook Pro on the iPad.  Hopefully, updates will be posted here regularly throughout the day.&lt;/p&gt;

&lt;h2 id=&quot;1127&quot;&gt;11:27&lt;/h2&gt;
&lt;p&gt;A rather slow start.  I’ve decided to just start drawing and see where the comic book goes.  Here is the first page.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/24hcd2012/page01.png&quot; alt=&quot;Page 1&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;1248&quot;&gt;12:48&lt;/h2&gt;
&lt;p&gt;Still behind schedule.  No plot yet.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/24hcd2012/page02.png&quot; alt=&quot;Page 2&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;1430&quot;&gt;14:30&lt;/h2&gt;
&lt;p&gt;Delayed by the arrival of lunch.  A second character has arrived that clearly needs rescuing by our hero Bob.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/24hcd2012/page03.png&quot; alt=&quot;Page 3&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;1703&quot;&gt;17:03&lt;/h2&gt;
&lt;p&gt;After several hours of aimless doodling, I’m going to call time.  Lack of ideas and ability to draw and particularly lack of ability to colour have left me too far behind.  I shall try to spend more time over the next year learning to draw and paint and see if I’m in a better position for next year’s event.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>iOS Audio Playback - What Does 2x Mean?</title>
   <link href="http://markwithall.com/misc/2012/08/02/ios-audio-playback-speed.html"/>
   <updated>2012-08-02T00:00:00+00:00</updated>
   <id>http://markwithall.com/misc/2012/08/02/ios-audio-playback-speed</id>
   <content type="html">&lt;p&gt;For quite some time it has bugged me that selecting 2x in the Music app on iOS doesn’t play back the selected audio in half the time.  I have, therefore, taken the time to measure the playback time in my two most used apps: Apple Podcasts and Audible.&lt;/p&gt;

&lt;p&gt;The experiment was simple: play 1 minute of audio at each of the different speed options and time them.  The results were as follows (times are only approximate, as they were manually timed using my wristwatch).&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Podcasts Hair (2x): 41s&lt;/li&gt;
  &lt;li&gt;Podcasts Tortoise (0.5x): 1m19s&lt;/li&gt;
  &lt;li&gt;Audible 1.5x: 48s&lt;/li&gt;
  &lt;li&gt;Audible 2x: 41s&lt;/li&gt;
  &lt;li&gt;Audible 3x: 31s&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This doesn’t really shed any light on the naming of the speed options but at least I can now judge roughly how long it will take to play an audio file of a given length at each of the speeds.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>World Snooker Championship 2010</title>
   <link href="http://markwithall.com/misc/2010/04/21/world-snooker-championship.html"/>
   <updated>2010-04-21T00:00:00+00:00</updated>
   <id>http://markwithall.com/misc/2010/04/21/world-snooker-championship</id>
   <content type="html">&lt;p&gt;On Monday (19th April 2010) my wife and I visited Sheffield to watch the World Snooker Championship first round match between Mark King and Steve Davis at the Crucible Theatre.&lt;/p&gt;

&lt;p&gt;This was the first time I had been to Sheffield and my first impression was that it had a very large number of litter bins in the town centre.  Well done Sheffield.&lt;/p&gt;

&lt;p&gt;The Crucible Theatre was a surprisingly small and intimate venue.  The views that we had from seats 62F and 63F were excellent.  After years of watching the snooker on the television, the table was unexpectedly hi-def.  Even if we had been at the back of the theatre, the view of the game would have been excellent.&lt;/p&gt;

&lt;p&gt;Steve Davis was making his 30th appearance at the World Snooker Championship and got a standing ovation when he entered the arena (our participation in which was covered nicely by the BBC).&lt;/p&gt;

&lt;p&gt;The match was very entertaining, with a nice mix of big breaks and tactical play.  The highlight of the first half was when Marcus Campbell (playing on the other table) blew his nose very loudly during one of Mark King’s shots.  A similar situation occurred in the second half, when Steve Davis was distracted during a shot by a member of the audience stifling a sneeze very loudly.&lt;/p&gt;

&lt;p&gt;The session ended with Mark King leading 5-4; though Steve Davis went on to book his place in the second round, to play John Higgins, with a 10-9 win.&lt;/p&gt;

&lt;p&gt;Leaving the theatre we were met with a large queue for the parking meter, so we went down to one on a lower level of the car park where we found no one at all.  It was very enjoyable to drive passed the long queue a minute later on our way home.&lt;/p&gt;

&lt;p&gt;Bed was achieved before 1am, despite the late finish.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>3D Movie Rant</title>
   <link href="http://markwithall.com/misc/2010/03/31/3d-movie-rant.html"/>
   <updated>2010-03-31T00:00:00+00:00</updated>
   <id>http://markwithall.com/misc/2010/03/31/3d-movie-rant</id>
   <content type="html">&lt;p&gt;I’ve recently seen two of the new wave of 3D movies sweeping across the globe (Avatar and Alice in Wonderland).  These movies have received great praise.  However, I’d like to take some time out to step back and take an ‘objective’ look at the 3D element of these movies.&lt;/p&gt;

&lt;p&gt;Firstly, Avatar.  I, rather carelessly, went to see this film whilst wearing glasses.  This is not, in general, a good idea (unless, of course, that is the only way you are able to see).  The problem is that these 3D films require you to wear another pair of glasses.  This second pair of glasses rests in an uncomfortable possible further down the nose and gives the constant feeling of being about to fall off (the glasses, not the nose).  The film itself looked very nice; as long as the shots were wide shots of the open countryside.  Any close up shots had the problem that most of the frame is out of focus, which is perfectly fine in 2D but the brain doesn’t seem to be able to cope with it in 3D and gives many people headaches when looking away from the focused areas.  Having the whole frame in focus would be a great improvement to 3D films (though may be hard in practice).  Another close up element that cause problems was rapid movement across the screen.  The picture seemed unable to keep up with this and cause the image to be very blurred.  More frames per second would probably help.  The final issue was that, on several occasions, things poked unnaturally far out of the screen; making it appear has if the objects in question had dramatically increased in length.&lt;/p&gt;

&lt;p&gt;Now on to Alice in Wonderland.  This had the same problems as Avatar.  However, an additional thing that I noticed was how, often, people didn’t seem to really be part of the scene.  They floated on top of the scene with a shiny glow around them.  This may be fine in Wonderland but I doubt it was supposed to happen in the ‘real’ world scenes.  This may have been an artefact of the CGI processing used in the film.&lt;/p&gt;

&lt;p&gt;The two films themselves weren’t bad but I suspect I would have enjoyed them much more in their 2D versions.  I’m sure that many of these issues will be ironed out in the coming years.  The frame rate is a particular issue that is long overdue being addressed (even for 2D films).&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>My 10 Favourite Free iPhone Apps</title>
   <link href="http://markwithall.com/misc/2010/03/04/top-10-iphone-apps.html"/>
   <updated>2010-03-04T00:00:00+00:00</updated>
   <id>http://markwithall.com/misc/2010/03/04/top-10-iphone-apps</id>
   <content type="html">&lt;p&gt;Here are some of my favourite iPhone apps; in no particular order (well, in the order they are in on my phone).&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;http://itunes.apple.com/gb/app/facebook/id284882215?mt=8&quot;&gt;Facebook&lt;/a&gt; - Access to the popular social networking site.  Most of the important functionality is there now and it should only get better with time.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://itunes.apple.com/gb/app/echofon-for-twitter/id286756410?mt=8&quot;&gt;Echofon&lt;/a&gt; - The easiest to use of the twitter clients.  Only a couple of issues: it occasionally can’t connect to twitter and it only supports one account.  Most of the other free clients support multiple accounts but are nowhere near as nice to use.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://itunes.apple.com/gb/app/yahoo-messenger/id309219097?mt=8&quot;&gt;Yahoo! Messenger&lt;/a&gt; - Has push messaging, which means you don’t have to be in the application to receive messages.  It even works in standby mode.  Obviously only useful if you only want to use Yahoo!  &lt;a href=&quot;http://itunes.apple.com/gb/app/meebo/id351727311?mt=8&quot;&gt;Meebo&lt;/a&gt; and &lt;a href=&quot;http://itunes.apple.com/gb/app/im-lite/id285688934?mt=8&quot;&gt;IM+&lt;/a&gt; are superior if you want to connect to multiple things at the same time.  &lt;a href=&quot;http://itunes.apple.com/gb/app/skype/id304878510?mt=8&quot;&gt;Skype&lt;/a&gt; is also good.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://itunes.apple.com/gb/app/dropbox/id327630330?mt=8&quot;&gt;Dropbox&lt;/a&gt; - An excellent way to store files on the iPhone that you want to be able to access from anywhere.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://itunes.apple.com/gb/app/imdb-movies-tv/id342792525?mt=8&quot;&gt;IMDb&lt;/a&gt; - A dedicated client for the IMDb.  Much better suited to the iPhone than the website.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://itunes.apple.com/gb/app/goodreader-lite-large-pdf/id306722910?mt=8&quot;&gt;GoodReader&lt;/a&gt; - A very good PDF reader.  Much better than the build-in PDF support.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://itunes.apple.com/gb/app/tvguide-co-uk-tv-guide/id317212648?mt=8&quot;&gt;TVGuide&lt;/a&gt; - UK Television listing.  ‘Nuff said.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://itunes.apple.com/gb/app/fstream/id289892007?mt=8&quot;&gt;FStream&lt;/a&gt; - Internet radio player.  Supports all of the BBC Radio streams.  The streams can be found at &lt;a href=&quot;http://bbcstreams.com/&quot;&gt;bbcstreams.com&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://itunes.apple.com/gb/app/stanza/id284956128?mt=8&quot;&gt;Stanza&lt;/a&gt; - An excellent eBook reader with access to many free books.  One can also buy books from various stores within the app or upload them via wireless from the Mac.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://itunes.apple.com/gb/app/glaurung-chess/id305558605?mt=8&quot;&gt;Glaurung Chess&lt;/a&gt; - Probably the best free Chess app.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In addition, here are a couple of good mobile websites.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;http://iphone.tvcatchup.com/&quot;&gt;TVCatchup&lt;/a&gt; - A live broadcast of many of the Freeview channels.&amp;lt;/li&amp;gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.bbc.co.uk/mobile/iplayer/&quot;&gt;BBC iPlayer&lt;/a&gt; - Access to the BBC television shows.&amp;lt;/li&amp;gt;&lt;/li&gt;
&lt;/ol&gt;

</content>
 </entry>
 
 <entry>
   <title>Proteus - Leicester Comedy Festival 2010</title>
   <link href="http://markwithall.com/misc/2010/02/23/proteus.html"/>
   <updated>2010-02-23T00:00:00+00:00</updated>
   <id>http://markwithall.com/misc/2010/02/23/proteus</id>
   <content type="html">&lt;p&gt;Last Monday (15th February 2010) I, and my trusty sidekick, attended the opening night of the Proteus show at the Leicester Comedy Festival.  The show consisted of a number of short plays of varying styles [full disclosure: one was written and directed by my wife].&lt;/p&gt;

&lt;p&gt;The overall standard of both writing and acting was surprisingly high for an amateur student production.  In addition to the quality of the plays, several other aspects of the evening made it entertaining.&lt;/p&gt;

&lt;p&gt;Firstly, the venue, The Crumbing Cookie (an establishment that, I assume, sells a variety of biscuit-like comestibles during the day), was incredibly small.  So small, in fact, that our vantage point on the front row was effectively on the stage, allowing physical contact with the actors during various particularly vigorous scenes.&lt;/p&gt;

&lt;p&gt;The second entertainment was the artificial addition of several constraints on my sidekick’s and my style of laughing (one for each play).  Laughing styles included: laughing at as low a pitch as possible, only laughing through the nose, and laughing inwardly.  These added to the, already considerable, humour of the evening; and disturbed several other members of the audience too.&lt;/p&gt;

&lt;p&gt;The plays themselves were generally quite surreal.  The final lines of the wife’s play nearly gave the sidekick a hernia.  I particularly enjoyed the musical plays and the play involving a tryout for St. Peter’s stand-in at the gates to heaven.&lt;/p&gt;

&lt;p&gt;Overall, far better than spending the evening in front of the television (unless House is on).&lt;/p&gt;
</content>
 </entry>
 
 
</feed>

