<?xml version="1.0" encoding="utf-8" ?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Without the loop</title>
    <atom:link href="http://withouttheloop.com/feed.xml" rel="self" type="application/rss+xml"></atom:link>
    <link>http://withouttheloop.com</link>
    <description>it is nothing</description>
    <pubDate>Thu, 13 Jun 2024 20:32:00 +1000</pubDate>
    <generator>Wintersmith - https://github.com/jnordberg/wintersmith</generator>
    <language>en</language>
    <item>
      <title>Making Living Specifications Work</title>
      <link>http://withouttheloop.com/articles/2024-06-13-making-living-specifications-work/</link>
      <pubDate>Thu, 13 Jun 2024 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2024-06-13-making-living-specifications-work/</guid>
      <author></author>
      <description>&lt;p&gt;It has bugged me for years that software projects are not properly defined anywhere - except in the code - and that is not a human readable specification. &lt;/p&gt;
&lt;p&gt;Complex, long-lived computer programs are easier to extend and maintain if they have a clear, verified, specification. Specifications are valuable, but they, “are not a natural byproduct of incremental development” (thanks Andrew Best). &lt;/p&gt;
&lt;p&gt;For &lt;a href=&quot;http://withouttheloop.com/articles/2024-06-04-living-specification/&quot;&gt;various reasons&lt;/a&gt; the industry has drifted away from producing specifications, however it seems there may be a practical way to make specifications useful.&lt;/p&gt;
&lt;p&gt;What if we:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;let specification writers write specifications the way that they want?&lt;/li&gt;
&lt;li&gt;let software developers write automated tests the way that they want?&lt;/li&gt;
&lt;li&gt;map the specificaton statements to the tests that verify them and publish the result?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This adds rigour to the idea of &lt;a href=&quot;https://tom.preston-werner.com/2010/08/23/readme-driven-development&quot;&gt;readme driven development&lt;/a&gt;. As Tom Preston-Werner said, “a perfect implementation of the wrong specification is worthless… a beautifully crafted library with no documentation is also damn near worthless”.&lt;/p&gt;
&lt;p&gt;We can explore this idea with a simple example.&lt;/p&gt;
&lt;h2 id=&quot;the-number-guessing-game&quot;&gt;The Number Guessing Game&lt;/h2&gt;
&lt;p&gt;The number guessing game is a classic early programming exercise to write a program that prompts a user to guess a number. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2024-06-13-making-living-specifications-work/guessinggame.png&quot; alt=&quot;Guessing game in terminal&quot;&gt;&lt;/p&gt;
&lt;p&gt;The product owner writes the following specification:&lt;/p&gt;
&lt;div class=&quot;col col-lg-8&quot; style=&quot;background-color: antiquewhite; padding: 20px; border-radius: 0.25em;
background-image: url(paper.png);&quot;&gt;
        &lt;h1 class=&quot;display-4&quot;&gt;Guessing Game Specification&lt;/h1&gt;
&lt;p&gt;The system should prompt the user to guess a number that has been randomly generated. It should provide feedback on their guesses until they guess the correct number.&lt;/p&gt;
&lt;h2 id=&quot;user-input&quot;&gt;User Input&lt;/h2&gt;
&lt;p&gt;The computer chooses a number, within a range (&lt;code&gt;[1,10]&lt;/code&gt;) and prompts the user to guess the number.&lt;/p&gt;
&lt;h2 id=&quot;rules&quot;&gt;Rules:&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span data-bp-grep=&quot;WholeNumbersInRangeAreValid,NotWholeNumbersAreInvalid&quot; data-bp-outcome=&quot;Undefined&quot;&gt;The user must enter a valid, whole number&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span data-bp-grep=&quot;WholeNumbersOutOfRangeAreInvalid&quot; data-bp-outcome=&quot;Undefined&quot;&gt;The user must enter a number that is greater than or equal to the minimum value (&lt;code&gt;1&lt;/code&gt;) and less than or equal to the maximum value (&lt;code&gt;10&lt;/code&gt;)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;evaluation&quot;&gt;Evaluation&lt;/h2&gt;
&lt;p&gt;The computer then evaluates the user’s guess and provides feedback.&lt;/p&gt;
&lt;h2 id=&quot;rules-1&quot;&gt;Rules&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span data-bp-grep=&quot;ValidGuessesEqualToAnswerSayCorrectBang&quot; data-bp-outcome=&quot;Undefined&quot;&gt;If the user’s guess is equal to the answer then the feedback is &lt;code&gt;Correct!&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span data-bp-grep=&quot;ValidGuessesLowerThanAnswerSayHigher&quot; data-bp-outcome=&quot;Undefined&quot;&gt;If the user’s guess is lower than the answer then the feedback is &lt;code&gt;Higher&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span data-bp-grep=&quot;ValidGuessesHigherThanAnswerSayLower&quot; data-bp-outcome=&quot;Undefined&quot;&gt;If the user’s guess is higher than the answer then the feedback is &lt;code&gt;Lower&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span data-bp-grep=&quot;Guessing42IsAlwaysCorrect&quot; data-bp-outcome=&quot;Undefined&quot;&gt;Guessing &lt;code&gt;42&lt;/code&gt; is always correct&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;


&lt;p&gt;The developer then implements the program and produces the following tests (implementations elided as irrelevant):&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-csharp&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;UserInputTests&lt;/span&gt;
{    
    [Fact]
    &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;WholeNumbersInRangeAreValid&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;)&lt;/span&gt;;

    [Theory]
    [InlineData(&lt;span class=&quot;string&quot;&gt;&quot;&quot;&lt;/span&gt;)]
    [InlineData(&lt;span class=&quot;string&quot;&gt;&quot;3.141592&quot;&lt;/span&gt;)]
    [InlineData(&lt;span class=&quot;string&quot;&gt;&quot;cat in hat&quot;&lt;/span&gt;)]
    &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;NotWholeNumbersAreInvalid&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;string&lt;/span&gt; input&lt;/span&gt;)&lt;/span&gt;;

    [Theory]
    [InlineData(&lt;span class=&quot;string&quot;&gt;&quot;-5&quot;&lt;/span&gt;)]
    [InlineData(&lt;span class=&quot;string&quot;&gt;&quot;0&quot;&lt;/span&gt;)]
    [InlineData(&lt;span class=&quot;string&quot;&gt;&quot;1729&quot;&lt;/span&gt;)]
    &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;WholeNumbersOutOfRangeAreInvalid&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;string&lt;/span&gt; input&lt;/span&gt;)&lt;/span&gt;;
}

&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;EvaluationTests&lt;/span&gt;
{
    [Fact]
    &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;ValidGuessesLowerThanAnswerSayHigher&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;)&lt;/span&gt;;

    [Fact]
    &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;ValidGuessesHigherThanAnswerSayLower&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;)&lt;/span&gt;;

    [Fact]
    &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;ValidGuessesEqualToAnswerSayCorrectBang&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;)&lt;/span&gt;;

    [Fact(Skip = &lt;span class=&quot;string&quot;&gt;&quot;Not implemented yet&quot;&lt;/span&gt;)]
    &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Guessing42IsAlwaysCorrect&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;)&lt;/span&gt;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this simple example it is easy to see the implied mapping between statements in the specification and the unit tests. Each bullet point in the specification maps to a single unit test, except for the first statement, &lt;code&gt;The user must enter a valid, whole number&lt;/code&gt;, which maps to two unit tests: &lt;code&gt;WholeNumbersInRangeAreValid&lt;/code&gt; and &lt;code&gt;NotWholeNumbersAreInvalid&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If we add metadata to the specification, we can map each of its claims to the test, or tests, that verify them and then produce a verified specification:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2024-06-13-making-living-specifications-work/verified-spec.png&quot; alt=&quot;A verified specification&quot;&gt;&lt;/p&gt;
&lt;p&gt;All claims in the specification are highlighted. Those that have been successfully verified by the tests are green. Those that failed their tests are red, and those linked to tests that were skipped are gray. &lt;/p&gt;
&lt;p&gt;Having a living specification completes the link between work that developers do and the purpose of the system they are working on. It encourages the team to think before doing, and provides visibility of what the system does, what works, what doesn’t, and what has not been done yet. &lt;/p&gt;
&lt;p&gt;To quote Preston-Werner again, “until you’ve written about your software, you have no idea what you’ll be coding”. Maybe it’s time we did? &lt;/p&gt;
</description>
    </item>
    <item>
      <title>The Missing Software Specification</title>
      <link>http://withouttheloop.com/articles/2024-06-04-living-specification/</link>
      <pubDate>Tue, 04 Jun 2024 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2024-06-04-living-specification/</guid>
      <author></author>
      <description>&lt;p&gt;“The cost of software is approximately equal to the cost of change”, says &lt;a href=&quot;https://vtda.org/books/Computing/Programming/StructuredDesign_EdwardYourdonLarryConstantine.pdf&quot;&gt;Larry Constantine&lt;/a&gt; via &lt;a href=&quot;https://www.youtube.com/watch?v=yBEcq23OgB4&amp;amp;t=1497s&quot;&gt;Kent Beck&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;It is ironic that Kent Beck should propagate this idea, given that he created XP, with ephemeral user stories as work items for system development. It is a weakness of Agile processes that when v1 of a project ships there is no artifact that captures what the system does. There are a series of user stories, representing changes, that were applied in sequence to produce a result - but no clear idea of what that result is. Agile was a great improvement, but in this respect it was a regression. &lt;/p&gt;
&lt;p&gt;Up through the 80s good software development practice was to divide a project schedule into thirds: a third to define the system, a third to build it, and a third to test that the specification and the implementation match. This approach was justified by the flawed assumption that creating software is like a civil engineering project, which it is not. However, civil engineering projects have one great advantage. A bridge is built from a design and when the bridge has been built the design is an accurate description of the bridge. When software development outgrew the civil engineering model the system specification was collatoral damage. &lt;/p&gt;
&lt;p&gt;If Constantine and Beck are correct about the cost of change then having a correct software specification is invaluable. How can we efficiently maintain a system if we don’t know exactly what it does? This is not a new observation, but keeping an accurate specification of a complex system is hard. &lt;/p&gt;
&lt;p&gt;Accurate software specification is a problem of synchronization. Good programmers know that synchronization is a source of bugs and should therefore be avoided. This is done in software by ensuring that things have a single, canonical representation, from which other representations derive. So of course, attempts to solve the software specification problem have tried to follow the same model, with some variation on combining specification with automated tests as a way of verifying that a system matches its specification, while both are constantly changing. There were fit and fitnesse, which put the tests into the specification. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2024-06-04-living-specification/fitnesse.png&quot; alt=&quot;fitnesse&quot;&gt;&lt;/p&gt;
&lt;p&gt;There were rSpec and other BDD tools, which put the specification into the tests. Both of these approaches struggled because a specification is not an automated testing tool, and an automated testing tool is not a specification. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2024-06-04-living-specification/sflow.png&quot; alt=&quot;specflow&quot;&gt;&lt;/p&gt;
&lt;p&gt;Agile left a hole where the system specification should be. Despite many attempts to fill the void, progress has been minimal. I hope that one day we will find a solution. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>Host monitoring with the OpenTelemetry Collector and Prometheus</title>
      <link>http://withouttheloop.com/articles/2024-03-07-host-monitoring-opentelemetry-collector-prometheus/</link>
      <pubDate>Thu, 07 Mar 2024 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2024-03-07-host-monitoring-opentelemetry-collector-prometheus/</guid>
      <author></author>
      <description>&lt;p&gt;When you have a bunch of servers to monitor, it is a good idea to keep an eye on what they are doing. &lt;em&gt;CPU usage&lt;/em&gt;, &lt;em&gt;memory usage&lt;/em&gt; and &lt;em&gt;remaining disk space&lt;/em&gt; are some examples of &lt;em&gt;metrics&lt;/em&gt; that need to be monitored. &lt;/p&gt;
&lt;p&gt;In addition to its usual role as OpenTelemetry middleware, the OpenTelemetry collector can function as a host metrics agent, collecting host metrics and forwarding them to storage and analysis systems. &lt;/p&gt;
&lt;p&gt;The default storage and analysis choice for metrics is Prometheus, sometimes with Grafana on top for more sophisticated visualization. &lt;/p&gt;
&lt;p&gt;Let’s see what it takes to deploy host monitoring using the OpenTelemetry collector and Prometheus. &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The &lt;a href=&quot;https://github.com/liammclennan/otel-collector-prometheus-demo&quot;&gt;full demo code is available on GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;1-the-opentelemetry-collector&quot;&gt;1. The OpenTelemetry Collector&lt;/h2&gt;
&lt;p&gt;I will be using Docker Compose to deploy the collector and Prometheus on the same host. In a file &lt;code&gt;compose.yaml&lt;/code&gt; add a service for the OpenTelemetry collector, connected to a custom Docker network. &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;attr&quot;&gt;services:&lt;/span&gt;
&lt;span class=&quot;attr&quot;&gt;  otel-collector:&lt;/span&gt;
&lt;span class=&quot;attr&quot;&gt;    image:&lt;/span&gt; otel/opentelemetry-collector-contrib:latest
&lt;span class=&quot;attr&quot;&gt;    hostname:&lt;/span&gt; otel-collector
&lt;span class=&quot;attr&quot;&gt;    networks:&lt;/span&gt;
&lt;span class=&quot;bullet&quot;&gt;      -&lt;/span&gt; collectorandprometheus
&lt;span class=&quot;attr&quot;&gt;    restart:&lt;/span&gt; always
&lt;span class=&quot;attr&quot;&gt;    command:&lt;/span&gt; [&lt;span class=&quot;string&quot;&gt;&quot;--config=/etc/otel-collector-config.yaml&quot;&lt;/span&gt;]
&lt;span class=&quot;attr&quot;&gt;    volumes:&lt;/span&gt;
&lt;span class=&quot;bullet&quot;&gt;      -&lt;/span&gt; ./otel-collector-config.yaml:/etc/otel-collector-config.yaml

&lt;span class=&quot;attr&quot;&gt;networks:&lt;/span&gt;
&lt;span class=&quot;attr&quot;&gt;  collectorandprometheus:&lt;/span&gt; {}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that it maps a local config file to &lt;code&gt;/etc/otel-collector-config.yaml&lt;/code&gt; in the container file system. The container publishes no ports, because it is on its own network and we don’t need to access the collector from outside the docker network. &lt;/p&gt;
&lt;p&gt;The OTel collector config file declares and configures a &lt;code&gt;hostmetrics&lt;/code&gt; receiver, and a prometheus exporter, then wires them together in the metrics pipeline.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;attr&quot;&gt;receivers:&lt;/span&gt;
&lt;span class=&quot;attr&quot;&gt;  hostmetrics:&lt;/span&gt;
&lt;span class=&quot;attr&quot;&gt;    collection_interval:&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;m
&lt;span class=&quot;attr&quot;&gt;    scrapers:&lt;/span&gt;
&lt;span class=&quot;attr&quot;&gt;      cpu:&lt;/span&gt;
&lt;span class=&quot;attr&quot;&gt;      load:&lt;/span&gt;
&lt;span class=&quot;attr&quot;&gt;      memory:&lt;/span&gt;
&lt;span class=&quot;attr&quot;&gt;      disk:&lt;/span&gt;
&lt;span class=&quot;attr&quot;&gt;      filesystem:&lt;/span&gt;
&lt;span class=&quot;attr&quot;&gt;      network:&lt;/span&gt;
&lt;span class=&quot;attr&quot;&gt;      paging:&lt;/span&gt;
&lt;span class=&quot;attr&quot;&gt;      processes:&lt;/span&gt;

&lt;span class=&quot;attr&quot;&gt;exporters:&lt;/span&gt;
&lt;span class=&quot;attr&quot;&gt;  prometheus:&lt;/span&gt;
&lt;span class=&quot;attr&quot;&gt;    endpoint:&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;otel-collector:8889&quot;&lt;/span&gt;

&lt;span class=&quot;attr&quot;&gt;service:&lt;/span&gt;
&lt;span class=&quot;attr&quot;&gt;  pipelines:&lt;/span&gt;
&lt;span class=&quot;attr&quot;&gt;    metrics:&lt;/span&gt;
&lt;span class=&quot;attr&quot;&gt;      receivers:&lt;/span&gt; [hostmetrics]
&lt;span class=&quot;attr&quot;&gt;      exporters:&lt;/span&gt; [prometheus]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The endpoint &lt;code&gt;otel-collector&lt;/code&gt; is a reference to the hostname of the otel-collector container in the Docker Compose file. The Prometheus exporter doesn’t send metrics anywhere, it exposes an endpoint for Prometheus to poll and &lt;code&gt;otel-collector:8889&lt;/code&gt; is the address of that endpoint.&lt;/p&gt;
&lt;h2 id=&quot;2-prometheus&quot;&gt;2. Prometheus&lt;/h2&gt;
&lt;p&gt;The Prometheus service is declared in the same &lt;code&gt;compose.yaml&lt;/code&gt; Docker Compose file and added to the same Docker network. &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;attr&quot;&gt;prometheus:&lt;/span&gt;
&lt;span class=&quot;attr&quot;&gt;    image:&lt;/span&gt; prom/prometheus:latest
&lt;span class=&quot;attr&quot;&gt;    hostname:&lt;/span&gt; prometheus
&lt;span class=&quot;attr&quot;&gt;    networks:&lt;/span&gt;
&lt;span class=&quot;bullet&quot;&gt;      -&lt;/span&gt; collectorandprometheus
&lt;span class=&quot;attr&quot;&gt;    restart:&lt;/span&gt; always
&lt;span class=&quot;attr&quot;&gt;    ports:&lt;/span&gt;
&lt;span class=&quot;bullet&quot;&gt;      -&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;9090&lt;/span&gt;:&lt;span class=&quot;number&quot;&gt;9090&lt;/span&gt;
&lt;span class=&quot;attr&quot;&gt;    volumes:&lt;/span&gt;
&lt;span class=&quot;bullet&quot;&gt;      -&lt;/span&gt; ./prometheus.yaml:/etc/prometheus/prometheus.yml
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since Prometheus is on a Docker network it must publish a port to be visible from outside. It also has its own configuration file mapped into the container. The contents of &lt;code&gt;prometheus.yaml&lt;/code&gt; is:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;attr&quot;&gt;scrape_configs:&lt;/span&gt;
&lt;span class=&quot;attr&quot;&gt;  - job_name:&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'otel-collector'&lt;/span&gt;
&lt;span class=&quot;attr&quot;&gt;    scrape_interval:&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;10&lt;/span&gt;s
&lt;span class=&quot;attr&quot;&gt;    static_configs:&lt;/span&gt;
&lt;span class=&quot;attr&quot;&gt;      - targets:&lt;/span&gt; [&lt;span class=&quot;string&quot;&gt;'otel-collector:8889'&lt;/span&gt;]
&lt;span class=&quot;attr&quot;&gt;      - targets:&lt;/span&gt; [&lt;span class=&quot;string&quot;&gt;'otel-collector:8888'&lt;/span&gt;]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This configures Prometheus to poll the OTel Collector, every ten seconds, for metrics. Once again, &lt;code&gt;otel-collector&lt;/code&gt; here is a reference to the hostname of the OpenTelemetry collector service in the Docker Compose file. &lt;/p&gt;
&lt;p&gt;The system can now be started with &lt;code&gt;docker compose up&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;After running for a while you will be able to access Prometheus (&lt;code&gt;localhost:9090&lt;/code&gt;) and see the targets page:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2024-03-07-host-monitoring-opentelemetry-collector-prometheus/prometheus.png&quot; alt=&quot;Prometheus targets page showing the OpenTelemetry collector as targets&quot;&gt;&lt;/p&gt;
&lt;p&gt;And Prometheus will be able to answer queries about host metrics:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2024-03-07-host-monitoring-opentelemetry-collector-prometheus/chart.png&quot; alt=&quot;CPU load average on a Prometheus chart&quot;&gt;&lt;/p&gt;
&lt;p&gt;Which align with metrics gathered via other tools:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2024-03-07-host-monitoring-opentelemetry-collector-prometheus/hetznerchart.png&quot; alt=&quot;CPU load average on a different chart&quot;&gt;&lt;/p&gt;
&lt;p&gt;These are not the only way to collect host metrics. There are many other host agents that do the same thing, but if you happen to need an OpenTelemetry collector anyway then it is handy to be able to use it for host metrics too.    &lt;/p&gt;
</description>
    </item>
    <item>
      <title>A simple database called Wormwood</title>
      <link>http://withouttheloop.com/articles/2023-11-03-wormwood/</link>
      <pubDate>Fri, 03 Nov 2023 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2023-11-03-wormwood/</guid>
      <author></author>
      <description>&lt;p&gt;At &lt;a href=&quot;https://datalust.co/seq&quot;&gt;work&lt;/a&gt;, I contribute to a database called &lt;a href=&quot;https://blog.datalust.co/rust-at-datalust/&quot;&gt;Flare&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;Flare, and database technology in general, is fascinating and deeply rewarding, but it is also huge, complex and inscrutable :D&lt;/p&gt;
&lt;p&gt;Because I think databases are interesting, and I hope others may too, I started building a new database, called Wormwood. Originally, I called it ToyDB, because it is a toy db, but there is already at least one of those so I changed the name to Wormwood.&lt;/p&gt;
&lt;p&gt;Wormwood is being built in Typescript (because it is accessible) and Rust (because it will help me to learn Rust).&lt;/p&gt;
&lt;p&gt;I hope to keep Wormwood very, very simple so that it may serve as a demonstration of the concepts that make more sophisticated databases possible. This quickly leads to decisions that prevent it from being a useable database, and that is ok. Wormwood will never be useful for anything other than the joy of finding things out. &lt;/p&gt;
&lt;p&gt;If you’d like a quick introduction to the terrain you could do worse that &lt;a href=&quot;https://dsf.berkeley.edu/papers/fntdb07-architecture.pdf&quot;&gt;Architecture of a Database System&lt;/a&gt; (Hellerstein, Stonebraker and Hamilton). It describes a core type used to build data pipelines that looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-ts&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;type&lt;/span&gt; Row = &lt;span class=&quot;built_in&quot;&gt;any&lt;/span&gt;[];
&lt;span class=&quot;keyword&quot;&gt;type&lt;/span&gt; RowMarker = &lt;span class=&quot;string&quot;&gt;&quot;end of file&quot;&lt;/span&gt;;

&lt;span class=&quot;keyword&quot;&gt;interface&lt;/span&gt; Iter {
    &lt;span class=&quot;keyword&quot;&gt;constructor&lt;/span&gt;(inputs: Iter[]): Iter;
    next(): Promise&amp;lt;Row | RowMarker&amp;gt;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Instances of this &lt;code&gt;Iter&lt;/code&gt; type (or similar) are connected into a pipeline. When a value is required a consumer calls &lt;code&gt;next()&lt;/code&gt; on the iterator at the top of the stack and it calls &lt;code&gt;next()&lt;/code&gt; on down the stack until somewhere there is an &lt;code&gt;Iter&lt;/code&gt; that reads tuples from disk. In Wormwood this &lt;code&gt;Iter&lt;/code&gt; is called &lt;code&gt;Producer&lt;/code&gt; (because it produces rows).&lt;/p&gt;
&lt;h2 id=&quot;producer&quot;&gt;Producer&lt;/h2&gt;
&lt;p&gt;The disk format for Wormwood is &lt;a href=&quot;http://clef-json.org/&quot;&gt;CLEF&lt;/a&gt; (newline delimited JSON). It is easy to work with in JavaScript and it is familiar to me. CLEF looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-json&quot;&gt;{&lt;span class=&quot;attr&quot;&gt;&quot;@t&quot;&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;&quot;2023-10-19T11:54:57.9827300Z&quot;&lt;/span&gt;,&lt;span class=&quot;attr&quot;&gt;&quot;@mt&quot;&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;&quot;One&quot;&lt;/span&gt;,&lt;span class=&quot;attr&quot;&gt;&quot;@i&quot;&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;&quot;1&quot;&lt;/span&gt;}
{&lt;span class=&quot;attr&quot;&gt;&quot;@t&quot;&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;&quot;2023-10-19T11:54:58.9827300Z&quot;&lt;/span&gt;,&lt;span class=&quot;attr&quot;&gt;&quot;@mt&quot;&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;&quot;Two&quot;&lt;/span&gt;,&lt;span class=&quot;attr&quot;&gt;&quot;@i&quot;&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;&quot;2&quot;&lt;/span&gt;}
{&lt;span class=&quot;attr&quot;&gt;&quot;@t&quot;&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;&quot;2023-10-19T11:54:59.9827300Z&quot;&lt;/span&gt;,&lt;span class=&quot;attr&quot;&gt;&quot;@mt&quot;&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;&quot;Three&quot;&lt;/span&gt;,&lt;span class=&quot;attr&quot;&gt;&quot;@i&quot;&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;&quot;3&quot;&lt;/span&gt;}
{&lt;span class=&quot;attr&quot;&gt;&quot;@t&quot;&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;&quot;2023-10-19T11:55:00.9827300Z&quot;&lt;/span&gt;,&lt;span class=&quot;attr&quot;&gt;&quot;@mt&quot;&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;&quot;Four&quot;&lt;/span&gt;,&lt;span class=&quot;attr&quot;&gt;&quot;@i&quot;&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;&quot;4&quot;&lt;/span&gt;}
{&lt;span class=&quot;attr&quot;&gt;&quot;@t&quot;&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;&quot;2023-10-19T11:55:01.9827300Z&quot;&lt;/span&gt;,&lt;span class=&quot;attr&quot;&gt;&quot;@mt&quot;&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;&quot;Five&quot;&lt;/span&gt;,&lt;span class=&quot;attr&quot;&gt;&quot;@i&quot;&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;&quot;5&quot;&lt;/span&gt;}
{&lt;span class=&quot;attr&quot;&gt;&quot;@t&quot;&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;&quot;2023-10-19T11:55:02.9827300Z&quot;&lt;/span&gt;,&lt;span class=&quot;attr&quot;&gt;&quot;@mt&quot;&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;&quot;Six&quot;&lt;/span&gt;,&lt;span class=&quot;attr&quot;&gt;&quot;@i&quot;&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;&quot;6&quot;&lt;/span&gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The job of the producer is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;to stream tuples from a CLEF file. The file could be gigabytes so it is important not to rely on reading the entire file into memory. &lt;/li&gt;
&lt;li&gt;to extract properties from the CLEF objects. If a query requires the &lt;code&gt;@mt&lt;/code&gt; and &lt;code&gt;@i&lt;/code&gt; properties then we only want to take those. &lt;/li&gt;
&lt;li&gt;to convert a JSON object into a tuple row format. In Typescript this is the &lt;code&gt;type Row = any[]&lt;/code&gt; type that the &lt;code&gt;next()&lt;/code&gt; function returns. &lt;/li&gt;
&lt;li&gt;to convert node.js’s push based streams into the &lt;code&gt;Iter&lt;/code&gt;s pull model, by opening a stream, pushing data into a buffer, and letting &lt;code&gt;next()&lt;/code&gt; pull from the buffer. This is why &lt;code&gt;next()&lt;/code&gt; is asynchronous - if the buffer is empty the producer needs time to read another chunk from disk. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here is the &lt;code&gt;Producer&lt;/code&gt; constructor:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-ts&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;constructor&lt;/span&gt;(table: string, columns: string[]) {
    &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.filePath = Path.join(__dirname, &lt;span class=&quot;string&quot;&gt;&quot;../../data&quot;&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;`&lt;span class=&quot;subst&quot;&gt;${table}&lt;/span&gt;.clef`&lt;/span&gt;);
    &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.columns = columns;
    &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.open();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;‘Tables’ map to files in the &lt;code&gt;/data&lt;/code&gt; directory - so &lt;code&gt;select a, b from table1&lt;/code&gt; will open the file &lt;code&gt;/data/table1.clef&lt;/code&gt;. The &lt;code&gt;open()&lt;/code&gt; method opens the file and starts streaming chunks into the buffer and is an abomination that I won’t soil your eyes with. &lt;/p&gt;
&lt;p&gt;&lt;code&gt;Producer&lt;/code&gt;s &lt;code&gt;next()&lt;/code&gt; method tries to grab a row from the buffer, and then feeds it through the &lt;code&gt;makeRow&lt;/code&gt; function below to convert it into an array of the requested properties:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-ts&quot;&gt;makeRow(line: &lt;span class=&quot;built_in&quot;&gt;string&lt;/span&gt;): &lt;span class=&quot;built_in&quot;&gt;any&lt;/span&gt;[] {
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; parsed = &lt;span class=&quot;built_in&quot;&gt;JSON&lt;/span&gt;.parse(line);
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.columns.map((c) =&amp;gt; parsed[c]);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That is the state of the &lt;code&gt;Producer&lt;/code&gt; iterator at the moment. The typescript implementation is hideous and will hopefully get cleaned up. The Rust version is gorgeous.&lt;/p&gt;
&lt;p&gt;Here’s me running a query:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2023-11-03-wormwood/repl.png&quot; alt=&quot;repl&quot;&gt;&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Factory Reset a Windows Computer with Bitlocker</title>
      <link>http://withouttheloop.com/articles/2022-06-23-factory-reset-bitlocker/</link>
      <pubDate>Thu, 23 Jun 2022 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2022-06-23-factory-reset-bitlocker/</guid>
      <author></author>
      <description>&lt;p&gt;In short, it’s a nightmare. The best strategy is to boot Windows, disable bitlocker and then proceed with the factory reset. But I didn’t do that, and I didn’t have the bitlocker key, so completing a factory reset became difficult. &lt;/p&gt;
&lt;p&gt;The computer I tried to restore is a 2018 Dell XPS 13.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2022-06-23-factory-reset-bitlocker/xps13&quot; alt=&quot;XPS 13&quot;&gt;&lt;/p&gt;
&lt;p&gt;It comes with a tool called ‘Dell SupportAssist OS Restore’ which can factory reset the computer using an image stored on a disk partition. For reasons unknown, this tool does not work with a Bitlocker encrypted OS partition. &lt;/p&gt;
&lt;p&gt;The approach that (eventually) worked for me was:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Use another windows computer to create a Windows recovery media USB drive.&lt;/li&gt;
&lt;li&gt;Edit the BIOS to boot from the USB drive (I think only one of my USB ports detected the drive, and possible only if connected without a USB hub).&lt;/li&gt;
&lt;li&gt;Use the advanced setup option, delete the Bitlockered partition, create a new partition and choose it as the OS partition (you can’t install over the Bitlocker partition). &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This is why I hate computers. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>Rust Programming Mars Rovers Exercise</title>
      <link>http://withouttheloop.com/articles/2022-05-02-rust-mars-rovers/</link>
      <pubDate>Mon, 02 May 2022 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2022-05-02-rust-mars-rovers/</guid>
      <author></author>
      <description>&lt;p&gt;&lt;img src=&quot;/articles/2022-05-02-rust-mars-rovers/rust.png&quot; alt=&quot;Rust logo&quot;&gt;&lt;/p&gt;
&lt;p&gt;I’ve been learning to program with Rust, and frankly struggling. I like the book &lt;a href=&quot;https://www.goodreads.com/en/book/show/25550614&quot;&gt;Programming Rust&lt;/a&gt; which I’ve been working through, but still I get stuck. Things in the book make sense, but when I try it I end up tied in a knot. I decided I need to write more rust and work through it. When learning a new programming language I find it helpful to revist programs that I know well in other languages. &lt;/p&gt;
&lt;p&gt;Seven years ago I was &lt;a href=&quot;https://www.withouttheloop.com/articles/2015-04-17-mars-rover/&quot;&gt;playing with the Mars Rovers problem in F#&lt;/a&gt;, so today I tried it in Rust.&lt;/p&gt;
&lt;h2 id=&quot;bits-i-think-interesting&quot;&gt;Bits I Think Interesting&lt;/h2&gt;
&lt;h3 id=&quot;types&quot;&gt;Types&lt;/h3&gt;
&lt;p&gt;The types are neat, and similar to their F# equivalents. Enums for directions and commands and a tuple to represent cartesian coordinates. The tuple has a nice property (as opposed to &lt;code&gt;struct { x,y }&lt;/code&gt;) that it is a copy type (a type copied by value therefore not subject to borrowing). &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-rust&quot;&gt;&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Direction&lt;/span&gt;&lt;/span&gt; {
    NORTH,SOUTH,EAST,WEST
}

&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Point&lt;/span&gt;&lt;/span&gt; = (&lt;span class=&quot;keyword&quot;&gt;i8&lt;/span&gt;,&lt;span class=&quot;keyword&quot;&gt;i8&lt;/span&gt;);

&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Position&lt;/span&gt;&lt;/span&gt; {
    location: Point,
    orientation: Direction
}

&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Command&lt;/span&gt;&lt;/span&gt; {
    LEFT, RIGHT, MOVE, REPORT
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;parsing&quot;&gt;Parsing&lt;/h3&gt;
&lt;p&gt;The first step of the program is to parse the input file into the starting position of the rover and a set of commands. The input file is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PLACE 1,2,EAST
MOVE
MOVE
LEFT
MOVE
MOVE
MOVE
MOVE
MOVE
LEFT
MOVE
MOVE
MOVE
MOVE
MOVE
REPORT
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The function that parses the input is:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-rust&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;parse_input&lt;/span&gt;&lt;/span&gt;(content: &lt;span class=&quot;built_in&quot;&gt;String&lt;/span&gt;) -&amp;gt; (Position, &lt;span class=&quot;built_in&quot;&gt;Vec&lt;/span&gt;&amp;lt;Command&amp;gt;) {
    &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; lines: &lt;span class=&quot;built_in&quot;&gt;Vec&lt;/span&gt;&amp;lt;&amp;amp;&lt;span class=&quot;keyword&quot;&gt;str&lt;/span&gt;&amp;gt; = content.lines().collect();
    (get_start_position(&amp;amp;lines), get_commands(&amp;amp;lines))
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I preferred to return a tuple for the position and the list of commands rather than introducing a type just to hold this function return value, as the function is called and its result immediately consumed. &lt;/p&gt;
&lt;p&gt;Splitting the contents of the input file into lines could have been: &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-rust&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; lines: &lt;span class=&quot;built_in&quot;&gt;Vec&lt;/span&gt;&amp;lt;&amp;amp;&lt;span class=&quot;keyword&quot;&gt;str&lt;/span&gt;&amp;gt; = content.lines().collect();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-rust&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; lines = content.lines().collect::&amp;lt;&lt;span class=&quot;built_in&quot;&gt;Vec&lt;/span&gt;&amp;lt;&amp;amp;&lt;span class=&quot;keyword&quot;&gt;str&lt;/span&gt;&amp;gt;&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I prefer the version with the type annotation on the variable. &lt;/p&gt;
&lt;p&gt;Since &lt;code&gt;lines&lt;/code&gt; is passed to two functions, neither of them may consume the value, so they both expect &lt;code&gt;&amp;amp;Vec&amp;lt;str&amp;gt;&lt;/code&gt;. &lt;/p&gt;
&lt;p&gt;The code to parse the starting position (&lt;code&gt;PLACE 1,2,EAST&lt;/code&gt;) is:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-rust&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;get_start_position&lt;/span&gt;&lt;/span&gt;(lines: &amp;amp;&lt;span class=&quot;built_in&quot;&gt;Vec&lt;/span&gt;&amp;lt;&amp;amp;&lt;span class=&quot;keyword&quot;&gt;str&lt;/span&gt;&amp;gt;) -&amp;gt; Position {
    &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; first_line: &amp;amp;&lt;span class=&quot;keyword&quot;&gt;str&lt;/span&gt; = lines[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;];
    &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; args: &lt;span class=&quot;built_in&quot;&gt;Vec&lt;/span&gt;&amp;lt;&amp;amp;&lt;span class=&quot;keyword&quot;&gt;str&lt;/span&gt;&amp;gt; = first_line[&lt;span class=&quot;number&quot;&gt;6&lt;/span&gt;..].split(&lt;span class=&quot;string&quot;&gt;&quot;,&quot;&lt;/span&gt;).collect();
    Position {
        location: (args[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;].parse().unwrap(), args[&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;].parse().unwrap()),
        orientation: args[&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;].parse().unwrap()
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Skip the &lt;code&gt;PLACE&lt;/code&gt; part, split on &lt;code&gt;,&lt;/code&gt;, and build a &lt;code&gt;Position&lt;/code&gt; struct. The interesting thing here is that &lt;code&gt;args[2]&lt;/code&gt; is a &lt;code&gt;&amp;amp;str&lt;/code&gt;, and &lt;code&gt;Position::orientation&lt;/code&gt; is a &lt;code&gt;Direction&lt;/code&gt; enum (see above). How does that work?&lt;/p&gt;
&lt;p&gt;&lt;code&gt;parse&lt;/code&gt; uses the &lt;code&gt;from_str&lt;/code&gt; method of the &lt;code&gt;FromStr&lt;/code&gt; trait. You can &lt;code&gt;parse&lt;/code&gt; a string to anything that has this trait implemented, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-rust&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;impl&lt;/span&gt; FromStr &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; Direction {
    &lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Err&lt;/span&gt;&lt;/span&gt; = &lt;span class=&quot;built_in&quot;&gt;String&lt;/span&gt;;
    &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;from_str&lt;/span&gt;&lt;/span&gt;(input: &amp;amp;&lt;span class=&quot;keyword&quot;&gt;str&lt;/span&gt;) -&amp;gt; &lt;span class=&quot;built_in&quot;&gt;Result&lt;/span&gt;&amp;lt;Direction, Self::&lt;span class=&quot;literal&quot;&gt;Err&lt;/span&gt;&amp;gt; {
        &lt;span class=&quot;keyword&quot;&gt;match&lt;/span&gt; input {
            &lt;span class=&quot;string&quot;&gt;&quot;NORTH&quot;&lt;/span&gt; =&amp;gt; &lt;span class=&quot;literal&quot;&gt;Ok&lt;/span&gt;(Direction::NORTH),
            &lt;span class=&quot;string&quot;&gt;&quot;EAST&quot;&lt;/span&gt; =&amp;gt; &lt;span class=&quot;literal&quot;&gt;Ok&lt;/span&gt;(Direction::EAST),
            &lt;span class=&quot;string&quot;&gt;&quot;SOUTH&quot;&lt;/span&gt; =&amp;gt; &lt;span class=&quot;literal&quot;&gt;Ok&lt;/span&gt;(Direction::SOUTH),
            &lt;span class=&quot;string&quot;&gt;&quot;WEST&quot;&lt;/span&gt; =&amp;gt; &lt;span class=&quot;literal&quot;&gt;Ok&lt;/span&gt;(Direction::WEST),
            _ =&amp;gt; &lt;span class=&quot;literal&quot;&gt;Err&lt;/span&gt;(&lt;span class=&quot;built_in&quot;&gt;format!&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;&quot;Unknown direction {}&quot;&lt;/span&gt;, input))
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Of course, in C# this would be easier with &lt;a href=&quot;https://docs.microsoft.com/en-us/dotnet/api/system.enum.parse?view=net-6.0&quot;&gt;&lt;code&gt;Enum.Parse&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Parsing the commands is implemented by mapping the remaining lines of the input file, trimming each line, skipping the empty lines, and using the same &lt;code&gt;FromStr&lt;/code&gt; / &lt;code&gt;parse&lt;/code&gt; trick to turn each line into a &lt;code&gt;Command&lt;/code&gt;. &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-rust&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;get_commands&lt;/span&gt;&lt;/span&gt;(lines: &amp;amp;&lt;span class=&quot;built_in&quot;&gt;Vec&lt;/span&gt;&amp;lt;&amp;amp;&lt;span class=&quot;keyword&quot;&gt;str&lt;/span&gt;&amp;gt;) -&amp;gt; &lt;span class=&quot;built_in&quot;&gt;Vec&lt;/span&gt;&amp;lt;Command&amp;gt; {
    lines[&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;..].iter().map(|line| {
        line.trim()
    }).filter(|line| {
        !line.is_empty()
    }).map(|line| {
        line.parse().unwrap()
    }).collect()
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Rust’s iterators can be a bit clumsy compared to the F# equivalent, but here it works nicely. Chaining transformations on an iterator works well so long as their is a materialized type on either end of the chain. &lt;/p&gt;
&lt;h3 id=&quot;methods-on-types&quot;&gt;Methods on Types&lt;/h3&gt;
&lt;p&gt;In F# I tend to keep types and functions separate (in the same module), but in Rust I found it nice to implement the ‘mutations’ on the &lt;code&gt;Position&lt;/code&gt; type, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-rust&quot;&gt;&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Position&lt;/span&gt;&lt;/span&gt; {
    location: Point,
    orientation: Direction
}
&lt;span class=&quot;keyword&quot;&gt;impl&lt;/span&gt; Position {
    &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;turn_left&lt;/span&gt;&lt;/span&gt;(&amp;amp;&lt;span class=&quot;keyword&quot;&gt;self&lt;/span&gt;) -&amp;gt; Position {
        &lt;span class=&quot;keyword&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;self&lt;/span&gt;.orientation {
            Direction::NORTH =&amp;gt; 
                Position { orientation: Direction::WEST, ..*&lt;span class=&quot;keyword&quot;&gt;self&lt;/span&gt; },
            Direction::EAST =&amp;gt; 
                Position { orientation: Direction::NORTH, ..*&lt;span class=&quot;keyword&quot;&gt;self&lt;/span&gt; },
            Direction::SOUTH =&amp;gt; 
                Position { orientation: Direction::EAST, ..*&lt;span class=&quot;keyword&quot;&gt;self&lt;/span&gt; },
            Direction::WEST =&amp;gt; 
                Position { orientation: Direction::SOUTH, ..*&lt;span class=&quot;keyword&quot;&gt;self&lt;/span&gt; },
        }
    }

    &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;turn_right&lt;/span&gt;&lt;/span&gt;(&amp;amp;&lt;span class=&quot;keyword&quot;&gt;self&lt;/span&gt;) -&amp;gt; Position {
        &lt;span class=&quot;keyword&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;self&lt;/span&gt;.orientation {
            Direction::NORTH =&amp;gt; 
                Position { orientation: Direction::EAST, ..*&lt;span class=&quot;keyword&quot;&gt;self&lt;/span&gt; },
            Direction::EAST =&amp;gt; 
                Position { orientation: Direction::SOUTH, ..*&lt;span class=&quot;keyword&quot;&gt;self&lt;/span&gt; },
            Direction::SOUTH =&amp;gt; 
                Position { orientation: Direction::WEST, ..*&lt;span class=&quot;keyword&quot;&gt;self&lt;/span&gt; },
            Direction::WEST =&amp;gt; 
                Position { orientation: Direction::NORTH, ..*&lt;span class=&quot;keyword&quot;&gt;self&lt;/span&gt; },
        }
    }

    &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;move_forward&lt;/span&gt;&lt;/span&gt;(&amp;amp;&lt;span class=&quot;keyword&quot;&gt;self&lt;/span&gt;) -&amp;gt; Position {
        &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; delta: (&lt;span class=&quot;keyword&quot;&gt;i8&lt;/span&gt;,&lt;span class=&quot;keyword&quot;&gt;i8&lt;/span&gt;) = &lt;span class=&quot;keyword&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;self&lt;/span&gt;.orientation {
            Direction::NORTH =&amp;gt; (&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;,&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;),
            Direction::EAST =&amp;gt; (&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;),
            Direction::SOUTH =&amp;gt; (&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;,&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;),
            Direction::WEST =&amp;gt; (-&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;),
        };

        &lt;span class=&quot;comment&quot;&gt;// restrict val to `low..=high`&lt;/span&gt;
        &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;bound&lt;/span&gt;&lt;/span&gt;(low: &lt;span class=&quot;keyword&quot;&gt;i8&lt;/span&gt;, high: &lt;span class=&quot;keyword&quot;&gt;i8&lt;/span&gt;, val: &lt;span class=&quot;keyword&quot;&gt;i8&lt;/span&gt;) -&amp;gt; &lt;span class=&quot;keyword&quot;&gt;i8&lt;/span&gt; {
            max(min(val, high), low)
        }

        &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; highest_index = GRID_SIZE - &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;;

        Position {
            location: (
                bound(&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;, highest_index, &lt;span class=&quot;keyword&quot;&gt;self&lt;/span&gt;.location.&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt; + delta.&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;), 
                bound(&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;, highest_index, &lt;span class=&quot;keyword&quot;&gt;self&lt;/span&gt;.location.&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt; + delta.&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;)),
            ..*&lt;span class=&quot;keyword&quot;&gt;self&lt;/span&gt;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;‘Mutations’ is quoted because each of the operations, &lt;code&gt;turn_left&lt;/code&gt;, &lt;code&gt;turn_right&lt;/code&gt; and &lt;code&gt;move_forward&lt;/code&gt;, returns a new, owned, &lt;code&gt;Position&lt;/code&gt; instead of mutating &lt;code&gt;self&lt;/code&gt;. Creating the new &lt;code&gt;Postion&lt;/code&gt; uses the ‘struct update’ syntax (&lt;code&gt;..*self&lt;/code&gt;) to be robust to changes in the &lt;code&gt;Position&lt;/code&gt; type and to make the code more clearly express its purpose (make a new value the same as the old one except this specific change). &lt;/p&gt;
&lt;h3 id=&quot;drawing-the-rest-of-the-owl&quot;&gt;Drawing the Rest of the Owl&lt;/h3&gt;
&lt;p&gt;The last part is to fold over the list of commands, applying them to the starting position. &lt;/p&gt;
&lt;p&gt;Here I chose to pass the starting position (&lt;code&gt;start: Position&lt;/code&gt;) and the list of commands (&lt;code&gt;Vec&amp;lt;Command&amp;gt;&lt;/code&gt;), by value such that they are consumed by the &lt;code&gt;apply_commands&lt;/code&gt; function. It is the last statement in the program so I know those values are not needed and can be safely released. &lt;/p&gt;
&lt;p&gt;Rust allows blocks anywhere an expression is valid, which makes it easy to embed statements in expressions. By making the value of the &lt;code&gt;Command::REPORT&lt;/code&gt; branch a block it is possible to perform a side-effect (&lt;code&gt;report(&amp;amp;position)&lt;/code&gt;) and then return the current position value, to move to the next command. &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-rust&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;apply_commands&lt;/span&gt;&lt;/span&gt;(start: Position, commands: &lt;span class=&quot;built_in&quot;&gt;Vec&lt;/span&gt;&amp;lt;Command&amp;gt;) -&amp;gt; Position {
    commands.iter().fold(start, |position, command| {
        &lt;span class=&quot;keyword&quot;&gt;match&lt;/span&gt; command {
            Command::LEFT =&amp;gt; position.turn_left(),
            Command::RIGHT =&amp;gt; position.turn_right(),
            Command::MOVE =&amp;gt; position.move_forward(),
            Command::REPORT =&amp;gt; {
                report(&amp;amp;position);
                position
            }
        }
    })
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I am enjoying the exercise of Rust, because I find it difficult, but that does not make it a good programming language. &lt;/p&gt;
&lt;p&gt;At this stage I can’t honestly say that I &lt;em&gt;like&lt;/em&gt; Rust, but I really want to. Surely, all those &lt;a href=&quot;https://insights.stackoverflow.com/survey/2021#section-most-loved-dreaded-and-wanted-programming-scripting-and-markup-languages&quot;&gt;stack overflow respondents&lt;/a&gt; can’t be wrong? My hope is that once I pass the frustration stage I will move into the blissful satisfaction stage. &lt;/p&gt;
&lt;p&gt;If I was coming from a lower-level language (C, assembler) no doubt Rust would seem amazing, but coming from higher-level languages there is a sense in which it is a step backwards - a concession to the constraints of computer hardware and an acknowledgement that technology is not yet sufficiently advanced to free programmers from a bunch of &lt;a href=&quot;https://www.cgl.ucsf.edu/Outreach/pc204/NoSilverBullet.html&quot;&gt;accidental complexity&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;Entire program for reference:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-rust&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;use&lt;/span&gt; std::fs;
&lt;span class=&quot;keyword&quot;&gt;use&lt;/span&gt; std::str::FromStr;
&lt;span class=&quot;keyword&quot;&gt;use&lt;/span&gt; std::cmp::{min,max};

&lt;span class=&quot;keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;run&lt;/span&gt;&lt;/span&gt;() {
    &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; content = read_file(&lt;span class=&quot;string&quot;&gt;&quot;src/rovers/input.txt&quot;&lt;/span&gt;);
    &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; input = parse_input(content);
    apply_commands(input.&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;, input.&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;);
}

&lt;span class=&quot;keyword&quot;&gt;static&lt;/span&gt; GRID_SIZE: &lt;span class=&quot;keyword&quot;&gt;i8&lt;/span&gt; = &lt;span class=&quot;number&quot;&gt;5&lt;/span&gt;;

&lt;span class=&quot;meta&quot;&gt;#[derive(Debug,PartialEq,Eq,Clone,Copy)]&lt;/span&gt;
&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Direction&lt;/span&gt;&lt;/span&gt; {
    NORTH,SOUTH,EAST,WEST
}
&lt;span class=&quot;keyword&quot;&gt;impl&lt;/span&gt; FromStr &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; Direction {
    &lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Err&lt;/span&gt;&lt;/span&gt; = &lt;span class=&quot;built_in&quot;&gt;String&lt;/span&gt;;
    &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;from_str&lt;/span&gt;&lt;/span&gt;(input: &amp;amp;&lt;span class=&quot;keyword&quot;&gt;str&lt;/span&gt;) -&amp;gt; &lt;span class=&quot;built_in&quot;&gt;Result&lt;/span&gt;&amp;lt;Direction, Self::&lt;span class=&quot;literal&quot;&gt;Err&lt;/span&gt;&amp;gt; {
        &lt;span class=&quot;keyword&quot;&gt;match&lt;/span&gt; input {
            &lt;span class=&quot;string&quot;&gt;&quot;NORTH&quot;&lt;/span&gt; =&amp;gt; &lt;span class=&quot;literal&quot;&gt;Ok&lt;/span&gt;(Direction::NORTH),
            &lt;span class=&quot;string&quot;&gt;&quot;EAST&quot;&lt;/span&gt; =&amp;gt; &lt;span class=&quot;literal&quot;&gt;Ok&lt;/span&gt;(Direction::EAST),
            &lt;span class=&quot;string&quot;&gt;&quot;SOUTH&quot;&lt;/span&gt; =&amp;gt; &lt;span class=&quot;literal&quot;&gt;Ok&lt;/span&gt;(Direction::SOUTH),
            &lt;span class=&quot;string&quot;&gt;&quot;WEST&quot;&lt;/span&gt; =&amp;gt; &lt;span class=&quot;literal&quot;&gt;Ok&lt;/span&gt;(Direction::WEST),
            _ =&amp;gt; &lt;span class=&quot;literal&quot;&gt;Err&lt;/span&gt;(&lt;span class=&quot;built_in&quot;&gt;format!&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;&quot;Unknown direction {}&quot;&lt;/span&gt;, input))
        }
    }
}

&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Point&lt;/span&gt;&lt;/span&gt; = (&lt;span class=&quot;keyword&quot;&gt;i8&lt;/span&gt;,&lt;span class=&quot;keyword&quot;&gt;i8&lt;/span&gt;);

&lt;span class=&quot;meta&quot;&gt;#[derive(Debug,PartialEq,Eq)]&lt;/span&gt;
&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Position&lt;/span&gt;&lt;/span&gt; {
    location: Point,
    orientation: Direction
}
&lt;span class=&quot;keyword&quot;&gt;impl&lt;/span&gt; Position {
    &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;turn_left&lt;/span&gt;&lt;/span&gt;(&amp;amp;&lt;span class=&quot;keyword&quot;&gt;self&lt;/span&gt;) -&amp;gt; Position {
        &lt;span class=&quot;keyword&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;self&lt;/span&gt;.orientation {
            Direction::NORTH =&amp;gt; 
                Position { orientation: Direction::WEST, ..*&lt;span class=&quot;keyword&quot;&gt;self&lt;/span&gt; },
            Direction::EAST =&amp;gt; 
                Position { orientation: Direction::NORTH, ..*&lt;span class=&quot;keyword&quot;&gt;self&lt;/span&gt; },
            Direction::SOUTH =&amp;gt; 
                Position { orientation: Direction::EAST, ..*&lt;span class=&quot;keyword&quot;&gt;self&lt;/span&gt; },
            Direction::WEST =&amp;gt; 
                Position { orientation: Direction::SOUTH, ..*&lt;span class=&quot;keyword&quot;&gt;self&lt;/span&gt; },
        }
    }

    &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;turn_right&lt;/span&gt;&lt;/span&gt;(&amp;amp;&lt;span class=&quot;keyword&quot;&gt;self&lt;/span&gt;) -&amp;gt; Position {
        &lt;span class=&quot;keyword&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;self&lt;/span&gt;.orientation {
            Direction::NORTH =&amp;gt; 
                Position { orientation: Direction::EAST, ..*&lt;span class=&quot;keyword&quot;&gt;self&lt;/span&gt; },
            Direction::EAST =&amp;gt; 
                Position { orientation: Direction::SOUTH, ..*&lt;span class=&quot;keyword&quot;&gt;self&lt;/span&gt; },
            Direction::SOUTH =&amp;gt; 
                Position { orientation: Direction::WEST, ..*&lt;span class=&quot;keyword&quot;&gt;self&lt;/span&gt; },
            Direction::WEST =&amp;gt; 
                Position { orientation: Direction::NORTH, ..*&lt;span class=&quot;keyword&quot;&gt;self&lt;/span&gt; },
        }
    }

    &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;move_forward&lt;/span&gt;&lt;/span&gt;(&amp;amp;&lt;span class=&quot;keyword&quot;&gt;self&lt;/span&gt;) -&amp;gt; Position {
        &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; delta: (&lt;span class=&quot;keyword&quot;&gt;i8&lt;/span&gt;,&lt;span class=&quot;keyword&quot;&gt;i8&lt;/span&gt;) = &lt;span class=&quot;keyword&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;self&lt;/span&gt;.orientation {
            Direction::NORTH =&amp;gt; (&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;,&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;),
            Direction::EAST =&amp;gt; (&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;),
            Direction::SOUTH =&amp;gt; (&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;,&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;),
            Direction::WEST =&amp;gt; (-&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;),
        };

        &lt;span class=&quot;comment&quot;&gt;// restrict val to `low..=high`&lt;/span&gt;
        &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;bound&lt;/span&gt;&lt;/span&gt;(low: &lt;span class=&quot;keyword&quot;&gt;i8&lt;/span&gt;, high: &lt;span class=&quot;keyword&quot;&gt;i8&lt;/span&gt;, val: &lt;span class=&quot;keyword&quot;&gt;i8&lt;/span&gt;) -&amp;gt; &lt;span class=&quot;keyword&quot;&gt;i8&lt;/span&gt; {
            max(min(val, high), low)
        }

        &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; highest_index = GRID_SIZE - &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;;

        Position {
            location: (bound(&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;, highest_index, &lt;span class=&quot;keyword&quot;&gt;self&lt;/span&gt;.location.&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt; + delta.&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;), bound(&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;, highest_index, &lt;span class=&quot;keyword&quot;&gt;self&lt;/span&gt;.location.&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt; + delta.&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;)),
            ..*&lt;span class=&quot;keyword&quot;&gt;self&lt;/span&gt;
        }
    }
}

&lt;span class=&quot;meta&quot;&gt;#[derive(Debug,PartialEq,Eq)]&lt;/span&gt;
&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;enum&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Command&lt;/span&gt;&lt;/span&gt; {
    LEFT, RIGHT, MOVE, REPORT
}
&lt;span class=&quot;keyword&quot;&gt;impl&lt;/span&gt; FromStr &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; Command {
    &lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Err&lt;/span&gt;&lt;/span&gt; = &lt;span class=&quot;built_in&quot;&gt;String&lt;/span&gt;;
    &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;from_str&lt;/span&gt;&lt;/span&gt;(input: &amp;amp;&lt;span class=&quot;keyword&quot;&gt;str&lt;/span&gt;) -&amp;gt; &lt;span class=&quot;built_in&quot;&gt;Result&lt;/span&gt;&amp;lt;Command, Self::&lt;span class=&quot;literal&quot;&gt;Err&lt;/span&gt;&amp;gt; {
        &lt;span class=&quot;keyword&quot;&gt;match&lt;/span&gt; input {
            &lt;span class=&quot;string&quot;&gt;&quot;LEFT&quot;&lt;/span&gt; =&amp;gt; &lt;span class=&quot;literal&quot;&gt;Ok&lt;/span&gt;(Command::LEFT),
            &lt;span class=&quot;string&quot;&gt;&quot;RIGHT&quot;&lt;/span&gt; =&amp;gt; &lt;span class=&quot;literal&quot;&gt;Ok&lt;/span&gt;(Command::RIGHT),
            &lt;span class=&quot;string&quot;&gt;&quot;MOVE&quot;&lt;/span&gt; =&amp;gt; &lt;span class=&quot;literal&quot;&gt;Ok&lt;/span&gt;(Command::MOVE),
            &lt;span class=&quot;string&quot;&gt;&quot;REPORT&quot;&lt;/span&gt; =&amp;gt; &lt;span class=&quot;literal&quot;&gt;Ok&lt;/span&gt;(Command::REPORT),
            _ =&amp;gt; &lt;span class=&quot;literal&quot;&gt;Err&lt;/span&gt;(&lt;span class=&quot;built_in&quot;&gt;format!&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;&quot;Unknown command {}&quot;&lt;/span&gt;, input))
        }
    }
}

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;apply_commands&lt;/span&gt;&lt;/span&gt;(start: Position, commands: &lt;span class=&quot;built_in&quot;&gt;Vec&lt;/span&gt;&amp;lt;Command&amp;gt;) -&amp;gt; Position {
    commands.iter().fold(start, |position, command| {
        &lt;span class=&quot;keyword&quot;&gt;match&lt;/span&gt; command {
            Command::LEFT =&amp;gt; position.turn_left(),
            Command::RIGHT =&amp;gt; position.turn_right(),
            Command::MOVE =&amp;gt; position.move_forward(),
            Command::REPORT =&amp;gt; {
                report(&amp;amp;position);
                position
            }
        }
    })
}

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;report&lt;/span&gt;&lt;/span&gt;(position: &amp;amp;Position) {
    &lt;span class=&quot;built_in&quot;&gt;println!&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;&quot;{:?}&quot;&lt;/span&gt;, position);
}

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;read_file&lt;/span&gt;&lt;/span&gt;(file_path: &amp;amp;&lt;span class=&quot;keyword&quot;&gt;str&lt;/span&gt;) -&amp;gt; &lt;span class=&quot;built_in&quot;&gt;String&lt;/span&gt; {
    fs::read_to_string(file_path).expect(&amp;amp;&lt;span class=&quot;built_in&quot;&gt;format!&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;&quot;Failed to read file {}&quot;&lt;/span&gt;, file_path))
}

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;parse_input&lt;/span&gt;&lt;/span&gt;(content: &lt;span class=&quot;built_in&quot;&gt;String&lt;/span&gt;) -&amp;gt; (Position, &lt;span class=&quot;built_in&quot;&gt;Vec&lt;/span&gt;&amp;lt;Command&amp;gt;) {
    &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; lines: &lt;span class=&quot;built_in&quot;&gt;Vec&lt;/span&gt;&amp;lt;&amp;amp;&lt;span class=&quot;keyword&quot;&gt;str&lt;/span&gt;&amp;gt; = content.lines().collect();
    (get_start_position(&amp;amp;lines), get_commands(&amp;amp;lines))
}

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;get_start_position&lt;/span&gt;&lt;/span&gt;(lines: &amp;amp;&lt;span class=&quot;built_in&quot;&gt;Vec&lt;/span&gt;&amp;lt;&amp;amp;&lt;span class=&quot;keyword&quot;&gt;str&lt;/span&gt;&amp;gt;) -&amp;gt; Position {
    &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; first_line: &amp;amp;&lt;span class=&quot;keyword&quot;&gt;str&lt;/span&gt; = lines[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;];
    &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; args: &lt;span class=&quot;built_in&quot;&gt;Vec&lt;/span&gt;&amp;lt;&amp;amp;&lt;span class=&quot;keyword&quot;&gt;str&lt;/span&gt;&amp;gt; = first_line[&lt;span class=&quot;number&quot;&gt;6&lt;/span&gt;..].split(&lt;span class=&quot;string&quot;&gt;&quot;,&quot;&lt;/span&gt;).collect();
    Position {
        location: (args[&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;].parse().unwrap(), args[&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;].parse().unwrap()),
        orientation: args[&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;].parse().unwrap()
    }
}

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;get_commands&lt;/span&gt;&lt;/span&gt;(lines: &amp;amp;&lt;span class=&quot;built_in&quot;&gt;Vec&lt;/span&gt;&amp;lt;&amp;amp;&lt;span class=&quot;keyword&quot;&gt;str&lt;/span&gt;&amp;gt;) -&amp;gt; &lt;span class=&quot;built_in&quot;&gt;Vec&lt;/span&gt;&amp;lt;Command&amp;gt; {
    lines[&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;..].iter().map(|line| {
        line.trim()
    }).filter(|line| {
        !line.is_empty()
    }).map(|line| {
        line.parse().unwrap()
    }).collect()
}
&lt;/code&gt;&lt;/pre&gt;
</description>
    </item>
    <item>
      <title>The Joy and Terror of Hard Problems</title>
      <link>http://withouttheloop.com/articles/2021-12-05-hard-problems/</link>
      <pubDate>Sun, 05 Dec 2021 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2021-12-05-hard-problems/</guid>
      <author></author>
      <description>&lt;p&gt;Among software developers, and perhaps all creative engineers, hard problems are festishized.&lt;/p&gt;
&lt;p&gt;It’s a combination of the personality type that hungers for intellectual fulfilment, and the boredom that comes with the reality that most software development work is trivial and repetitive. Most projects are some kind of mutable list with some analysis on top.&lt;/p&gt;
&lt;h2 id=&quot;give-the-boring-problems-to-the-boring-computers&quot;&gt;Give the Boring Problems to the Boring Computers&lt;/h2&gt;
&lt;p&gt;For this reason I have long been an advocate of the &lt;em&gt;idea&lt;/em&gt; of higher-level programming via 4GLs or “low-code” tools. Why waste money on smart people implementing trivial solutions? It is a waste, good developers resent working below their capability, and they inevitably make the problem interesting for themselves by introducing complexity that is not necessary but feeds their intellectual curiosity.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2021-12-05-hard-problems/complexity.jpg&quot; alt=&quot;complex topology&quot;&gt;
&lt;small&gt;Photo by Glitch Lab App&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;I like the idea of these tools, although I’m not sure how pragmatic the available solutions are. They suffer from two clear failure modes. Firstly, by conflating programming with code they replace well-known, reusable coding skills with an equally complicated, non-transferable, bespoke graphical user interface based programming. It may be “low code” but it is just an inferior interface to creating abstract syntax trees. Secondly, such tools excel for certain low-complexity spaces, but fail spectacularly at higher complexity. Given that systems that survive tend to increase in complexity this creates a phenomenon where systems outgrow their low-code tool and have to be replaced. I’ll finish this tangent with an illustrative claim:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If your application is a set of lists with some reports on top then you are far better off with Foxpro or Access than with Angular and microservices&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If we leave the easy stuff to the machines we can clarify the software developer’s role as being one of applying deep intellectual effort to genuinely hard problems. &lt;/p&gt;
&lt;h2 id=&quot;the-dark-side-of-hard-problems&quot;&gt;The Dark Side of Hard Problems&lt;/h2&gt;
&lt;p&gt;Hard problems are hard.&lt;/p&gt;
&lt;p&gt;They create fear and anxiety. They carry a genuine risk of failure and real consequences. &lt;/p&gt;
&lt;p&gt;It is easy to crave an opportunity to work on something difficult, jump in full of ego, fail spectacularly, then quietly explain why it wasn’t our fault and can we please have another interesting challenge? &lt;/p&gt;
&lt;p&gt;Just because an organisation is prepared to explore the boundaries of what is known and undertake speculative research projects that carry a risk of failure, doesn’t mean that failure is a good outcome, or one that will be rewarded. &lt;/p&gt;
&lt;p&gt;Be scared of hard problems. Respect hard problems. Use that fear and respect to motivate extensive research, analytical decomposition of the problem, standing on the shoulders of giants, and doing absolutely everything you can to give yourself the best chance of success.&lt;/p&gt;
&lt;h2 id=&quot;the-joy-of-hard-problems&quot;&gt;The Joy of Hard Problems&lt;/h2&gt;
&lt;p&gt;Hard problems offer the possibility of deep engagement and immersion. The work is deeply satisfying and presents the possibility of ecstatic success. To succeed at something difficult is to place a milestone in your career that once accomplished can never be taken away. To leave a trail of such achievements, perhaps interspersed with the odd forgotten failure, seems to me the most fulfilling career imaginable. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2021-12-05-hard-problems/climber.jpg&quot; alt=&quot;A climber atop a mountain&quot;&gt;
&lt;small&gt;Photo by Nicholas Sampson&lt;/small&gt;&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Thinking Through a Problem with de Bono's Thinking Hats</title>
      <link>http://withouttheloop.com/articles/2021-06-21-deBonoThinkingHats/</link>
      <pubDate>Mon, 21 Jun 2021 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2021-06-21-deBonoThinkingHats/</guid>
      <author></author>
      <description>&lt;blockquote&gt;
&lt;p&gt;It’s time to put our thinking hat on - but which one?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Edward de Bono proposed a tool called the Six Thinking Hats that provides a methodical approach to thinking through a problem from different perspectives. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2021-06-21-deBonoThinkingHats/debono.jpg&quot; alt=&quot;Edward de Bono&quot;&gt;&lt;/p&gt;
&lt;p&gt;I’ve been reading de Bono’s &lt;a href=&quot;https://www.goodreads.com/book/show/98485.Teach_Your_Child_How_to_Think&quot;&gt;Teach Your Child How to Think&lt;/a&gt;. The title is misleading as the book is about thinking techniques, not specific to the education of children. I assume it was published at a time when the titles seemed like a good way to cash in on the &lt;a href=&quot;https://www.youtube.com/watch?v=bXg7KQ9jFpk&quot;&gt;as a guilty Mum(/Dad)&lt;/a&gt; social trend. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2021-06-21-deBonoThinkingHats/guiltymum.jpg&quot; alt=&quot;Guilty Mum&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;small&gt;Image from ABC’s ‘The Checkout’&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;On a whim, I put the audiobook on in the car to bore my oldest child as de Bono was explaining the usage of his &lt;strong&gt;six thinking hats&lt;/strong&gt;. Honestly, I’d been finding the book hard going, so putting it on in the car was mostly passive-agressive punishment for the transgressions my kid was yet to commit that day - but he loved it!&lt;/p&gt;
&lt;h2 id=&quot;the-six-thinking-hats&quot;&gt;The six thinking hats&lt;/h2&gt;
&lt;p&gt;The six thinking hats are a way of categorizing and remembering six distinctive approaches to problem solving. We are supposed to metaphorically (perhaps) put on one hat at a time and restrict ourselves to that approach for a period, then change to a different thinking hat. &lt;/p&gt;
&lt;h3 id=&quot;the-white-hat&quot;&gt;The White Hat&lt;/h3&gt;
&lt;p&gt;When wearing our white thinking hat our task is to collect data, information, and facts about the problem. de Bono emphasizes that perception is a more powerful problem-solving tool that logic, so its no surprise that this gets its own hat. It also reminds me of the data science axiom &lt;strong&gt;more data beats better algorithms&lt;/strong&gt;. &lt;/p&gt;
&lt;h3 id=&quot;the-yellow-hat&quot;&gt;The Yellow Hat&lt;/h3&gt;
&lt;p&gt;Like sunshine the yellow hat brings brightness and unfailing optimism. It is our Pollyanna hat that requires us to only see the best in ideas. &lt;/p&gt;
&lt;h3 id=&quot;the-black-hat&quot;&gt;The Black Hat&lt;/h3&gt;
&lt;p&gt;The black hat is the critical thinking hat and the opposite of the yellow hat. For this reason, we are supposed to ensure that we always wear the yellow hat before the black hat. My nine-year-old loved and remembered this idea for some reason. For many of us the black hat is the default hat, especially in business decisions. It is the hat the considers and evaluates risk. It is important, but de Bono argues that it is overused at the expense of creativity. &lt;/p&gt;
&lt;h3 id=&quot;the-red-hat&quot;&gt;The Red Hat&lt;/h3&gt;
&lt;p&gt;The red hat is worn when trying to choose a linux operating system.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2021-06-21-deBonoThinkingHats/laugh.jpg&quot; alt=&quot;Laughing&quot;&gt;
&lt;small&gt;Photo by Brooke Cagle&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;That was a joke. &lt;/p&gt;
&lt;p&gt;The red hat is the feelings hat. When a topic is emotive de Bono suggests starting with the red hat to get all the relevant feelings out in the open. &lt;/p&gt;
&lt;h3 id=&quot;the-green-hat&quot;&gt;The Green Hat&lt;/h3&gt;
&lt;p&gt;The green hat is the creativity hat. When wearing the creativity hat one can ignore facts, limitations, and the fear of bad ideas. &lt;/p&gt;
&lt;h3 id=&quot;the-blue-hat&quot;&gt;The Blue Hat&lt;/h3&gt;
&lt;p&gt;The blue hat is for thinking about thinking, or metacognition. We wear the blue hat to plan our use of the other hats. &lt;/p&gt;
&lt;p&gt;Those are de Bono’s six thinking hats. I’ve been thinking about them (black hat on) and I think they might be useful. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>Why C#'s `var` keyword is not always a good idea</title>
      <link>http://withouttheloop.com/articles/2021-05-31-var/</link>
      <pubDate>Mon, 31 May 2021 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2021-05-31-var/</guid>
      <author></author>
      <description>&lt;p&gt;The C# &lt;code&gt;var&lt;/code&gt; keyword is used to declare a variable whose type is inferred by the compiler. &lt;/p&gt;
&lt;p&gt;It’s good because it means we can go from:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;LongLongTypeName thing = new LongLongTypeName();
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;to&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var thing = new LongLongTypeName();
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That is shorter and hence easier to read, while conveying the same amount of information to both the compiler and a person reading this code. &lt;/p&gt;
&lt;p&gt;Alternatively, C# 9 allows&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;LongLongTypeName thing = new();
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;which, as Robert Frost said, is also great, and would suffice. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2021-05-31-var/ice.jpg&quot; alt=&quot;ice&quot;&gt;
Photo by Erin Mckenna&lt;/p&gt;
&lt;p&gt;All writers should consider their audience, and this also applies for writers of code. Once upon a time we wrote code for the compiler, but for the last thirty years or so the next programmer who will have to read your code has been the more important audience (the compiler is clever). Which brings me to the situation where type inference, and the &lt;code&gt;var&lt;/code&gt; keyword, is a problem:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var thing = gimmeSomeThing();
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The compiler, in its omnipotent wisdom, knows exactly what is going on, because it can see the &lt;code&gt;gimmeSomeThing&lt;/code&gt; function and know what type it denotes. The humble programmer however is left in the dark. Merely reading this code it is impossible to know what is the type of &lt;code&gt;thing&lt;/code&gt;. A clever IDE can tell me, or I can go and inspect the &lt;code&gt;gimmeSomeThing&lt;/code&gt; function, but all of this slows me down and creates one more thing that I need to keep track off. &lt;/p&gt;
&lt;p&gt;Hence, the takeaway:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Write code for the reader, not the compiler. Don’t use &lt;code&gt;var&lt;/code&gt; unless the inferred type is obvious. &lt;/p&gt;
&lt;/blockquote&gt;
</description>
    </item>
    <item>
      <title>The Most Important Consultant Skill</title>
      <link>http://withouttheloop.com/articles/2021-05-25-consulting-skill/</link>
      <pubDate>Tue, 25 May 2021 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2021-05-25-consulting-skill/</guid>
      <author></author>
      <description>&lt;blockquote&gt;
&lt;p&gt;Spoiler - it’s the ability to observe and identify our mistakes and micro-failures. &lt;/p&gt;
&lt;p&gt;These are our opportunities to learn and improve. We can be so busy trying to convince the world, and ourselves, of our awesomeness that we deny ourselves the opportunity to improve. &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Recently I was working with a colleague who is an exceptionally talented consultant. After a particular customer interaction he told me that something was bothering him. When he tried to work with the customer to co-design the optimal solution for a problem the customer insisted that it be solved the familiar way it had always been solved. No matter what he tried, he couldn’t get the customer to engage in a search for the best solution. They just wanted the old solution. We believe in outcomes over outputs, and one of our company values is “do what is best for the customer”. So he was right to identify this as a micro-failure. It’s good that it bothered him. It doesn’t put the project or the customer relationship in jeopardy, but by noticing and identifying something that could have been better he created the opportunity to learn a new skill and improve his capability. He put a grain of sand in his oyster. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2021-05-25-consulting-skill/pearl.jpg&quot; alt=&quot;Pearl&quot;&gt;
Photo by Anastasiia Rozumna on Unsplash&lt;/p&gt;
&lt;p&gt;We should attempt to observe these moments of sub-perfection, and try to understand them. Hold onto it. Think about it. We may not see a solution in the moment, but if we hold onto these gaps then one day we will see a solution, in something we read, something we see someone else do, or maybe it is just delivered by our sub-conscious. &lt;/p&gt;
&lt;p&gt;Being able to identify and acknowledge our weaknesses/gaps/failures and hold them in view until we match a solution, creates the possibility of improvement and is the most important capability a consultant can have.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2021-05-25-consulting-skill/cat.jpg&quot; alt=&quot;cat&quot;&gt;
Photo by Karina Vorozheeva on Unsplash&lt;/p&gt;
&lt;p&gt;Other domains, apart from consulting, have the same property. For example, programming computers. To improve we must be able to see when something could be better, and care to make it so. &lt;/p&gt;
&lt;p&gt;This advice was articulated brilliantly by &lt;a href=&quot;https://www.cs.utexas.edu/~EWD/transcriptions/EWD03xx/EWD340.html&quot;&gt;Edsger Dijkstra in 1972&lt;/a&gt;. &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The best way to learn to live with our limitations is to know them&lt;/em&gt; – Edsger Dijkstra&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Here we see a brilliant man reminding us that programming is hard, sometimes impossibly so. The best programmer, like the best consultant, is the one who knows their limitations and is vigilant in the search to combat them. &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;We shall do a much better programming job, provided that we approach the task with a full appreciation of its tremendous difficulty, provided that we stick to modest and elegant programming languages, provided that we respect the intrinsic limitations of the human mind and approach the task as Very Humble Programmers.&lt;/em&gt; – Edsger Dijkstra&lt;/p&gt;
&lt;/blockquote&gt;
</description>
    </item>
    <item>
      <title>Easy OKRs</title>
      <link>http://withouttheloop.com/articles/2021-05-06-okrs/</link>
      <pubDate>Thu, 06 May 2021 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2021-05-06-okrs/</guid>
      <author></author>
      <description>&lt;p&gt;A colleague asked about learning how to use OKRs (objectives and key results), so I’m re-posting here (waste not). &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“It almost doesn’t matter what you know. Execution is everything” - Andy Grove&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Here is my approach to learning OKRs:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Watch &lt;a href=&quot;https://www.ted.com/talks/john_doerr_why_the_secret_to_success_is_setting_the_right_goals?language=en#t-692734&quot;&gt;John Doerr’s TED Talk ‘Why the Secret to Success is Setting the Right Goals&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Listen to &lt;a href=&quot;https://www.listennotes.com/podcasts/you-exec-book/measure-what-matters-by-john-VoLRAtzgaD2/&quot;&gt;a summary of John’s book ‘Measure What Matters’&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Read &lt;a href=&quot;https://www.goodreads.com/book/show/39286958-measure-what-matters&quot;&gt;‘Measure What Matters’&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id=&quot;additional-thought-s-on-okr-usage&quot;&gt;Additional Thought’s on OKR Usage&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;OKRs are a tool for empowering individuals/teams. The people closest to the problem are empowered to find the best solution, instead of being given instructions. &lt;/li&gt;
&lt;li&gt;People/teams negotiate their own OKRs. They are not imposed. &lt;/li&gt;
&lt;li&gt;OKRs are an evolution of Drucker’s &lt;a href=&quot;https://en.wikipedia.org/wiki/Management_by_objectives&quot;&gt;Management by Objectives&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Less is more. OKRs help with focus and de-prioritization.&lt;/li&gt;
&lt;li&gt;Should be publically (within the organisation) visible.&lt;/li&gt;
&lt;li&gt;Must not be linked to pay/bonuses because it perverts the process. Failure must be allowed and expected. In this way it is different to management by objectives. &lt;/li&gt;
&lt;li&gt;Provides the basis for strategic planning. Issue trees and impact mapping can pickup from OKRs. &lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    <item>
      <title>A Modern Approach to Fixed-price Software Product Development</title>
      <link>http://withouttheloop.com/articles/2020-09-30-fixed-price-fixed-effort/</link>
      <pubDate>Wed, 30 Sep 2020 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2020-09-30-fixed-price-fixed-effort/</guid>
      <author></author>
      <description>&lt;p&gt;When purchasing software development services the customer wishes to optimize three variables: value, cost and risk. The approach described below is designed to maximize value and minimize cost and risk.&lt;/p&gt;
&lt;h1 id=&quot;fixed-price-fixed-effort&quot;&gt;Fixed-price, Fixed-effort&lt;/h1&gt;
&lt;p&gt;Consider the project ABCD.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2020-09-30-fixed-price-fixed-effort/project-abcd.png&quot; alt=&quot;Project ABCD&quot;&gt;
Figure 1: The ABCD project&lt;/p&gt;
&lt;p&gt;ABCD consists of four high-level components: A, B, C and D. Each component is subject to a high-level analysis to identify an appropriate budget. The budget is based on the expected value of the component and expert opinion of the investment required to deliver a quality, effective solution. &lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/th&gt;
&lt;th&gt;Effort Budget (days)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;B&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;30&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;D&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;35&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;90&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;br/&gt;The fixed-price is the vendor’s price for ninety days of effort. The fixed-effort is ninety days. The vendor and customer now form a fixed-price, fixed-effort agreement to deliver project ABCD. &lt;/p&gt;
&lt;p&gt;During delivery the customer and vendor prioritize and negotiate the details of each component to ensure that they fit within the effort budget.&lt;/p&gt;
&lt;h1 id=&quot;fixed-price&quot;&gt;Fixed-price&lt;/h1&gt;
&lt;p&gt;Fixing the price has the benefit of controlling the customer’s cost risk. While not denying the value of controlling cost there are some caveats that must be noted. Firstly, like the hydra, risk is a many-headed beast and cost is rarely the risk that causes failure. The greater risk is the risk of delivering a solution that does not achieve the required outcome. It does not matter how effectively the cost risk is controlled if the solution does not solve the problem. In this case every dollar that was spent returned nothing. &lt;/p&gt;
&lt;p&gt;Unfortunately, the most common technique for controlling cost, fixed-price fixed-scope, dramatically increases the chance of delivering a solution that is not fit for purpose (see &lt;a href=&quot;http://withouttheloop.com/articles/2020-09-30-fixed-price-bad-idea/&quot;&gt;Why Fixed-price, Fixed-scope Is Bad For The Customer&lt;/a&gt;).&lt;/p&gt;
&lt;h1 id=&quot;fixed-effort&quot;&gt;Fixed-effort&lt;/h1&gt;
&lt;p&gt;Fixing the effort ensures efficiency. &lt;/p&gt;
&lt;p&gt;Imagine a scenario where the planned implementation of a blockchain storage mechanism is discovered to require twice as much effort as expected, but a database solution is available for less than the original estimate, delivering 99% of the functionality. Because the customer and vendor are required to jointly prioritize and negotiate the details of each component to fit the effort estimate their motivations are aligned to make the sensible decision and choose the database solution. &lt;/p&gt;
&lt;p&gt;Each feature and decision is necessarily scrutinized to ensure that it serves the goals of the project. It becomes very difficult for pet features, unjustified features and gold-plating to sneak in. &lt;/p&gt;
&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;The final reason to support a fixed-price, fixed-effort approach is that other fixed-price approaches empirically do not work. The control of cost risk is lost to predatory change requests and the necessity of following the plan prevents the team from pursuing value and a system that will achieve its outcome. &lt;/p&gt;
&lt;p&gt;Finally, fixed-price fixed scope misalignes incentives in a way that prevents efficient delivery. For more, see &lt;a href=&quot;http://withouttheloop.com/articles/2020-09-30-fixed-price-bad-idea/&quot;&gt;Why Fixed-price, Fixed-scope Is Bad For The Customer&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Why Fixed-price, Fixed-scope Is Bad For The Customer</title>
      <link>http://withouttheloop.com/articles/2020-09-30-fixed-price-bad-idea/</link>
      <pubDate>Wed, 30 Sep 2020 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2020-09-30-fixed-price-bad-idea/</guid>
      <author></author>
      <description>&lt;p&gt;A common design of a fixed-price, fixed scope agreement is:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Attempt to define the solution up-front, based on expert knowledge and instinct&lt;/li&gt;
&lt;li&gt;Establish a competitive procurement process, based on the defined requirements&lt;/li&gt;
&lt;li&gt;Select the partner who promises the best combination of cost effectiveness and compelling proposal&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The above approach effectively guarantees failure. Unfortunately, it is a popular approach among large enterprises. I can understand why. It seems to promise achieving the required outcome while shifting all risk to the vendor. In addition it looks like it should achieve cost effectiveness due to the competitive procurement process. This procurement approach is an understandable attempt to apply practices that work in other domains, such as purchasing heavy equipment or the construction of roads, to the domain of software development. The approach fails because software development is not the same as building a road, specifically it has much greater uncertainty and much lower cost of change. &lt;/p&gt;
&lt;p&gt;The unfortunate irony is that the well-intentioned attempt to protect the purchasing organisation almost guarantees an unsuccessful outcome. This happens because the procurement logic described above rests on a number of incorrect assumptions.&lt;/p&gt;
&lt;h1 id=&quot;myth-1-the-customer-knows-and-can-define-the-solution-to-their-problem&quot;&gt;Myth 1: The customer knows, and can define, the solution to their problem&lt;/h1&gt;
&lt;p&gt;Observe &lt;a href=&quot;https://pragprog.com/titles/jtrap/the-agile-samurai/&quot;&gt;Jonathan Rasmusen&lt;/a&gt;’s facts of software development:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;You can’t gather all the requirements up front.&lt;/li&gt;
&lt;li&gt;The requirements you do gather will change.&lt;/li&gt;
&lt;li&gt;There is always more to do than time and money will allow.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In the beginning, I don’t know the solution to my customer’s problem, and nor do they. The competitive procurement process presupposes that it is possible to define what is needed so that vendors can propose approaches and compete on price, with a shared definition of what will be delivered. It is not possible to precisely define a solution and if it was you’d be defining the wrong solution anyway. Inexperienced customers think they can define what they need. Predatory vendors know better and exploit the knowledge asymmetry, making their money on change requests. &lt;strong&gt;Fixed-price, fixed-scope doesn’t fix the price at all&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;I once triggered an angry reaction in a project sponsor when I asked why the organisation wanted to fund the project we were discussing. He was ready to spend hundreds of thousands of dollars without the faintest idea of why. How can you know the optimal solution if you don’t even know why you are doing the work? The customer had carefully implemented their competitive procurement process, dutifully documented their requirements and engaged vendors, all without giving a thought to what outcome they were trying to achieve. &lt;/p&gt;
&lt;p&gt;Our business is divided into a number of capabilities, one of which is design. The first responsibility of the design capability is to help customers understand their problem and discover the best solution. These are highly skilled specialists, focused on solution discovery via careful application of the scientific method. They exist because instinct is not enough. You have an instinctive understanding of your customers and your coworkers and you know which solution will work. So do I, and we are both wrong. Leading technology companies understand this. Google doesn’t assume they can guess what solution they need. Microsoft doesn’t do it. Amazon certainly doesn’t do it. They have acquired humility through hard lessons. Instead of guessing they do the work to discover, test, prototype, research and validate their ideas. It is the less advanced organisations that believe they can take a blank page and guess the solution that is going to work. &lt;/p&gt;
&lt;p&gt;As a purchaser of technology services, don’t pay someone to implement a solution, pay them to help you to achieve an outcome. The best way to achieve that outcome is something you will discover together as the project progresses.&lt;/p&gt;
&lt;h1 id=&quot;myth-2-a-project-that-is-on-time-and-on-budget-is-a-successful-project&quot;&gt;Myth 2: A project that is on-time and on-budget is a successful project&lt;/h1&gt;
&lt;p&gt;Fixed-price, fixed-scope doesn’t say anything about outcomes. The focus is 100% on costs and 0% on value. The process is designed to reduce the risk of being over budget and over time, and ignores the greater risk of failing to solve the problem. Also, not very effective at being on time and on budget. Focusing on cost, schedule and scope establishes a competitive environment that makes it hard to deliver a valuable outcome. The customer is incentivized to get as much as they can for as little as possible. The vendor is incentived to charge as much as possible for as little as possible. This creates an environment of conflict and an emphasis on following the plan over delivering something that is actually valuable. &lt;/p&gt;
&lt;p&gt;So, how do we all succeed together?&lt;/p&gt;
&lt;h1 id=&quot;fixed-price-fixed-effort&quot;&gt;Fixed-price, Fixed-effort&lt;/h1&gt;
&lt;p&gt;I propose a different fixed-price approach called &lt;a href=&quot;http://withouttheloop.com/articles/2020-09-30-fixed-price-fixed-effort/&quot;&gt;fixed-price, fixed-effort&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Linear Feedback</title>
      <link>http://withouttheloop.com/articles/2019-09-11-linear-feedback/</link>
      <pubDate>Wed, 11 Sep 2019 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2019-09-11-linear-feedback/</guid>
      <author></author>
      <description>&lt;p&gt;Feedback should be DIRECT. Provide feedback immediately, consistently, and to the subject of the feedback. This is often not what happens.&lt;/p&gt;
&lt;h2 id=&quot;triangular-feedback&quot;&gt;Triangular Feedback&lt;/h2&gt;
&lt;p&gt;Most people, myself included, would rather pull their fingernails off than give someone critical feedback. Yet feedback is an essential tool, especially for leaders. It is necessary because:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;high performers, especially those motivated by the need for achievement, are hungry for feedback as a tool for self-awareness and self-improvement&lt;/li&gt;
&lt;li&gt;without feedback you may set expectations but they will be ignored. Feedback is the tool by which we demonstrate that we mean what we say.&lt;/li&gt;
&lt;li&gt;feedback accelerates learning. It improves the performance of individuals and teams. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We know we should give feedback, but we hate it, so often we give feedback to a third party, “hey Alice, Bob has been writing a lot of insecure software lately”. This is called Triangular feedback, the intention being that Alice should pass on the feedback to Bob. Unfortunately, this is just gossip. Bob’s reputation is tarnished and he is unable to defend himself. The person most able to improve Bob’s performance is Bob, so that is who needs to receive the feedback. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2019-09-11-linear-feedback/triangular-feedback.png&quot; alt=&quot;Triangular feedback&quot;&gt;
&lt;em&gt;The feedback triangle&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Attribute_substitution#History&quot;&gt;Tversky and Kahneman&lt;/a&gt; proposed a family of cognitive biases that reduce the effort of decision making by replacing (substituting) a hard question with an easy question. For example, in 1899 when required to chose a leader the American voters elected President Harding, “whose only qualification for the position was that he perfectly looked the part” (Kahneman, 2011). They replaced a hard question (who would be the best leader), with an easier one (who looks strong and decisive). So it is with feedback that we replace the hard thing (giving a person feedback that they may not like) with an easier thing (gossiping to a third-party). Unfortunately, the value of feedback is lost and the harmful side-effects of gossip are introduced.  &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2019-09-11-linear-feedback/harding.jpg&quot; alt=&quot;President Harding&quot;&gt;
&lt;em&gt;Strong and decisive?&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&quot;linear-feedback&quot;&gt;Linear Feedback&lt;/h2&gt;
&lt;p&gt;Either give feedback directly to the subject, or keep it to yourself. &lt;/p&gt;
&lt;p&gt;Linear feedback is my personal rule, and a virus I’d like to spread, that I won’t be involved in triangular feedback. If someone comes to me with feedback about someone else, I ask them to give the feedback directly. I also do not enjoy being the subject of triangular feedback. When it happens I suggest that the commentor bring their concerns to me directly. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2019-09-11-linear-feedback/linear-feedback.png&quot; alt=&quot;Linear feedback&quot;&gt;
&lt;em&gt;Linear feedback&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Feedback triangles are pervasive and unproductive. Let’s do better. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>Impact Mapping is Better Than the Impact/Effort Matrix</title>
      <link>http://withouttheloop.com/articles/2019-07-12-impact-mapping-impact-effort-matrix/</link>
      <pubDate>Fri, 12 Jul 2019 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2019-07-12-impact-mapping-impact-effort-matrix/</guid>
      <author></author>
      <description>&lt;h1 id=&quot;impact-effort-matrix&quot;&gt;Impact/effort matrix&lt;/h1&gt;
&lt;p&gt;An Impact/Effort Matrix is a quadrant model that ranks initiatives by impact and effort. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2019-07-12-impact-mapping-impact-effort-matrix/theory.jpg&quot; alt=&quot;How the Impact Effort Matrix is supposed to work&quot;&gt;
&lt;em&gt;How the Impact/Effort Matrix is supposed to work&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;It is meant as a rough strategic planning tool that can separate high net-value initiatives (easy wins) from low net-value initiatives (money pit). &lt;a href=&quot;https://www.linkedin.com/pulse/why-prioritization-impacteffort-doesnt-work-itamar-gilad/&quot;&gt;Itamar Gilad&lt;/a&gt; explains that it does not work because we cannot reliably estimate effort or impact. Many of the identified high-impact, low-effort initiatives will turn out to be low-impact and high-effort. They are also likely to have no impact or a negative impact. Thus, he suggests the matrix is more like this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2019-07-12-impact-mapping-impact-effort-matrix/practice.jpg&quot; alt=&quot;Impact/Effort Matrix in practice&quot;&gt;
&lt;em&gt;Impact/Effort Matrix in practice&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The reason to use a tool like the Impact/Effort Matrix is to combat the bias in favour of pet projects. However, because the impact assessment is entirely subjective people simply push their pet projects to the high-impact side. Every matrix ends up looking like this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2019-07-12-impact-mapping-impact-effort-matrix/impacteffort.gif&quot; alt=&quot;Actual Impact/Effort Matrix&quot;&gt;&lt;/p&gt;
&lt;p&gt;Thus we learn nothing about how to prioritize investments. &lt;/p&gt;
&lt;h1 id=&quot;impact-mapping&quot;&gt;Impact mapping&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://www.impactmapping.org/about.html&quot;&gt;Impact mapping&lt;/a&gt; is another technique that attempts to solve the same investment decision problem. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2019-07-12-impact-mapping-impact-effort-matrix/im_template.png&quot; alt=&quot;Impact Map&quot;&gt;
&lt;em&gt;from &lt;a href=&quot;https://www.impactmapping.org/drawing.html&quot;&gt;https://www.impactmapping.org/drawing.html&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Rather than a subjective assessment of impact, Impact Mapping requires a causal mapping of initiatives to goals. Instead of simply saying, “chats will be high impact” I have to make the case that &lt;strong&gt;implementing chats&lt;/strong&gt; will cause the &lt;strong&gt;super-fans with mobile devices&lt;/strong&gt; to &lt;strong&gt;stay longer&lt;/strong&gt; thus &lt;strong&gt;growing mobile advertising&lt;/strong&gt;. In this way Impact mapping is a collaborative strategic planning tool that documents not just what we might do, but why and how that thing will be useful. &lt;/p&gt;
&lt;p&gt;Each step in the chain forms a hypothesis, that can be validated by an experiment, such as user testing with a prototype, an MVP or an A/B test. They can be formulated into the “Feature Hypothesis Statement Template” (from &lt;a href=&quot;https://www.amazon.com/Lean-UX-Designing-Great-Products/dp/1491953608&quot;&gt;Lean UX&lt;/a&gt;):&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2019-07-12-impact-mapping-impact-effort-matrix/hypothesis.png&quot; alt=&quot;Feature Hypothesis statement template&quot;&gt;&lt;/p&gt;
&lt;p&gt;To use the previous example:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;We belienve &lt;strong&gt;growing mobile advertising&lt;/strong&gt; will be achieved if &lt;strong&gt;super-fans with mobile devices&lt;/strong&gt; successfully achieve &lt;strong&gt;staying longer&lt;/strong&gt; with &lt;strong&gt;chats&lt;/strong&gt;. &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Impact Mapping provides a structured framework for evaluating &lt;em&gt;things we might do&lt;/em&gt;. It doesn’t magically deliver an optimal investment plan but it does surface the assumptions we are using, allowing us to test them, track them, and correct them when they turn out to be wrong. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>Technology Leadership and Management Newsletter</title>
      <link>http://withouttheloop.com/articles/2019-07-03-newsletter/</link>
      <pubDate>Wed, 03 Jul 2019 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2019-07-03-newsletter/</guid>
      <author></author>
      <description>&lt;p&gt;I read and think a lot, and write a little, about improving the effectiveness of technology creation teams. Since I do all the hard work anyway I might as well share, so I am publishing a fortnightly newsletter on technology leadership and management.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.getrevue.co/profile/liam-mclennan&quot;&gt;https://www.getrevue.co/profile/liam-mclennan&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Sign up if you are interested. No ads. No spam. &lt;/p&gt;
&lt;h1 id=&quot;-first-edition-https-www-getrevue-co-profile-liam-mclennan-issues-how-to-kill-software-projects-inspired-book-review-improving-design-sprints-185213-&quot;&gt;&lt;a href=&quot;https://www.getrevue.co/profile/liam-mclennan/issues/how-to-kill-software-projects-inspired-book-review-improving-design-sprints-185213&quot;&gt;First Edition&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;The last 20 years have shown that product development needs to be considered broadly, from, “we have no idea what we are going to do” all the way to retiring a successful product. The old idea that product development begins with software developers implementing perfectly defined features has become uncompetitive.
An effective product development organisation needs to master technology strategy and design. Marty Cagan (author of Inspired) is possibly the most articulate voice promoting this idea and explaining how to do it.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&quot;https://medium.com/@maa1/book-review-inspired-how-to-create-tech-products-customers-love-4fc8e8f26739?utm_campaign=Technology%20Leadership%20Post&amp;amp;utm_medium=email&amp;amp;utm_source=Revue%20newsletter&quot;&gt;Book review: “Inspired: How To Create Tech Products Customers Love”&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&quot;https://techbeacon.com/app-dev-testing/project-management-surefire-way-kill-your-software-product?utm_campaign=Technology%20Leadership%20Post&amp;amp;utm_medium=email&amp;amp;utm_source=Revue%20newsletter&quot;&gt;Project management: A surefire way to kill your software product | TechBeacon&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&quot;https://www.invisionapp.com/inside-design/design-sprints-need-iteration/?utm_campaign=Technology%20Leadership%20Post&amp;amp;utm_medium=email&amp;amp;utm_source=Revue%20newsletter&quot;&gt;Design sprints need iteration | Inside Design Blog&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    <item>
      <title>Why Steve Mcconnell is wrong about software estimation</title>
      <link>http://withouttheloop.com/articles/2019-01-28-why-mcconnell-is-wrong/</link>
      <pubDate>Mon, 28 Jan 2019 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2019-01-28-why-mcconnell-is-wrong/</guid>
      <author></author>
      <description>&lt;p&gt;Maybe not so much “wrong” as 30 years ago. The software development community has continued to learn and discover new approaches that produce better results. This article is a critique of Mcconnell’s &lt;a href=&quot;https://stevemcconnell.com/blog/17-theses-software-estimation/&quot;&gt;17 Theses on Software Estimation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This came up following responses to my article, &lt;a href=&quot;https://withouttheloop.com/articles/2019-01-27-estimate-without-estimating/&quot;&gt;How To “Estimate” Without Estimating&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Let’s take Mcconnell’s points in turn. &lt;/p&gt;
&lt;h3 id=&quot;1-estimation-is-often-done-badly-and-ineffectively-and-in-an-overly-time-consuming-way-&quot;&gt;1. Estimation is often done badly and ineffectively and in an overly time-consuming way.&lt;/h3&gt;
&lt;p&gt;Classic you’re holding it wrong. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2019-01-28-why-mcconnell-is-wrong/fullbars.jpg&quot; alt=&quot;Holding it wrong&quot;&gt; &lt;/p&gt;
&lt;p&gt;I’m not saying he is wrong, just that it doesn’t add anything to the conversation. You can defend any practice by claiming that everyone but you is doing it wrong. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2019-01-28-why-mcconnell-is-wrong/water.jpg&quot; alt=&quot;Water divining&quot;&gt;&lt;/p&gt;
&lt;p&gt;I do partly agree with Mcconnell. Practices like “planning poker” have always seemed silly to me. Even if it produces better estimates (not saying it does) the massive cost is not worth it.&lt;/p&gt;
&lt;h3 id=&quot;3-many-comments-in-support-of-noestimates-demonstrate-a-lack-of-basic-software-estimation-knowledge-&quot;&gt;3. Many comments in support of #NoEstimates demonstrate a lack of basic software estimation knowledge.&lt;/h3&gt;
&lt;p&gt;My complaint is similar to before. This comment adds nothing and is just insulting the other side. It is even a variation on “you’re holding it wrong”. This time it’s “you lack knowledge”. Obviously, this is not an argument. &lt;/p&gt;
&lt;h3 id=&quot;4-being-able-to-estimate-effectively-is-a-skill-that-any-true-software-professional-needs-to-develop-even-if-they-don-t-need-it-on-every-project-&quot;&gt;4. Being able to estimate effectively is a skill that any true software professional needs to develop, even if they don’t need it on every project.&lt;/h3&gt;
&lt;p&gt;100% agree. As I said in my article, estimation is essential. Estimation a backlog and using that as the basis for a project is the mistake. Without some level of estimation it would be impossible to schedule anything. &lt;/p&gt;
&lt;h3 id=&quot;5-estimates-serve-numerous-legitimate-important-business-purposes-&quot;&gt;5. Estimates serve numerous legitimate, important business purposes.&lt;/h3&gt;
&lt;p&gt;Again, this is a valid statement. His first example, “allocating budgets to projects” is pretty much the only legitimate use of estimates for most circumstances. &lt;/p&gt;
&lt;p&gt;He then makes a valid criticism of “#NoEstimates” advocates for criticising estimates without providing anything resembling an alternative. He then returns to criticising them for not being able to estimate properly and throws in a sick burn, “improved estimation skill should be part of the definition of being a true software professional”. This is odd, since Mcconnell has previously conceded that professional software estimators cannot reliably predict the future, and that estimates at project inception are frequently off by 400%:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The primary purpose of software estimation is not to predict a project’s outcome; it is to determine whether a project’s targets are realistic enough to allow the project to be controlled to meet them.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;His own graphic makes the same point.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2019-01-28-why-mcconnell-is-wrong/cone.jpg&quot; alt=&quot;Cone of uncertainty&quot;&gt;&lt;/p&gt;
&lt;p&gt;According to this, we can reduce the uncertainty to 50%, by completing the detailed requirements. That is, if we give up on agility and spend 1/3 of the cost of the project, we can get a wildly inaccurte estimate. &lt;/p&gt;
&lt;h3 id=&quot;7-estimation-and-planning-are-not-the-same-thing-and-you-can-estimate-things-that-you-can-t-plan-&quot;&gt;7. Estimation and planning are not the same thing, and you can estimate things that you can’t plan.&lt;/h3&gt;
&lt;p&gt;Completely agree. This topic demonstrates that much of the disagreement is just confusion about what we mean by “estimate”. The way that McConnell uses “estimate” is not the way that 99% of the software development industry uses it. When people talk about estimating they mean: define the solution, break it down, add up guesses about how long the pieces will take. &lt;/p&gt;
&lt;p&gt;If you remove the planning part from the estimation then the problems with estimation largely go away, so long as the uncertainty involved (400% according to McConnell) is understood and accepted by everyone. &lt;/p&gt;
&lt;h3 id=&quot;8-you-can-estimate-what-you-don-t-know-up-to-a-point-&quot;&gt;8. You can estimate what you don’t know, up to a point.&lt;/h3&gt;
&lt;p&gt;“Most projects contain a mix of precedented and unprecedented work, or certain and uncertain work” McConnell says. Here we start to see that McConnell’s conception of knowledgable, professional estimator is a person who essentially builds the same project over and over, and can notice how long it takes. It is rediculous to claim that estimation is a matter of experience and skill when you are excluding any original work by definition. Estimating things that you have not done before is the only kind that makes sense to discuss. If you have done it before, why are doing it again?&lt;/p&gt;
&lt;h3 id=&quot;9-both-estimation-and-control-are-needed-to-achieve-predictability-&quot;&gt;9. Both estimation and control are needed to achieve predictability.&lt;/h3&gt;
&lt;p&gt;Once again the disagreement is down to how you define “estimation”. If you are estimating a defined solution then this point is invalid. Control has already been given away. When McConnell says estimation here he means estimating a solution that has not been defined. &lt;/p&gt;
&lt;h3 id=&quot;10-people-use-the-word-estimate-sloppily-&quot;&gt;10. People use the word “estimate” sloppily.&lt;/h3&gt;
&lt;p&gt;Agreed. The irony is palpable. McConnell manages to argue for estimation by assuming a definition that nobody else has. Just like the time that &lt;a href=&quot;https://www.vice.com/en_ca/article/qvqa7v/trumps-wall-is-now-a-fence-or-maybe-nothing-at-all&quot;&gt;someone argued for a wall that everyone else thought was a fence&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;11-good-project-level-estimation-depends-on-good-requirements-and-average-requirements-skills-are-about-as-bad-as-average-estimation-skills-&quot;&gt;11. Good project-level estimation depends on good requirements, and average requirements skills are about as bad as average estimation skills.&lt;/h3&gt;
&lt;p&gt;McConnell starts by saying that it is possible to get good requirements. This is easily disproven with a simple scenario.&lt;/p&gt;
&lt;p&gt;An ecommerce project is delivered over 10 iterations. After the first iteration the product is shipped to real users, who interact with it in ways that do not entirely match the assumptions made during development. For iteration two the teams makes substantial changes that produce a far more successful outcome. Unless McConnell has a crystal ball he cannot possibly have had correct requirements in advance of actual product usage, and without knowing what the product needed to be he would have a hard time producing those amazing knowledgable, professional estimates. &lt;/p&gt;
&lt;p&gt;This is what I mean about McConnell having an excellent interpretation of what was known about software development thirty years ago. He proves this further by arguing that businesses should abandon agility in favour of predictibility. He values predictibility even if it means knowingly building the wrong thing. About this time I started wondering how long McConnell has been in a bunker. Maybe one behind a waterfall. &lt;/p&gt;
&lt;h3 id=&quot;12-the-typical-estimation-context-involves-moderate-volatility-and-a-moderate-levels-of-unknowns&quot;&gt;12. The typical estimation context involves moderate volatility and a moderate levels of unknowns&lt;/h3&gt;
&lt;p&gt;“The typical software project has requirements that are knowable in principle, but that are mostly unknown in practice due to insufficient requirements skills.” Once again, everyone except McConnell is doing it wrong. &lt;/p&gt;
&lt;h3 id=&quot;13-responding-to-change-over-following-a-plan-does-not-imply-not-having-a-plan-&quot;&gt;13. Responding to change over following a plan does not imply not having a plan.&lt;/h3&gt;
&lt;p&gt;This is another point on which we completely agree. Before starting to write code, we should think. I think where we disagree is that my idea of a plan is not a backlog. &lt;/p&gt;
&lt;p&gt;McConnell ridiculues “treating 100% of the project as emergent” and implies that 0% of the project should be emergent, stating that typical projects are, “amenable to having both effective requirements work and effective estimation work performed on those projects, given sufficient training in both skill sets”.&lt;/p&gt;
&lt;p&gt;We both believe in planning, I just don’t think that planning requires detailed requirements specification. &lt;/p&gt;
&lt;h3 id=&quot;14-scrum-provides-better-support-for-estimation-than-waterfall-ever-did-and-there-does-not-have-to-be-a-trade-off-between-agility-and-predictability-&quot;&gt;14. Scrum provides better support for estimation than waterfall ever did, and there does not have to be a trade off between agility and predictability.&lt;/h3&gt;
&lt;p&gt;McConnel supports his argument for estimation based on projecting from a measured velocity. All the time he has been arguing that professionals can produce effective estimation he has neglected to mention that they have to start the project first. &lt;/p&gt;
&lt;h3 id=&quot;16-this-is-not-religion-we-need-to-get-more-technical-and-economic-about-software-discussions-&quot;&gt;16. This is not religion. We need to get more technical and economic about software discussions.&lt;/h3&gt;
&lt;p&gt;McConnell says, “I’ve seen #NoEstimates advocates treat these questions of requirements volatility, estimation effectiveness, and supposed tradeoffs between agility and predictability as value-laden moral discussions”. This is in the same article where he previously described these people as lacking knowledge and skill because they hold an opinion different to his. &lt;/p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;
&lt;p&gt;NoEstimates folk say estimation doens’t work. They mean that you can’t guess how much effort will be required to implement something before you’ve started, and if you could you would have had to commit to a big-design-up-front waterfall process. &lt;/p&gt;
&lt;p&gt;McConnell says that estimates are useful and possible if you do his training course and are a “professional”. He means that if you make a substantial upfront investment to define the requirements, and are prepared to stick to that plan, even when you learn it is wrong, then you can produce an estimate with only 50% uncertainty. You are free to change the requirements (be agile) but that invalidates your estimate. &lt;/p&gt;
&lt;p&gt;They agree on the basic facts  but manage to make an argument by being sloppy with definitions. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>How To &quot;Estimate&quot; Without Estimating</title>
      <link>http://withouttheloop.com/articles/2019-01-27-estimate-without-estimating/</link>
      <pubDate>Sun, 27 Jan 2019 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2019-01-27-estimate-without-estimating/</guid>
      <author></author>
      <description>&lt;p&gt;The trouble with estimation is that it is both essential and impossible. &lt;/p&gt;
&lt;p&gt;For some time one of the great twitter battlegrounds has been #NoEstimates. The clickbaity hashtag encourages the two sides to talk past each other and claim intellectual superiority. For instance:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“The #NoEstimates advocates are essentially uninformed about basic probabilistic decision making and willfully ignores the principles to be found easily on the web A middle schooler with Google knows more than they do”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Nice one. Here comes the reply!&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“That argument is bullshit. But I’ll let it slide because you obviously have read anything at all about #NoEstimates Start here. 6 authors, 20+ blog posts &lt;a href=&quot;http://softwaredevelopmenttoday.com/noestimates&quot;&gt;http://softwaredevelopmenttoday.com/noestimates&lt;/a&gt;“&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The trouble with estimation is that it is both essential and impossible. It is also harmful. There is a battle tested way to get the benefits of estimation, without the problems of actually doing it. But first, some context. &lt;/p&gt;
&lt;h2 id=&quot;how-estimation-is-essential&quot;&gt;How Estimation is Essential&lt;/h2&gt;
&lt;p&gt;Estimation is essential. My family are considering renovating our house. If the builder told me he would like to start the project, measure velocity and then give me a projection of possible costs our conversation would be over. I don’t have unlimited funds and I cannot sponsor an unlimited construction budget. Similarly, my consulting clients inevitably want to know roughly how much they need to invest to get their problem solved. It is not fair to simply say that estimation is hard and the work will be finished when it is finished. &lt;/p&gt;
&lt;h2 id=&quot;how-estimation-is-impossible&quot;&gt;How Estimation is Impossible&lt;/h2&gt;
&lt;p&gt;I am tempted to simply state this one as an axiom, however, I know there are people who disagree. I have been a professional software developer for 20 years and have never met anyone who could estimate accurately. The way it is frequently simulated is simply to estimate far too high, then keep working until you hit your estimate. Magic! If a team goes over an estimate it is visible, if they are under the estimate they appear exactly on time. &lt;/p&gt;
&lt;p&gt;That’s just an anecdote. Good point. Here are some more:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Estimates are difficult. When requirements are vague — and it seems that they always are — then the best conceivable estimates would also be very vague. Accurate estimation becomes essentially impossible. Even with clear requirements — and it seems that they never are — it is still almost impossible to know how long something will take, because we’ve never done it before. If we had done it before, we’d just give it to you.” – &lt;a href=&quot;http://ronjeffries.com/xprog/articles/the-noestimates-movement/&quot;&gt;Ron Jeffries&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;“Every project contains uncertainty. If it doesn’t you shouldn’t be doing it — it’s already been solved!” – &lt;a href=&quot;https://dannorth.net/2013/08/08/blink-estimation/&quot;&gt;Dan North&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If you prefer data, the CHAOS report has found consistently that 75% of projects are late/over budget or failed. Even a proponent of estimates, Steve McConnell, says, “we have come to value project control over project estimation, as a means of achieving predictability”.  &lt;/p&gt;
&lt;p&gt;All of that is to say why we cannot predict the amount of effort required to deliver a particular, defined feature. Here is an even bigger problem. People want estimates before they commit to an initiative. In the agile world an initiative is a problem to solve - there is no particular defined feature. Unless we are doing big-design-up-front and prematurely committing to a solution of a problem not yet well understood there isn’t even anything to estimate. It’s like asking my builder to accurately estimate my renovation defined as “more space and brighter colours”. &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Predefined backlogs of work reduce creativity and inhibit steering the project for success.” – &lt;a href=&quot;https://pragprog.com/magazines/2013-04/estimation&quot;&gt;Ron Jeffries&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;how-estimation-is-harmful&quot;&gt;How Estimation is Harmful&lt;/h2&gt;
&lt;p&gt;Return on investment depends upon cost and value. The focus on estimation puts the emphasis entirely on the cost side. When was the last time someone asked for an estimate that included an estimate of value? Teams that focus on estimates tend to track progress against cost, but do they track progress against value? (see &lt;a href=&quot;https://withouttheloop.com/articles/2018-12-12-project-lamb-meatballs/&quot;&gt;Project Lamb Meatballs - Value-based vs Project-based Portfolio Management&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;As high performing teams move from managing outputs to managing outcomes it is natural to shift emphasis from cost towards value. Ron Jeffries agrees, “teams focused on estimation are generally working the short end of the lever of cost vs. value. Better teams focus more on value and less on cost”. &lt;/p&gt;
&lt;p&gt;Estimates encourage a zero-sum mindset. On the customer side I want to get as much as I can for as little as possible to demonstrate my superior negotiation capability. Teams get beaten up over their estimates, which were impossible to start with. Then they cut corners and find ways to get back to the estimate, at the cost of creating real value. Estimates are disputed and argued over, then when a requirement changes, the battle starts all over again. &lt;/p&gt;
&lt;p&gt;Perhaps most importantly, estimation locks us into a path (the one we estimated), chosen at a time when we had the least possible information (before we started). Intelligent, motivated professionals are unable to pursue to best outcome because they are locked into a specific course of action. In theory it is possible to significantly renegotiate the agreed scope. In practice people tend to just stick to the plan. &lt;/p&gt;
&lt;h2 id=&quot;how-estimation-is-helpful&quot;&gt;How Estimation is Helpful&lt;/h2&gt;
&lt;p&gt;I once built a deck. I am not a builder and I did not know how to build a deck, therefore I accepted that estimation was impossible. I knew enough to know that the raw materials would be less than $10,000. The other investment was my labour, which I was prepared to contribute until the job was done. I did not estimate the project, but I assembled enough information to support the investment decision. I wanted a deck and I got one within an acceptable cost. &lt;/p&gt;
&lt;h2 id=&quot;how-to-estimate-without-estimating&quot;&gt;How to Estimate Without Estimating&lt;/h2&gt;
&lt;p&gt;Here is how this might play out in a consulting scenario:&lt;/p&gt;
&lt;p&gt;Me: “Hi, I’d like a deck please! How much will that cost?”&lt;/p&gt;
&lt;p&gt;Builder: “‘Deck’ does not precisely define what you want, so I cannot provide an exact figure. Looking at your house, and knowing the type of decks people tend to build for this type of property and in this location I can build you a deck for $10,000. If you’d like a really fancy deck then budget $15,000. I am confident that I can deliver “a deck” within these parameters.”&lt;/p&gt;
&lt;p&gt;Me: “Woo hoo!”&lt;/p&gt;
&lt;p&gt;The key here is in the vagueness of the project definition: “a deck”. This allows the builder to manage the project to the budget. If decking is expensive the week the project commences she can build a more modest deck that still meets my needs. &lt;/p&gt;
&lt;p&gt;As the sponsor of an initiative what I really need is to know that I will get &lt;strong&gt;A SOLUTION&lt;/strong&gt; for &lt;strong&gt;A PRICE&lt;/strong&gt; (or price range). By leaving the precise solution undefined I:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;make it possible to reliably find a solution within the budget&lt;/li&gt;
&lt;li&gt;leave the experts delivering my solution the freedom to do their jobs to the best of their abilities&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Many industries operate this way. You pay your mechanic $X to fix your car. You pay your lawyer $Y to protect your intellectual property. You don’t specify &lt;strong&gt;how&lt;/strong&gt; they should do it, because they are the experts.&lt;/p&gt;
&lt;p&gt;While I might pay a trusted builder to construct “a deck” nobody will pay for “an application”. To make this approach specific to software development we need a better way to clarify that the customer will get a solution to their problem (&lt;strong&gt;a&lt;/strong&gt; solution, not &lt;strong&gt;the&lt;/strong&gt; solution). &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2019-01-27-estimate-without-estimating/fight_club_airport_security.jpg&quot; alt=&quot;a solution not the solution&quot;&gt;&lt;/p&gt;
&lt;p&gt;I like a technique called goal-based requirements analysis. In short, all actors in the system are identified along with their goals. An acceptable solution is one which allows all actors to achieve their goals. That is all an initiative sponsor really wants or needs, and at this level of detail we &lt;strong&gt;can&lt;/strong&gt; nominate an appropriate budget. &lt;/p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Clarify the problem to be solved.&lt;/li&gt;
&lt;li&gt;Work to establish a sufficient budget.&lt;/li&gt;
&lt;li&gt;Agree to provide the best solution you can, within the budget agreed.&lt;/li&gt;
&lt;li&gt;Follow the &lt;strong&gt;outcome&lt;/strong&gt; not the &lt;strong&gt;output&lt;/strong&gt;. &lt;/li&gt;
&lt;/ol&gt;
</description>
    </item>
    <item>
      <title>Project Lamb Meatballs - Value-based vs Project-based Portfolio Management</title>
      <link>http://withouttheloop.com/articles/2018-12-12-project-lamb-meatballs/</link>
      <pubDate>Wed, 12 Dec 2018 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2018-12-12-project-lamb-meatballs/</guid>
      <author></author>
      <description>&lt;p&gt;Intuitively, when a person looks for a technology solution, they begin with a &lt;strong&gt;project&lt;/strong&gt; mindset. They want to understand what they will get, when they will get it, and how much it will cost. This is a logical way to attempt to control cost and limit risk, unfortunately it is incompatible with pursuing value. To understand why, think of a buffet.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2018-12-12-project-lamb-meatballs/buffet.jpg&quot; alt=&quot;Buffet&quot;&gt;
Photo by Mohammad Saifullah on Unsplash&lt;/p&gt;
&lt;h2 id=&quot;the-value-mindset&quot;&gt;The Value Mindset&lt;/h2&gt;
&lt;p&gt;When one approaches a buffet with a clean, empty plate the desired value is the satisfaction of a good meal. The diner surveys the buffet options then begins to take small quantities of desired foods, until a pleasing meal is assembled. The diner has optimized for the creation of value, according to their criteria (satisfaction of a good meal). &lt;/p&gt;
&lt;h2 id=&quot;the-project-mindset&quot;&gt;The Project Mindset&lt;/h2&gt;
&lt;p&gt;Next in line is a hungry project manager. The project manager sees the world not in terms of value to be created but in terms of projects to be started, progressed, completed and retired. The project manager arrives plate in hand at the first item in the buffet, which happens to be loose corn kernels. The project manager begins heaping their plate with corn, then requests more plates when they realize that they have underestimated the required capacity. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2018-12-12-project-lamb-meatballs/corn.jpg&quot; alt=&quot;corn&quot;&gt;&lt;/p&gt;
&lt;p&gt;They then proceed to eat all the corn in the buffet and declare the corn kernel project a success. They did not achieve the satisfaction of a good meal, but there is no time to think about that before moving on to project lamb meatballs.&lt;/p&gt;
&lt;h2 id=&quot;if-not-nothing-then-all&quot;&gt;If Not Nothing, Then All&lt;/h2&gt;
&lt;p&gt;When we decide to use technology to assist in a particular area, we often fall into the trap of thinking that if we are doing something we must do everything, presented as defining and completing “the project”. This fails to consider the opportunity cost of any one project. By deciding to see one project (corn kernels) through to the bitter end we miss out on other options that we could be pursuing to create value. All initiatives have diminishing returns so proper portfolio management requires considering all options simultaneously and pursuing each only to the extent that it creates the maximum value (sample many buffet items to create the optimal meal).  &lt;/p&gt;
&lt;h2 id=&quot;value-based-portfolio-management&quot;&gt;Value-based Portfolio Management&lt;/h2&gt;
&lt;p&gt;The idea described above is sometimes called value-based portfolio management. To core idea is to always be working on the tasks that will create the most value at this moment. When an organisation attempts to follow the value in this way, they quickly come into conflict with the project mindset. The very notion of planning out a program of work and then executing against it conflicts with the idea of pursuing value. If we are to follow the plan, then we cannot follow the value. Since all initiatives have diminishing returns if we are working according to a program of work then at some point we will dip below a threshold where what we are working on is no longer the most valuable thing to the organisation. &lt;/p&gt;
&lt;h2 id=&quot;an-antidote&quot;&gt;An Antidote&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2018-12-12-project-lamb-meatballs/bottles.jpg&quot; alt=&quot;Antidote&quot;&gt;&lt;/p&gt;
&lt;p&gt;One simple solution is to continually evaluate the plan, detect the moment when we cease to be working on the most valuable thing, and correct the plan at that moment. The astute observer will recognize that this looks suspiciously like not following a plan at all. &lt;/p&gt;
&lt;p&gt;Another option emerges as we recognize that objectives are more stable than solutions. Instead of planning tasks to be executed, plan in terms of progress against goals. Next quarter we will assemble a satisfying meal from the buffet. The optimal steps to achieve that outcome will change but a plan expressed in terms of outcomes is stable. A talented team will be free to find the optimal solution, instead of being chained to an out-of-date plan. &lt;/p&gt;
&lt;h2 id=&quot;challenge-plus-constraints&quot;&gt;Challenge, plus constraints&lt;/h2&gt;
&lt;p&gt;One way to define technology initiatives is &lt;strong&gt;challenge, plus constraints&lt;/strong&gt;. For example:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;create an online sales channel for a coffee retailer. Spend less than $1M. Ship before Christmas.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As a sponsor or stakeholder of this initiative this lets me manage my risk, so long as I trust the team executing. It is an unfamiliar model in technology that makes some people uncomfortable, but it is widespread in other contexts. You don’t tell your surgeon how to perform your surgery, or your chef how to prepare your food. As a rule, I propose that mandating to experts how they should do their work is a bad idea. It might feel like it reduces risk, but it does not. &lt;/p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;
&lt;p&gt;When we think of projects, we think we need to do everything now or else it will never get done. This is not realistic in technology delivery. Everything is an iterative process that takes time and changes when it encounters real users. Instead, focus on value. Clarify what your goals are and find the thing that will have the most effect right now. If something is important it will eventually get done. If it doesn’t then you probably dodged a bullet. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>My Weird Obsession with Glitch</title>
      <link>http://withouttheloop.com/articles/2018-10-23-glitch/</link>
      <pubDate>Tue, 23 Oct 2018 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2018-10-23-glitch/</guid>
      <author></author>
      <description>&lt;p&gt;&lt;a href=&quot;http://withouttheloop.com/articles/2018-10-23-glitch/glitch.com&quot;&gt;Glitch&lt;/a&gt; is an online environment for creating and sharing web applications. It’s like codepen, but with a node.js server side environment. &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://glitch.com/edit/#!/tangy-silver?path=server.js:15:21&quot;&gt;My Spaced Repetition Flash Card Export ported to Glitch&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For easy creation, rapid prototyping and simple experiments it is a wonderful resource. &lt;/p&gt;
&lt;p&gt;As you may know, I have a &lt;a href=&quot;https://withouttheloop.com/articles/2018-10-02-my-weird-obsession-with-markdown-and-spaced/&quot;&gt;Weird Obsession with Markdown and Spaced Repetition&lt;/a&gt;, that led to me creating a system for embedding flash card data into my markdown notes, and using the github API to extract the data and build a CSV for importing into Anki (a program for studying spaced repetition flash cards). &lt;/p&gt;
&lt;p&gt;The workflow then is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;write my study note, including flash card data for the things that I would like to memorize&lt;/li&gt;
&lt;li&gt;go to codepen to run my extract &lt;/li&gt;
&lt;li&gt;copy the CSV from the browser console&lt;/li&gt;
&lt;li&gt;save the CSV to a file&lt;/li&gt;
&lt;li&gt;import the file into Anki&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I don’t have to do it often, but even so this is an intimidating workflow. By moving the extract from codepen to glitch I can learn a little about glitch and improve the workflow to: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;write my study note, including flash card data for the things that I would like to memorize&lt;/li&gt;
&lt;li&gt;go to glitch to run my extract and download a CSV file&lt;/li&gt;
&lt;li&gt;import the file into Anki&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;moving-to-glitch&quot;&gt;Moving to Glitch&lt;/h2&gt;
&lt;p&gt;After logging into Glitch I created a new project. This provides a working node.js application (I chose to use the Express MVC framework) complete with static file serving and client side code (which I don’t need).&lt;/p&gt;
&lt;p&gt;Porting my client-side code from codepen to server side code running on node.js broke a number of things. Firstly, I used the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API&quot;&gt;fetch API&lt;/a&gt; to make HTTP requests, and this API is not available in a node.js environment. This can be fixed using the &lt;code&gt;node-fetch&lt;/code&gt; npm module.&lt;/p&gt;
&lt;p&gt;To add an npm module to a glitch project, simply add the dependency to the &lt;code&gt;package.json&lt;/code&gt; file. I needed a number of dependencies:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-json&quot;&gt;&amp;quot;dependencies&amp;quot;: {
    &amp;quot;express&amp;quot;: &amp;quot;^4.16.3&amp;quot;,
    &amp;quot;papaparse&amp;quot;: &amp;quot;*&amp;quot;,
    &amp;quot;node-fetch&amp;quot;: &amp;quot;*&amp;quot;,
    &amp;quot;atob&amp;quot;: &amp;quot;*&amp;quot;
  },
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The second uncertainty I encountered was how to factor my application into multiple modules and files. I started by implementing the application in a single file &lt;code&gt;server.js&lt;/code&gt; and making sure that it worked. Then I moved some code for parsing the micro format into a file (&lt;code&gt;cards.js&lt;/code&gt;) and the code for working with the github API into a file (&lt;code&gt;github.js&lt;/code&gt;). Importing those modules into another module is done the same way as any other node.js application:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; github = &lt;span class=&quot;built_in&quot;&gt;require&lt;/span&gt;(&lt;span class=&quot;string&quot;&gt;'./github'&lt;/span&gt;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now I can access my application at &lt;a href=&quot;https://tangy-silver.glitch.me/cards&quot;&gt;https://tangy-silver.glitch.me/cards&lt;/a&gt; and download the latest CSV of flash card data.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2018-10-23-glitch/csv.png&quot; alt=&quot;Flash card CSV&quot;&gt;&lt;/p&gt;
&lt;p&gt;To spin up a quick, hosted node.js application with the minimal friction, try &lt;a href=&quot;http://withouttheloop.com/articles/2018-10-23-glitch/glitch.com&quot;&gt;Glitch&lt;/a&gt;. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>My Weird Obsession with Markdown and Spaced Repetition</title>
      <link>http://withouttheloop.com/articles/2018-10-02-my-weird-obsession-with-markdown-and-spaced/</link>
      <pubDate>Tue, 02 Oct 2018 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2018-10-02-my-weird-obsession-with-markdown-and-spaced/</guid>
      <author></author>
      <description>&lt;p&gt;Each time I go back to studying I decide that a better use of my time, instead of studying, is to solve the problem of markdown study notes with embedded spaced repetition flash cards. How’s that for procrastination?&lt;/p&gt;
&lt;p&gt;I studied mathematics in 2015 and compiled a &lt;a href=&quot;https://github.com/liammclennan/maths&quot;&gt;comprehensive set of markdown notes&lt;/a&gt;. Here’s an excerpt:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-markdown&quot;&gt;&lt;span class=&quot;section&quot;&gt;Polynomial Derivatives
---&lt;/span&gt;

$$\frac{dx^n}{dx} = nx^{n-1}$$

&lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;script&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;type&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;flashcard&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;undefined&quot;&gt;&lt;/span&gt;&lt;/span&gt;
Q&amp;gt;&amp;gt;&amp;gt; What is the derivative of $$ 7x^4 $$? &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;javascript&quot;&gt;&amp;lt;&amp;lt;&lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;
&lt;span class=&quot;attr&quot;&gt;A&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&amp;gt;&amp;gt; $$ 28x^3 $$ &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;undefined&quot;&gt;&amp;lt;&amp;lt;&amp;lt;
&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;script&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;section&quot;&gt;### Constants&lt;/span&gt;

The derivative of a constant is &lt;span class=&quot;code&quot;&gt;`0`&lt;/span&gt;.

$$\frac{dc}{dx} = 0$$

This can be found from the derivative of polynomials, since $5 = 5x^0 -&amp;gt; 0 * 5x^-1 = 0$.

&lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;script&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;type&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;flashcard&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;undefined&quot;&gt;&lt;/span&gt;&lt;/span&gt;
Q&amp;gt;&amp;gt;&amp;gt; What is the derivative of $$ 99 $$? &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;javascript&quot;&gt;&amp;lt;&amp;lt;&lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;
&lt;span class=&quot;attr&quot;&gt;A&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&amp;gt;&amp;gt; $$ 0 $$ because $$ 99 = 99x^0 = 0 * 99x^-1 = 0 $$ &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;undefined&quot;&gt;&amp;lt;&amp;lt;&amp;lt;
&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;script&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note the embedded microformat metadata describing flash cards:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-html&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;script&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;type&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;flashcard&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;javascript&quot;&gt;
Q&amp;gt;&amp;gt;&amp;gt; What is the derivative &lt;span class=&quot;keyword&quot;&gt;of&lt;/span&gt; $$ &lt;span class=&quot;number&quot;&gt;7&lt;/span&gt;x^&lt;span class=&quot;number&quot;&gt;4&lt;/span&gt; $$? &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&amp;lt;&amp;lt;
&lt;span class=&quot;attr&quot;&gt;A&lt;/span&gt;&amp;gt;&lt;/span&gt;&amp;gt;&amp;gt; $$ 28x^3 $$ &lt;span class=&quot;tag&quot;&gt;&amp;lt;&amp;lt;&amp;lt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;script&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This information is not displayed in the notes, but is there to generate flash cards for &lt;a href=&quot;https://en.wikipedia.org/wiki/Spaced_repetition&quot;&gt;spaced repetition&lt;/a&gt;. At the time I built a web application to pull out the flash cards for studying. Sometime in the last three years the domain expired, and the source code is trapped in my bitbucket account that I can’t login to anymore.  &lt;code&gt;¯\_(ツ)_/¯&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This year I’m starting an MBA, and immediately felt the need to record notes in markdown. Naturally, that was followed by a desire to embedd flash cards. Since I’ve lost my last solution, I created a new one. I’m using github to edit and store the markdown files, so I delimit the flash card with comments (this is the only content I could find that github doesn’t display):&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-xml&quot;&gt;&lt;span class=&quot;comment&quot;&gt;&amp;lt;!---

---&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For the questions and answers I use an xml-like syntax for easy parsing:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-xml&quot;&gt;&lt;span class=&quot;comment&quot;&gt;&amp;lt;!---
&amp;lt;question&amp;gt;What is a blah?&amp;lt;/question&amp;gt;
&amp;lt;answer&amp;gt;It's a foo!&amp;lt;/answer&amp;gt;

&amp;lt;question&amp;gt;What is a foo?&amp;lt;/question&amp;gt;
&amp;lt;answer&amp;gt;It's a blah!&amp;lt;/answer&amp;gt;
---&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;fetching-content-from-github&quot;&gt;Fetching Content From Github&lt;/h2&gt;
&lt;p&gt;Fortunately, Github provides a &lt;a href=&quot;https://developer.github.com/v3/repos/contents/&quot;&gt;simple API for fetching content from a repository&lt;/a&gt;. My solution is currently a &lt;a href=&quot;https://codepen.io/liammclennan/pen/oaXpya?editors=0010&quot;&gt;codepen script&lt;/a&gt;, so JavaScript. This function recursively navigates a github repository and builds a collection of urls to fetch those files. &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; collectFilesInDirectory = &lt;span class=&quot;function&quot;&gt;(&lt;span class=&quot;params&quot;&gt;directoryUrl&lt;/span&gt;) =&amp;gt;&lt;/span&gt; {
  &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; fetch(directoryUrl)
    .then(&lt;span class=&quot;function&quot;&gt;(&lt;span class=&quot;params&quot;&gt;response&lt;/span&gt;) =&amp;gt;&lt;/span&gt; response.json())
    .then(&lt;span class=&quot;function&quot;&gt;(&lt;span class=&quot;params&quot;&gt;entries&lt;/span&gt;) =&amp;gt;&lt;/span&gt; ({
      &lt;span class=&quot;attr&quot;&gt;files&lt;/span&gt;: entries.filter(&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;params&quot;&gt;e&lt;/span&gt; =&amp;gt;&lt;/span&gt; e.type === &lt;span class=&quot;string&quot;&gt;&quot;file&quot;&lt;/span&gt;),
      &lt;span class=&quot;attr&quot;&gt;directories&lt;/span&gt;: entries.filter(&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;params&quot;&gt;e&lt;/span&gt; =&amp;gt;&lt;/span&gt; e.type === &lt;span class=&quot;string&quot;&gt;&quot;dir&quot;&lt;/span&gt;)
    }))
    .then(&lt;span class=&quot;function&quot;&gt;(&lt;span class=&quot;params&quot;&gt;{files, directories}&lt;/span&gt;) =&amp;gt;&lt;/span&gt; &lt;span class=&quot;built_in&quot;&gt;Promise&lt;/span&gt;.all(directories.map(&lt;span class=&quot;function&quot;&gt;(&lt;span class=&quot;params&quot;&gt;d&lt;/span&gt;) =&amp;gt;&lt;/span&gt; collectFilesInDirectory(d.url)))
          .then(&lt;span class=&quot;function&quot;&gt;(&lt;span class=&quot;params&quot;&gt;fs&lt;/span&gt;) =&amp;gt;&lt;/span&gt; flatten(fs))
          .then(&lt;span class=&quot;function&quot;&gt;(&lt;span class=&quot;params&quot;&gt;flattened&lt;/span&gt;) =&amp;gt;&lt;/span&gt; flattened.concat(files.map(&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;params&quot;&gt;f&lt;/span&gt; =&amp;gt;&lt;/span&gt; f.url)))
    )
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At a high level, it adds the files in the current directory to a collection, as well as doing the same thing for all sub-directories (and their sub-directories).&lt;/p&gt;
&lt;p&gt;E.g.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;collectFilesInDirectory(&lt;span class=&quot;string&quot;&gt;&quot;https://api.github.com/repos/liammclennan/mba/contents&quot;&lt;/span&gt;)
  .then(&lt;span class=&quot;built_in&quot;&gt;console&lt;/span&gt;.log);

&lt;span class=&quot;comment&quot;&gt;// […]&lt;/span&gt;
&lt;span class=&quot;comment&quot;&gt;// 0: &quot;https://api.github.com/repos/liammclennan/MBA/contents/Business-Analytics/index.md?ref=master&quot;&lt;/span&gt;
​&lt;span class=&quot;comment&quot;&gt;// 1: &quot;https://api.github.com/repos/liammclennan/MBA/contents/README.md?ref=master&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;parsing-flash-card-data-out-of-markdown&quot;&gt;Parsing Flash Card Data Out of Markdown&lt;/h2&gt;
&lt;p&gt;Next task was to extract the metadata blocks out of markdown files. This involved re-learning JavaScript regular expressions. The thing that slowed me down the most was that the &lt;code&gt;RegEx.exec&lt;/code&gt; can only do one match at a time, so if you want to select all of the &lt;code&gt;&amp;lt;!--- ---&amp;gt;&lt;/code&gt; blocks in a markdown file you must call &lt;code&gt;exec&lt;/code&gt; repeatedly until it stops finding matches, which I did with this regular express &lt;code&gt;/(?:&amp;lt;!---\n?)([\s\S]*?)(?:\n?---&amp;gt;)/gm&lt;/code&gt;. &lt;/p&gt;
&lt;p&gt;Once we have the microformat blocks we must extract the pairs of questions and anwsers. This calls for another regular expression, &lt;code&gt;/(?:&amp;lt;question&amp;gt;\n?)([\s\S]*?)&amp;lt;\/question&amp;gt;(?:[\s\S]*?)&amp;lt;answer&amp;gt;([\s\S]*?)(?:\n?&amp;lt;\/answer&amp;gt;)/gm&lt;/code&gt;. &lt;/p&gt;
&lt;p&gt;This gives me a nice collection of question / answer pairs, each of which will become a study flash card.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;[…]
​
&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;: &lt;span class=&quot;built_in&quot;&gt;Object&lt;/span&gt; { &lt;span class=&quot;attr&quot;&gt;question&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;What are the components of business analytics?&quot;&lt;/span&gt;, &lt;span class=&quot;attr&quot;&gt;answer&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;BI / IS, statistics, modelling and optimization&quot;&lt;/span&gt; }
​
&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;: &lt;span class=&quot;built_in&quot;&gt;Object&lt;/span&gt; { &lt;span class=&quot;attr&quot;&gt;question&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;What is descriptive analytics?&quot;&lt;/span&gt;, &lt;span class=&quot;attr&quot;&gt;answer&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;formatting data for understanding. Creating information from historical data.&quot;&lt;/span&gt; }
​
&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;: &lt;span class=&quot;built_in&quot;&gt;Object&lt;/span&gt; { &lt;span class=&quot;attr&quot;&gt;question&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;What is predictive analytics?&quot;&lt;/span&gt;, &lt;span class=&quot;attr&quot;&gt;answer&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;using data to predict the future&quot;&lt;/span&gt; }
​
&lt;span class=&quot;number&quot;&gt;3&lt;/span&gt;: &lt;span class=&quot;built_in&quot;&gt;Object&lt;/span&gt; { &lt;span class=&quot;attr&quot;&gt;question&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;What is prescriptive analytics?&quot;&lt;/span&gt;, &lt;span class=&quot;attr&quot;&gt;answer&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;Using data to maximize or minimize some value. Using data to facilitate decision making.&quot;&lt;/span&gt; }
​
&lt;span class=&quot;number&quot;&gt;4&lt;/span&gt;: &lt;span class=&quot;built_in&quot;&gt;Object&lt;/span&gt; { &lt;span class=&quot;attr&quot;&gt;question&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;What is price elasticity?&quot;&lt;/span&gt;, &lt;span class=&quot;attr&quot;&gt;answer&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;The extent to which price affects demand.&quot;&lt;/span&gt; }
​
&lt;span class=&quot;number&quot;&gt;5&lt;/span&gt;: &lt;span class=&quot;built_in&quot;&gt;Object&lt;/span&gt; { &lt;span class=&quot;attr&quot;&gt;question&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;What is a model?&quot;&lt;/span&gt;, &lt;span class=&quot;attr&quot;&gt;answer&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;Abstraction that captures the most important features of a system and presents them in a form that is easy to interpret. &quot;&lt;/span&gt; }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then I used &lt;a href=&quot;https://www.papaparse.com/&quot;&gt;Papa Parse&lt;/a&gt; to format this data as csv:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-csv&quot;&gt;&amp;quot;What are the components of business analytics?&amp;quot;,&amp;quot;BI / IS, statistics, modelling and optimization&amp;quot;

&amp;quot;What is descriptive analytics?&amp;quot;,&amp;quot;formatting data for understanding. Creating information from historical data.&amp;quot;

&amp;quot;What is predictive analytics?&amp;quot;,&amp;quot;using data to predict the future&amp;quot;

&amp;quot;What is prescriptive analytics?&amp;quot;,&amp;quot;Using data to maximize or minimize some value. Using data to facilitate decision making.&amp;quot;

&amp;quot;What is price elasticity?&amp;quot;,&amp;quot;The extent to which price affects demand.&amp;quot;

&amp;quot;What is a model?&amp;quot;,&amp;quot;Abstraction that captures the most important features of a system and presents them in a form that is easy to interpret. &amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;using-my-flash-card-data-for-spaced-repetition-study&quot;&gt;Using My Flash Card Data for Spaced Repetition Study&lt;/h2&gt;
&lt;p&gt;The leader in the apparently uncompetitive flash card sector is &lt;a href=&quot;https://apps.ankiweb.net/&quot;&gt;Anki&lt;/a&gt;. Anki can import my CSV file. Now I have my flash cards available in Anki for studying. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2018-10-02-my-weird-obsession-with-markdown-and-spaced/imported.png&quot; alt=&quot;Anki deck&quot;&gt;&lt;/p&gt;
&lt;p&gt;Studying looks like this:&lt;/p&gt;
&lt;video width=&quot;480&quot; height=&quot;320&quot; controls=&quot;controls&quot;&gt;
&lt;source src=&quot;studying.mp4&quot; type=&quot;video/mp4&quot;&gt;
&lt;/video&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;
&lt;p&gt;Here is the full source:&lt;/p&gt;
&lt;p&gt;&lt;p data-height=&quot;265&quot; data-theme-id=&quot;0&quot; data-slug-hash=&quot;oaXpya&quot; data-default-tab=&quot;js&quot; data-user=&quot;liammclennan&quot; data-pen-title=&quot;Parsing QA out of MD&quot; class=&quot;codepen&quot;&gt;See the Pen &lt;a href=&quot;https://codepen.io/liammclennan/pen/oaXpya/&quot;&gt;Parsing QA out of MD&lt;/a&gt; by Liam McLennan (&lt;a href=&quot;https://codepen.io/liammclennan&quot;&gt;@liammclennan&lt;/a&gt;) on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/p&gt;&lt;/p&gt;
&lt;script async src=&quot;https://static.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;

</description>
    </item>
    <item>
      <title>Startup Software Product Development</title>
      <link>http://withouttheloop.com/articles/2018-02-10-software-product-development/</link>
      <pubDate>Sat, 10 Feb 2018 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2018-02-10-software-product-development/</guid>
      <author></author>
      <description>&lt;p&gt;Software product development in new businesses is usually limited by a lack of funds and an excess of potential features. There is too much to do, and not enough time or money to do it. A startup needs to make product investment decisions carefully. Some mistakes are likely, but too many false starts can cause the enterprise to fail. &lt;/p&gt;
&lt;p&gt;Many, if not most, technology startups seem to fall into the trap of HiPPO (Highest Paid Person’s Opinion) decision making. That is, they choose to invest based on the “gut feel” or “instinct” of the CEO. The problem with intuition is that it is frequently wrong. We can, and should, do better. &lt;/p&gt;
&lt;h2 id=&quot;a-process-for-software-product-development-&quot;&gt;A Process For Software Product Development &lt;/h2&gt;
&lt;p&gt;As the CTO of a startup I have thought a lot about how to maximise our success in the face of much uncertainty. Being able to do a few things well requires that we say no to many opportunities. To guide this decision making we have established a product development process described below. &lt;/p&gt;
&lt;p&gt;The first and most important step is to discover, clarify and consolidate the enterprise’s goals into a small number of clear goals that everyone can be aware of, remember and understand. Getting to these goals is more difficult than one might think. I have previously written about &lt;a href=&quot;https://withouttheloop.com/articles/2016-08-24-goaltree/&quot;&gt;The Goal Tree&lt;/a&gt; technique for uncovering goals. At times leaders seem unsure about the wisdom of publishing their goals, and sometimes even embarrassed about them. For example, CEOs sometimes feel like they need to be seen to have a lofty change-the-world type goal and may be reluctant to admit the profit motive as a top-level goal. Nothing else described in the post has any value if the goals are wrong, so take the time to ensure that the goals are correctly identified, documented and agreed. &lt;/p&gt;
&lt;p&gt;Once the goals have been agreed we need a process for evaluating, prioritising and scheduling initiatives. &lt;/p&gt;
&lt;h3 id=&quot;1-socialize-and-propose&quot;&gt;1. Socialize and Propose&lt;/h3&gt;
&lt;p&gt;Good ideas can come from anywhere. Those close to the customers, for example, can often identify opportunities that the engineering team are not aware of. Our process starts with socializing the initiative with stakeholders, then preparing a proposal. The amount of effort invested in the proposal is proportionate to the size and risk of the opportunity. The proposal:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;establishes a clear link between the initiative and the business goals that it will affect. &lt;/li&gt;
&lt;li&gt;identifies quantitative goals for the initiative itself. Exactly how will we know if this initiative has been successful? If the outcome of an initiative cannot be measured, then leaders should be deeply sceptical. The goals section is the most important part of the proposal and the primary input to the delivery process.  &lt;/li&gt;
&lt;li&gt;documents research and findings&lt;/li&gt;
&lt;li&gt;documents assumptions&lt;/li&gt;
&lt;li&gt;documents risk and mitigations&lt;/li&gt;
&lt;li&gt;describes the problem being addressed&lt;/li&gt;
&lt;li&gt;describes the solution&lt;/li&gt;
&lt;li&gt;establishes the items in scope and the items out of scope&lt;/li&gt;
&lt;li&gt;estimates the value of the initiative to the enterprise. Work will not proceed if the effort estimated to be required is not significantly less than the estimated value to the enterprise. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note that the proposal intentionally stays away from documenting solutions. The important information to capture is what we want to achieve (goals) and what is it worth to us. &lt;/p&gt;
&lt;h3 id=&quot;2-evaluate&quot;&gt;2. Evaluate&lt;/h3&gt;
&lt;p&gt;Negotiate an implementation budget. If the initiative is worth $X how much do we want to invest in an initial implementation? As described in &lt;a href=&quot;https://m.signalvnoise.com/how-we-set-up-our-work-cbce3d3d9cae&quot;&gt;Basecamp’s process&lt;/a&gt; we try to find a solution that can be completed in 4-8 weeks, with some flexibility to change the team size so we stay in this window. &lt;/p&gt;
&lt;h3 id=&quot;4-scheduling&quot;&gt;4. Scheduling&lt;/h3&gt;
&lt;p&gt;Evaluated proposals are prioritized. This prioritization must be done collaboratively and must be communicated widely. We use a large wall in our office. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://withouttheloop.com/articles/2017-11-16-product-planning/Redacted.jpg&quot; alt=&quot;Prioritization wall&quot;&gt; &lt;/p&gt;
&lt;p&gt;Each documented initiative is represented by a card. The cards are sorted according to priority. When someone inevitably asks for all things to be done immediately we go stand in front of the wall the put the cards in the right order. This is a hard process, but essential! Sensible project management means confronting reality and choosing the best path with what we have.  &lt;/p&gt;
&lt;p&gt;The highest priority proposals get a team allocated and a schedule (start and end date). One member of the team is given responsibility for the overall successful delivery of the initiative. &lt;/p&gt;
&lt;h3 id=&quot;5-kickoff&quot;&gt;5. Kickoff&lt;/h3&gt;
&lt;p&gt;This whole process is intended to maximize effective communication and one important activity is the kickoff meeting. The kickoff meeting:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ensures all stakeholders have a consistent understanding of what will be done and why&lt;/li&gt;
&lt;li&gt;clarifies roles and decision making responsibilities&lt;/li&gt;
&lt;li&gt;clarifies the schedule&lt;/li&gt;
&lt;li&gt;recaps the proposal (goals, risks etc)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;6-design-and-implementation&quot;&gt;6. Design and implementation&lt;/h3&gt;
&lt;p&gt;Initiative teams are cross-functional including designers and developers (and any other skillsets required for the initiative). Together they must plan a solution that will achieve the agreed goals comfortably within the agreed effort budget. Neither design nor development may be overly ambitions in their planning without risking the success of the initiative, so there is a negotiation. This way we guarantee that the cost of the initiative is matched to its anticipated benefit. &lt;/p&gt;
&lt;h3 id=&quot;7-assess&quot;&gt;7. Assess&lt;/h3&gt;
&lt;p&gt;Finally, the initiative is delivered, and its outcome measured. We return to the original proposal and record the measured outcomes against what was planned. Either way, we then have a choice to continue investing in the initiative or to move investment elsewhere based on the latest information. Thus, the process starts again from the beginning. &lt;/p&gt;
&lt;h2 id=&quot;further-reading&quot;&gt;Further Reading&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://withouttheloop.com/articles/2016-08-24-goaltree/&quot;&gt;The Goal Tree&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://withouttheloop.com/articles/2017-11-16-product-planning/&quot;&gt;Goals, Strategic Planning and Product Road Maps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://m.signalvnoise.com/how-we-set-up-our-work-cbce3d3d9cae&quot;&gt;How we structure our work and teams at Basecamp&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    <item>
      <title>Learning React 10 - Typescript</title>
      <link>http://withouttheloop.com/articles/2018-01-17-react-10-typescript/</link>
      <pubDate>Wed, 17 Jan 2018 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2018-01-17-react-10-typescript/</guid>
      <author></author>
      <description>&lt;p&gt;&lt;a href=&quot;http://withouttheloop.com/articles/2018-01-11-react-9-data-bound-routes/&quot;&gt;Learning React 9 - Data Bound Routes&lt;/a&gt; showed the &lt;em&gt;redux-first-router&lt;/em&gt; way to implement data bound routes, that is, routes that require fetching some data to be able to render their view. This post will add static typing to our movie library application.&lt;/p&gt;
&lt;h1 id=&quot;types&quot;&gt;Types&lt;/h1&gt;
&lt;p&gt;A type is a restriction on data. It defines the set of valid values for that type. E.g. all real numbers are valid for the type &lt;code&gt;number&lt;/code&gt;, but only the whole numbers are valid for the type &lt;code&gt;integer&lt;/code&gt;. All unicode characters are valid possibilities for the &lt;code&gt;character&lt;/code&gt; type, but only ‘true’ and ‘false’ are valid values for the &lt;code&gt;boolean&lt;/code&gt; type. &lt;/p&gt;
&lt;h1 id=&quot;static-typing&quot;&gt;Static Typing&lt;/h1&gt;
&lt;p&gt;Static typing means that the types of a program are verified for correctness at compile time. The types flow through the program and everywhere they are used the compiler checks that the usage is valid for the type. A static type checker would prevent the following non-sensical operation:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt; + &lt;span class=&quot;string&quot;&gt;'a'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;on the grounds that there is no good, semantically valid interpretation. It would also prevent &lt;code&gt;1 + &amp;#39;a&amp;#39;.toNum()&lt;/code&gt;, because the string type does not have a &lt;code&gt;toNum()&lt;/code&gt; method. Thus a static type system detects a class of errors that would otherwise potentially occur at runtime.&lt;/p&gt;
&lt;p&gt;Gary Bernhardt provided &lt;a href=&quot;https://www.destroyallsoftware.com/compendium/types?share_key=baf6b67369843fa2&quot;&gt;an interesting overview&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To help us write correct React applications it is useful to add a static type checker. Two options are available: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://flow.org/&quot;&gt;flow&lt;/a&gt;, developed by Facebook&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.typescriptlang.org/&quot;&gt;typescript&lt;/a&gt;, developed by Microsoft&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Both are great. This post will convert the movie library application to Typescript. &lt;/p&gt;
&lt;h1 id=&quot;converting-to-typescript&quot;&gt;Converting to Typescript&lt;/h1&gt;
&lt;p&gt;My preferred way to convert a &lt;em&gt;create-react-app&lt;/em&gt; project to Typescript is by creating a new application and porting the code over. &lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;a href=&quot;https://github.com/wmonk/create-react-app-typescript&quot;&gt;create-react-app-typescript&lt;/a&gt;&lt;/em&gt; is a project that maintains a Typescript fork of &lt;em&gt;create-react-app&lt;/em&gt;. To use it:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-bash&quot;&gt;&amp;gt; create-react-app movie-library-ts --scripts-version=react-scripts-ts
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will create a new empty application in &lt;code&gt;movie-library-ts&lt;/code&gt;. &lt;/p&gt;
&lt;p&gt;Next, add type definitions for the external libraries we are using:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-bash&quot;&gt;&amp;gt; npm install @types/&lt;span class=&quot;built_in&quot;&gt;history&lt;/span&gt; @types/react @types/react-dom @types/redux @types/react-redux @types/redux-first-router @types/redux-first-router-link @types/redux-promise-middleware --save-dev
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This allows Typescript to determine the types of the APIs exposed by those libraries. We use &lt;code&gt;--save-dev&lt;/code&gt; because these dependencies are only required for compilation. They are not used at runtime. &lt;/p&gt;
&lt;p&gt;Add a file &lt;code&gt;Movie.tsx&lt;/code&gt; to the &lt;code&gt;src/&lt;/code&gt; directory. Typescript files have the &lt;code&gt;.ts&lt;/code&gt; extension. Typescript files containing JSX have the &lt;code&gt;.tsx&lt;/code&gt; extension. &lt;/p&gt;
&lt;p&gt;Typescript requires the &lt;code&gt;props&lt;/code&gt; parameter to have a type, so declare a type &lt;code&gt;MovieData&lt;/code&gt; having an optional property &lt;code&gt;movie&lt;/code&gt; of type &lt;code&gt;MovieSummary&lt;/code&gt; that contains the basic movie information. &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;interface MovieSummary {
    Title: string;
    Poster: string;
    imdbID: string;
}

interface MovieData {
    movie?: MovieSummary;
}

function Movie(props: MovieData)
    return (
        &amp;lt;div&amp;gt;
        { props.movie 
            ? &amp;lt;p&amp;gt;
                    &amp;lt;h1&amp;gt;{props.movie.Title}&amp;lt;/h1&amp;gt;
                    &amp;lt;img src={props.movie.Poster} alt={`${props.movie.Title} poster`} /&amp;gt;
                &amp;lt;/p&amp;gt;
            : &amp;lt;p&amp;gt;Loading...&amp;lt;/p&amp;gt;
        }
        &amp;lt;/div&amp;gt;
    );
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This guarantees that consumers of the movie component cannot pass the wrong props, or props of the wrong type. Next, add type information to the &lt;code&gt;connect&lt;/code&gt; mappers:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; ConnectedMovie = connect(
    &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;mapStateToProps&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;state: { movie: MovieData }&lt;/span&gt;) &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; state.movie;
    }, 
    &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;mapDispatchToProps&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;dispatch: (action: any&lt;/span&gt;) =&amp;gt; &lt;span class=&quot;title&quot;&gt;void&lt;/span&gt;) &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; {};
    }
)(Movie);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note the type of the &lt;code&gt;dispatch&lt;/code&gt; function &lt;code&gt;(action: any) =&amp;gt; void&lt;/code&gt;. This declares that &lt;code&gt;dispatch&lt;/code&gt; is a function with one parameter and no return value. &lt;/p&gt;
&lt;p&gt;Converting the other files follows the same pattern, with the exception of the &lt;code&gt;SearchForm&lt;/code&gt; component, our single React class component. As a class component it needs to supply type variables to its base class, one for the type of its props, and one for the type of its state. &lt;/p&gt;
&lt;p&gt;The other interesting thing to note is that the type of &lt;code&gt;Search&lt;/code&gt; props is specified as &lt;code&gt;SearchFormProps &amp;amp; SearchResults&lt;/code&gt; which is the combination of those two types. In typescript this is called an &lt;a href=&quot;https://www.typescriptlang.org/docs/handbook/advanced-types.html&quot;&gt;Intersection Type&lt;/a&gt;. &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;interface SearchFormProps {
    &lt;span class=&quot;attr&quot;&gt;onSearch&lt;/span&gt;: &lt;span class=&quot;function&quot;&gt;(&lt;span class=&quot;params&quot;&gt;title: string&lt;/span&gt;) =&amp;gt;&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt;;
}

interface SearchResults {
    &lt;span class=&quot;attr&quot;&gt;results&lt;/span&gt;: MovieSummary[];
}

&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;SearchForm&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;React&lt;/span&gt;.&lt;span class=&quot;title&quot;&gt;Component&lt;/span&gt;&amp;lt;&lt;span class=&quot;title&quot;&gt;SearchFormProps&lt;/span&gt;, &lt;/span&gt;{title: string}&amp;gt; {
    &lt;span class=&quot;keyword&quot;&gt;constructor&lt;/span&gt;(props: SearchFormProps) {
        &lt;span class=&quot;keyword&quot;&gt;super&lt;/span&gt;(props);
        &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.state = {&lt;span class=&quot;attr&quot;&gt;title&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;''&lt;/span&gt;};
        &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.titleChange = &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.titleChange.bind(&lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;);
        &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.search = &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.search.bind(&lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;);
    }

    titleChange(event: any) {
        &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.setState({&lt;span class=&quot;attr&quot;&gt;title&lt;/span&gt;: event.target.value});
    }

    search(event: any) {
        event.preventDefault();
        &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.props.onSearch(&lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.state.title);
    }

    render() {
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; (
        &amp;lt;div&amp;gt;&amp;lt;form onSubmit={this.search}&amp;gt;
            &amp;lt;label htmlFor=&quot;title&quot;&amp;gt;Title: &amp;lt;/label&amp;gt;
            &amp;lt;input type=&quot;text&quot; name=&quot;title&quot; value={this.state.title} onChange={this.titleChange}/&amp;gt;
            &amp;lt;input type=&quot;submit&quot; value=&quot;Search&quot;/&amp;gt;
        &amp;lt;/form&amp;gt;
        &amp;lt;/div&amp;gt;
        );
    }
}

function Search({ onSearch, results = [] }: SearchFormProps &amp;amp; SearchResults) {
    return (
    &amp;lt;div&amp;gt;
        &amp;lt;h1&amp;gt;Search&amp;lt;/h1&amp;gt;
        &amp;lt;SearchForm onSearch={onSearch} /&amp;gt;
        &amp;lt;div&amp;gt;
            {results.map(({Title, Poster, imdbID}) =&amp;gt;
            &amp;lt;Link to={{type: 'MOVIE', payload: {imdbID}}} key={imdbID}&amp;gt;
                &amp;lt;img src={Poster} alt={Title} /&amp;gt;
            &amp;lt;/Link&amp;gt;)}
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
    );
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id=&quot;summary&quot;&gt;Summary&lt;/h1&gt;
&lt;p&gt;There is a typescript version of &lt;em&gt;create-react-app&lt;/em&gt; that makes it easier to setup a new typed React application. Using a type checker to verify the type of props passed to React elements provides a guarantee within the component that the supplied data is correctly typed. &lt;/p&gt;
&lt;h2 id=&quot;get-the-code&quot;&gt;Get The Code&lt;/h2&gt;
&lt;p&gt;The code for this example is &lt;a href=&quot;https://github.com/liammclennan/movie-library-ts&quot;&gt;on Github&lt;/a&gt;. You can access the code as it was at the completion of this step by cloning the repository and checking out the tag that corresponds to this post. &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-bash&quot;&gt;git &lt;span class=&quot;built_in&quot;&gt;clone&lt;/span&gt; https://github.com/liammclennan/movie-library-ts.git
git checkout react10
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or browse at &lt;a href=&quot;https://github.com/liammclennan/movie-library-ts/tree/react10&quot;&gt;https://github.com/liammclennan/movie-library-ts/tree/react10&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Learning React 9 - Data Bound Routes</title>
      <link>http://withouttheloop.com/articles/2018-01-11-react-9-data-bound-routes/</link>
      <pubDate>Thu, 11 Jan 2018 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2018-01-11-react-9-data-bound-routes/</guid>
      <author></author>
      <description>&lt;p&gt;&lt;a href=&quot;http://withouttheloop.com/articles/2018-01-10-react-8-ajax-continued/&quot;&gt;Learning React 8 - AJAX Continued&lt;/a&gt; has our application capable for searching a movie API and displaying the list of results. Now we would like to be able to view the details for a selected movie. &lt;/p&gt;
&lt;p&gt;A good web application should have a URL for every addressable state, so selecting a movie should change the URL. We will use, &lt;code&gt;/movie/:imdbID&lt;/code&gt;. First add an action to the &lt;code&gt;routesMap&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; routesMap = { 
    &lt;span class=&quot;attr&quot;&gt;HOME&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'/'&lt;/span&gt;,
    &lt;span class=&quot;attr&quot;&gt;MOVIE&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'/movie/:imdbID'&lt;/span&gt;
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then create a new movie component:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Movie&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;props&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
            { props.movie 
                ? &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;p&lt;/span&gt;&amp;gt;&lt;/span&gt;
                        &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;h1&lt;/span&gt;&amp;gt;&lt;/span&gt;{props.movie.Title}&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;h1&lt;/span&gt;&amp;gt;&lt;/span&gt;
                        &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;img&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;src&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;{props.movie.Poster}&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;alt&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;{&lt;/span&gt;`${&lt;span class=&quot;attr&quot;&gt;props.movie.Title&lt;/span&gt;} &lt;span class=&quot;attr&quot;&gt;poster&lt;/span&gt;`} /&amp;gt;&lt;/span&gt;
                    &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;p&lt;/span&gt;&amp;gt;&lt;/span&gt;
                : &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;p&lt;/span&gt;&amp;gt;&lt;/span&gt;Loading...&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;p&lt;/span&gt;&amp;gt;&lt;/span&gt;
            }
            &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;;
}

const ConnectedMovie = connect(
    function mapStateToProps(state) {
        return state.movie;
    }, 
    function mapDispatchToProps(dispatch) {
        return {};
    }
)(Movie);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and update the &lt;code&gt;App&lt;/code&gt; component to display the &lt;code&gt;ConnectedMovie&lt;/code&gt; component when the &lt;code&gt;MOVIE&lt;/code&gt; action is dispatched. &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; componentMap = {
    &lt;span class=&quot;attr&quot;&gt;HOME&lt;/span&gt;: ConnectedSearch,
    &lt;span class=&quot;attr&quot;&gt;MOVIE&lt;/span&gt;: ConnectedMovie
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id=&quot;-redux-first-router-route-thunks&quot;&gt;&lt;em&gt;redux-first-router&lt;/em&gt; Route Thunks&lt;/h1&gt;
&lt;p&gt;Now we encounter a problem. When the router sees the route &lt;code&gt;/movie/:imdbID&lt;/code&gt; it will cause the application to show the &lt;code&gt;ConnectedMovie&lt;/code&gt; component, which expects to display a movie using data from the redux store, but the data is not there. Somehow we need to take the &lt;code&gt;imdbID&lt;/code&gt; from the route and populate the redux store. &lt;em&gt;redux-first-router&lt;/em&gt; allows for this using an alternative way of specifying the action-to-route mapping, with an included &lt;code&gt;thunk&lt;/code&gt; value. This is a function that runs when the route is matched and that has access to the current store. Within the &lt;code&gt;thunk&lt;/code&gt; we can read the &lt;code&gt;imdbID&lt;/code&gt; from the store (&lt;em&gt;redux-first-router&lt;/em&gt; put it on the &lt;code&gt;location&lt;/code&gt; key for us), perform a request, and publish the &lt;code&gt;MOVIE_FETCHED&lt;/code&gt; action with the data when we are done. &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; routesMap = { 
    &lt;span class=&quot;attr&quot;&gt;HOME&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'/'&lt;/span&gt;,
    &lt;span class=&quot;attr&quot;&gt;MOVIE&lt;/span&gt;: {
        &lt;span class=&quot;attr&quot;&gt;path&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'/movie/:imdbID'&lt;/span&gt;,
        &lt;span class=&quot;attr&quot;&gt;thunk&lt;/span&gt;: &lt;span class=&quot;keyword&quot;&gt;async&lt;/span&gt; (dispatch, getState) =&amp;gt; {
            dispatch({ &lt;span class=&quot;attr&quot;&gt;type&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;MOVIE_CLEAR&quot;&lt;/span&gt;});
            &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; imdbID = getState().location.payload.imdbID;
            &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; movie = &lt;span class=&quot;keyword&quot;&gt;await&lt;/span&gt; fetch(&lt;span class=&quot;string&quot;&gt;`http://www.omdbapi.com/?apikey=8e4dcdac&amp;amp;i=&lt;span class=&quot;subst&quot;&gt;${imdbID}&lt;/span&gt;`&lt;/span&gt;)
            .then(&lt;span class=&quot;function&quot;&gt;(&lt;span class=&quot;params&quot;&gt;response&lt;/span&gt;) =&amp;gt;&lt;/span&gt; response.json());
            dispatch({ &lt;span class=&quot;attr&quot;&gt;type&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;MOVIE_FETCHED&quot;&lt;/span&gt;, movie });
        }
    }
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;MOVIE_CLEAR&lt;/code&gt; action is dispatched before the request to clear the previous movie data from the store. The &lt;code&gt;movieReducer&lt;/code&gt; then copies the data from the action into the store.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; defaultState = {&lt;span class=&quot;attr&quot;&gt;movie&lt;/span&gt;: &lt;span class=&quot;literal&quot;&gt;null&lt;/span&gt;};

&lt;span class=&quot;keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; movieReducer = {
    &lt;span class=&quot;attr&quot;&gt;movie&lt;/span&gt;: &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; (&lt;span class=&quot;params&quot;&gt;state = defaultState, action&lt;/span&gt;) &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;switch&lt;/span&gt; (action.type) {
            &lt;span class=&quot;keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;MOVIE_CLEAR&quot;&lt;/span&gt;: 
                &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;built_in&quot;&gt;Object&lt;/span&gt;.assign({}, state, defaultState);
            &lt;span class=&quot;keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;MOVIE_FETCHED&quot;&lt;/span&gt;:
                &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;built_in&quot;&gt;Object&lt;/span&gt;.assign({}, state, {&lt;span class=&quot;attr&quot;&gt;movie&lt;/span&gt;: action.movie});
            &lt;span class=&quot;keyword&quot;&gt;default&lt;/span&gt;: &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; state;
        }
    }
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is what I mean by a ‘data bound route’. Whenever the route &lt;code&gt;/movie/:imdbID&lt;/code&gt; is seen we fetch the data for that route and put it in the store. &lt;/p&gt;
&lt;p&gt;If an AJAX request is required because of a user action then dispatch an action, with a promise &lt;code&gt;payload&lt;/code&gt;, in the &lt;code&gt;mapDispatchToProps&lt;/code&gt; function. &lt;em&gt;redux-promise-middleware&lt;/em&gt; will resolve the promise and publish the &lt;code&gt;_FULFILLED&lt;/code&gt; version of the action, which can be processed in a reducer. &lt;/p&gt;
&lt;p&gt;If a route requires an AJAX request we need a different strategy, because routes map to actions, which are processed in reducers, which don’t have the ability to dispatch new actions. &lt;em&gt;redux-first-router&lt;/em&gt; provides the &lt;code&gt;thunk&lt;/code&gt; option so that we have a place to do asynchronous operations in response to URL changes, and publish actions when we have a result.&lt;/p&gt;
&lt;h1 id=&quot;converting-event-actions-to-route-actions&quot;&gt;Converting Event Actions to Route Actions&lt;/h1&gt;
&lt;p&gt;Above I said,&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A good web application should have a URL for every addressable state&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;yet, when we perform a search, the application state changes but the URL does not. When you think about it, most actions represent a state change that can, and should, be reflected in a URL change. When I search for ‘Terminator’ I want the url to change to &lt;code&gt;/search/Terminator&lt;/code&gt;. Thus a search for terminator becomes an addressable state that I can link directly to.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;redux-first-router&lt;/em&gt; synchonizes in both directions. If the URL changes it publishes the corresponding route action. If a route action is dispatched it changes the URL. To make search results addressable we will handle the search form submission, dispatch a route action, then do the search using the route handling thunk. First, modify the action that is dispatched when a user searches:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;mapDispatchToProps&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;dispatch&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; {
        &lt;span class=&quot;attr&quot;&gt;onSearch&lt;/span&gt;: &lt;span class=&quot;function&quot;&gt;(&lt;span class=&quot;params&quot;&gt;title&lt;/span&gt;)=&amp;gt;&lt;/span&gt; {
            dispatch({
                &lt;span class=&quot;attr&quot;&gt;type&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'SEARCH'&lt;/span&gt;,
                &lt;span class=&quot;attr&quot;&gt;payload&lt;/span&gt;: {title}
                });
        } 
    };
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This &lt;code&gt;SEARCH&lt;/code&gt; action will be a route action. Next, add the &lt;code&gt;SEARCH&lt;/code&gt; action to the route configuration, mapped to &lt;code&gt;/search/:title&lt;/code&gt;. When the route is matched, read the &lt;code&gt;title&lt;/code&gt; from the Redux store, query the API, and then dispatch the &lt;code&gt;SEARCH_FULFILLED&lt;/code&gt; action that the &lt;code&gt;searchReducer&lt;/code&gt; is already expecting. &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; routesMap = { 
    &lt;span class=&quot;comment&quot;&gt;// ...&lt;/span&gt;
    SEARCH: {
        &lt;span class=&quot;attr&quot;&gt;path&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'/search/:title'&lt;/span&gt;,
        &lt;span class=&quot;attr&quot;&gt;thunk&lt;/span&gt;: &lt;span class=&quot;keyword&quot;&gt;async&lt;/span&gt; (dispatch, getState) =&amp;gt; {
            &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; title = getState().location.payload.title;
            &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; results = &lt;span class=&quot;keyword&quot;&gt;await&lt;/span&gt; fetch(&lt;span class=&quot;string&quot;&gt;`http://www.omdbapi.com/?apikey=8e4dcdac&amp;amp;s=&lt;span class=&quot;subst&quot;&gt;${&lt;span class=&quot;built_in&quot;&gt;encodeURIComponent&lt;/span&gt;(title)}&lt;/span&gt;`&lt;/span&gt;)
                .then(&lt;span class=&quot;function&quot;&gt;(&lt;span class=&quot;params&quot;&gt;response&lt;/span&gt;) =&amp;gt;&lt;/span&gt; response.json())
            dispatch({ &lt;span class=&quot;attr&quot;&gt;type&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;SEARCH_FULFILLED&quot;&lt;/span&gt;, &lt;span class=&quot;attr&quot;&gt;payload&lt;/span&gt;: results });
        }
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The routing for the application is now:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Route action&lt;/th&gt;
&lt;th&gt;URL&lt;/th&gt;
&lt;th&gt;Thunk&lt;/th&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;HOME&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;ConnectedSearch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;MOVIE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/movie/:imdbID&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Publishes &lt;code&gt;MOVIE_CLEAR&lt;/code&gt; actions. Fetches movie data by &lt;code&gt;imdbID&lt;/code&gt;. Publishes &lt;code&gt;MOVIE_FETCHED&lt;/code&gt; action.&lt;/td&gt;
&lt;td&gt;ConnectedMovie&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SEARCH&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/search/:title&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Fetches results by &lt;code&gt;title&lt;/code&gt;. Publishes &lt;code&gt;SEARCH_FULFILLED&lt;/code&gt;.&lt;/td&gt;
&lt;td&gt;ConnectedSearch&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;As the &lt;code&gt;onSearch&lt;/code&gt; handler no longer publishes an action with a promise we are no longer using &lt;em&gt;redux-promise-middleware&lt;/em&gt;. Many actions can be route changes and do their asynchronous operations with &lt;em&gt;redux-first-router&lt;/em&gt; thunks. Actions that do not make sense as route changes, but that still require an asynchronous operation, should still use &lt;em&gt;redux-promise-middleware&lt;/em&gt;.&lt;/p&gt;
&lt;h1 id=&quot;summary&quot;&gt;Summary&lt;/h1&gt;
&lt;p&gt;Where sensible, states should be addressable via a route. Where a route requires an asynchronous operations, such as making an AJAX request, use the &lt;code&gt;thunk&lt;/code&gt; property of the route configuration object to do the asynchronous operation and dispatch an action when it is complete.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Next: &lt;a href=&quot;http://withouttheloop.com/articles/2018-01-17-react-10-typescript/&quot;&gt;Learning React 10 - Typescript&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;get-the-code&quot;&gt;Get The Code&lt;/h2&gt;
&lt;p&gt;The code for this example is &lt;a href=&quot;https://github.com/liammclennan/movie-library&quot;&gt;on Github&lt;/a&gt;. You can access the code as it was at the completion of this step by cloning the repository and checking out the tag that corresponds to this post. &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-bash&quot;&gt;git &lt;span class=&quot;built_in&quot;&gt;clone&lt;/span&gt; https://github.com/liammclennan/movie-library.git
git checkout react9
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or browse at &lt;a href=&quot;https://github.com/liammclennan/movie-library/tree/react9&quot;&gt;https://github.com/liammclennan/movie-library/tree/react9&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Learning React 7 - AJAX</title>
      <link>http://withouttheloop.com/articles/2018-01-10-react-7-ajax/</link>
      <pubDate>Wed, 10 Jan 2018 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2018-01-10-react-7-ajax/</guid>
      <author></author>
      <description>&lt;p&gt;In &lt;a href=&quot;http://withouttheloop.com/articles/2018-01-08-react-6-react-router/&quot;&gt;Learning React 6 - React Router&lt;/a&gt; we learned how to connect a client-side router to a React application. &lt;/p&gt;
&lt;p&gt;In this post we will look at how to add AJAX HTTP requests to a React application. This requires more thought than introducing AJAX to products built with other libraries, because our React application so far has used pure components (components that produce output entirely determined by their inputs) and been entirely synchronous (processing proceeds continuously without having to wait for any external events).&lt;/p&gt;
&lt;h1 id=&quot;movie-library&quot;&gt;Movie Library&lt;/h1&gt;
&lt;p&gt;For this demonstration we will need a more complicated application than the one we have used so far, so we will build a movie library. The application will allow the user to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;search the &lt;a href=&quot;http://www.omdbapi.com&quot;&gt;OMDB movie database API&lt;/a&gt; for movies.&lt;/li&gt;
&lt;li&gt;view the details of a movie &lt;/li&gt;
&lt;li&gt;select movies to add to their favourite list&lt;/li&gt;
&lt;li&gt;view their favourite list&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Start by creating a new application with create-react-app:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-bash&quot;&gt;$ create-react-app movie-library
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and start the app:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-bash&quot;&gt;$ npm start
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Install redux, react-redux and a router (&lt;a href=&quot;https://github.com/faceyspacey/redux-first-router&quot;&gt;redux-first-router&lt;/a&gt;):&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-bash&quot;&gt;$ npm install --save redux react-redux &lt;span class=&quot;built_in&quot;&gt;history&lt;/span&gt; redux-first-router redux-first-router-link
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Modify &lt;code&gt;index.js&lt;/code&gt; to use a default redux implementation:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; React &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'react'&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; ReactDOM &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'react-dom'&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'./index.css'&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; registerServiceWorker &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'./registerServiceWorker'&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; { createStore } &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'redux'&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; { Provider } &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'react-redux'&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; App &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'./App'&lt;/span&gt;;

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;reducer&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;state = { }, action&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;switch&lt;/span&gt; (action.type) {
        &lt;span class=&quot;attr&quot;&gt;default&lt;/span&gt;: &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; state;
    }
}
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; store = createStore(reducer);

ReactDOM.render(
    &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;Provider&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;store&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;{store}&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;App&lt;/span&gt; /&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;Provider&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;, 
    &lt;span class=&quot;built_in&quot;&gt;document&lt;/span&gt;.getElementById(&lt;span class=&quot;string&quot;&gt;'root'&lt;/span&gt;));

store.dispatch({&lt;span class=&quot;attr&quot;&gt;type&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;START&quot;&lt;/span&gt;});

registerServiceWorker();
&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id=&quot;the-search-component&quot;&gt;The Search Component&lt;/h1&gt;
&lt;p&gt;The starting page of the movie library will feature a movie search component. &lt;/p&gt;
&lt;p&gt;Start by creating a new file, &lt;code&gt;Search.js&lt;/code&gt; containing a minimal Search component:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; React &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'react'&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; { connect } &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'react-redux'&lt;/span&gt;;

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Search&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;h1&lt;/span&gt;&amp;gt;&lt;/span&gt;Search&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;h1&lt;/span&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;;
}

&lt;span class=&quot;keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; ConnectedSearch = connect(
    &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;mapStateToProps&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;state&lt;/span&gt;) &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; state;
    }, 
    &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;mapDispatchToProps&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;dispatch&lt;/span&gt;) &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; {};
    }
)(Search);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;Search&lt;/code&gt; module exports a component &lt;code&gt;ConnectedSearch&lt;/code&gt; that is our search component wrapped in a react-redux connector to give it access to the redux store (we will need this later). Now, modify &lt;code&gt;App.js&lt;/code&gt; to import and use the &lt;code&gt;ConnectedSearch&lt;/code&gt; component:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt; &lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; React, { Component } &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'react'&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'./App.css'&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; { ConnectedSearch } &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'./Search'&lt;/span&gt;;

&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;App&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Component&lt;/span&gt; &lt;/span&gt;{
  render() {
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; (
      &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;className&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;App&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;header&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;className&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;App-header&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;h1&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;className&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;App-title&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;Movie Library&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;h1&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;header&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;ConnectedSearch&lt;/span&gt; /&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
    );
  }
}

&lt;span class=&quot;keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;default&lt;/span&gt; App;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now the application should be working a displaying a heading ‘Search’.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;Search&lt;/code&gt; component needs a text input. We will create a new component &lt;code&gt;SearchForm&lt;/code&gt; to contain the text input. To get the form to function properly we must use React’s component ‘state’ feature, which means using the &lt;a href=&quot;https://reactjs.org/docs/state-and-lifecycle.html&quot;&gt;class component syntax&lt;/a&gt; instead of the function syntax. Both ‘state’ and the class syntax are undesirable, hence why they are contained in the smallest possible area where they are absolutely needed (the &lt;code&gt;SearchForm&lt;/code&gt; component).&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;SearchForm&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;React&lt;/span&gt;.&lt;span class=&quot;title&quot;&gt;Component&lt;/span&gt; &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;constructor&lt;/span&gt;(props) {
        &lt;span class=&quot;keyword&quot;&gt;super&lt;/span&gt;(props);
        &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.state = {&lt;span class=&quot;attr&quot;&gt;title&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;&quot;&lt;/span&gt;}
        &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.titleChange = &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.titleChange.bind(&lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;);
        &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.search = &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.search.bind(&lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;);
    }

    titleChange(event) {
        &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.setState({&lt;span class=&quot;attr&quot;&gt;title&lt;/span&gt;: event.target.value});
    }

    search(event) {
        event.preventDefault();
        &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.props.onSearch(&lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.state.title);
    }

    render() {
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;form&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;onSubmit&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;{this.search}&lt;/span&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;label&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;htmlFor&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;title&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;Title: &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;label&lt;/span&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;type&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;text&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;name&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;title&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;value&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;{this.state.title}&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;onChange&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;{this.titleChange}/&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;form&lt;/span&gt;&amp;gt;&lt;/span&gt;;
    }
}

function Search() {
    return &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;h1&lt;/span&gt;&amp;gt;&lt;/span&gt;Search&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;h1&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;SearchForm&lt;/span&gt; /&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;;
}

export const ConnectedSearch = connect(
    function mapStateToProps(state) {
        return state;
    }, 
    function mapDispatchToProps(dispatch) {
        return {
            onSearch: (title)=&amp;gt; { dispatch({type: &quot;SEARCH&quot;, title}); }
        };
    }
)(Search);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When a user types a character in the textbox it fires the &lt;code&gt;onChange&lt;/code&gt; event, which &lt;a href=&quot;https://reactjs.org/docs/forms.html&quot;&gt;updates the components state to have the latest value of the textbox&lt;/a&gt;, which causes the component to re-render and display the character the user typed in the textbox. &lt;/p&gt;
&lt;p&gt;When the form is submitted we call the &lt;code&gt;onSearch&lt;/code&gt; function on &lt;code&gt;props&lt;/code&gt;. The React-Redux connection translates this into a dispatch of an action with &lt;code&gt;type: &amp;quot;SEARCH&amp;quot;&lt;/code&gt;.&lt;/p&gt;
&lt;h1 id=&quot;summary&quot;&gt;Summary&lt;/h1&gt;
&lt;p&gt;We started building a React movie library with React, Redux, react redux, and redux-first-router. We implemented a class component for a form, with local state and connected everything to our Redux store. &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Next: &lt;a href=&quot;http://withouttheloop.com/articles/2018-01-10-react-8-ajax-continued/&quot;&gt;Learning React 8 - AJAX Continued&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;get-the-code&quot;&gt;Get The Code&lt;/h2&gt;
&lt;p&gt;The code for this example is &lt;a href=&quot;https://github.com/liammclennan/movie-library&quot;&gt;on Github&lt;/a&gt;. You can access the code as it was at the completion of this step by cloning the repository and checking out the tag that corresponds to this post. &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-bash&quot;&gt;git &lt;span class=&quot;built_in&quot;&gt;clone&lt;/span&gt; https://github.com/liammclennan/movie-library.git
git checkout react7
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or browse at &lt;a href=&quot;https://github.com/liammclennan/movie-library/tree/7548d450b7727f124070dd7ee9b73575d740e9b3&quot;&gt;https://github.com/liammclennan/movie-library/tree/7548d450b7727f124070dd7ee9b73575d740e9b3&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Learning React 8 - AJAX continued</title>
      <link>http://withouttheloop.com/articles/2018-01-10-react-8-ajax-continued/</link>
      <pubDate>Wed, 10 Jan 2018 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2018-01-10-react-8-ajax-continued/</guid>
      <author></author>
      <description>&lt;p&gt;The &lt;a href=&quot;http://withouttheloop.com/articles/2018-01-10-react-7-ajax/&quot;&gt;last post&lt;/a&gt; started implementing our new demo application - the movie library. We were forced to introduce a React class component with state to make the search form work. &lt;/p&gt;
&lt;p&gt;When we type in the search text box and submit the form the expected action is sent to the redux store, as you can see in this screenshot featuring &lt;a href=&quot;https://github.com/zalmoxisus/redux-devtools-extension&quot;&gt;redux-devtools-extension&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2018-01-10-react-8-ajax-continued/search.png&quot; alt=&quot;Movie search&quot;&gt;&lt;/p&gt;
&lt;h1 id=&quot;routing&quot;&gt;Routing&lt;/h1&gt;
&lt;p&gt;For this example we are going to use &lt;a href=&quot;https://github.com/faceyspacey/redux-first-router#the-gist&quot;&gt;&lt;em&gt;redux-first-router&lt;/em&gt;&lt;/a&gt;. As &lt;a href=&quot;http://withouttheloop.com/articles/2018-01-08-react-6-react-router/&quot;&gt;mentioned previously&lt;/a&gt; &lt;em&gt;redux-first-router&lt;/em&gt; binds routes to actions. We must handle those actions and update the UI accordingly. &lt;/p&gt;
&lt;p&gt;See &lt;a href=&quot;https://github.com/faceyspacey/redux-first-router#the-gist&quot;&gt;the redux-router documentation&lt;/a&gt; for the full documentation, but we need to make &lt;code&gt;index.js&lt;/code&gt; look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; React &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'react'&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; ReactDOM &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'react-dom'&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'./index.css'&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; registerServiceWorker &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'./registerServiceWorker'&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; { createStore, combineReducers, applyMiddleware, compose } &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'redux'&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; { Provider } &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'react-redux'&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; { connectRoutes } &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'redux-first-router'&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; createHistory &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'history/createBrowserHistory'&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; App &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'./App'&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; {searchReducer} &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'./Search'&lt;/span&gt;;

&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; routesMap = { 
  &lt;span class=&quot;attr&quot;&gt;HOME&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'/'&lt;/span&gt;
};

&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; { reducer, middleware, enhancer } = connectRoutes(createHistory(), routesMap)

&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; store = createStore(combineReducers({
    &lt;span class=&quot;attr&quot;&gt;location&lt;/span&gt;: reducer,
    &lt;span class=&quot;attr&quot;&gt;search&lt;/span&gt;: searchReducer
}), compose(enhancer, applyMiddleware(middleware),
&lt;span class=&quot;built_in&quot;&gt;window&lt;/span&gt;.__REDUX_DEVTOOLS_EXTENSION__ &amp;amp;&amp;amp; &lt;span class=&quot;built_in&quot;&gt;window&lt;/span&gt;.__REDUX_DEVTOOLS_EXTENSION__()));

ReactDOM.render(
    &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;Provider&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;store&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;{store}&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;App&lt;/span&gt; /&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;Provider&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;, 
    &lt;span class=&quot;built_in&quot;&gt;document&lt;/span&gt;.getElementById(&lt;span class=&quot;string&quot;&gt;'root'&lt;/span&gt;));

store.dispatch({&lt;span class=&quot;attr&quot;&gt;type&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;START&quot;&lt;/span&gt;});

registerServiceWorker();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;routesMap&lt;/code&gt; defines the mapping between action types and routes. Here we are saying that the route &lt;code&gt;/&lt;/code&gt; should map to the &lt;code&gt;HOME&lt;/code&gt; action type. The &lt;em&gt;redux-first-router&lt;/em&gt; state is put into the store on the &lt;code&gt;location&lt;/code&gt; key. &lt;/p&gt;
&lt;p&gt;Next we connect the &lt;code&gt;App&lt;/code&gt; component to the Redux store:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;App&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;{type}&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; componentMap = {
      &lt;span class=&quot;attr&quot;&gt;HOME&lt;/span&gt;: ConnectedSearch
    };
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; View = componentMap[type];

    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; (
      &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;className&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;App&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;header&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;className&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;App-header&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;h1&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;className&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;App-title&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;Movie Library&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;h1&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;header&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;View&lt;/span&gt; /&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
    );
}

&lt;span class=&quot;keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;default&lt;/span&gt; connect(&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;mapStateToProps&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;state&lt;/span&gt;) &lt;/span&gt;{
  &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; state.location;
}, 
(dispatch) =&amp;gt; ({}))(App);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;redux-first-router&lt;/em&gt; puts route information into the redux store when a route is matched. &lt;code&gt;mapStateToProps&lt;/code&gt; extracts the &lt;code&gt;location&lt;/code&gt; key from the store, which is then used in the &lt;code&gt;App&lt;/code&gt; component to extract the &lt;code&gt;type&lt;/code&gt; value.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;componentMap&lt;/code&gt; maps route action types to React components. If the route action type is &lt;code&gt;HOME&lt;/code&gt; then &lt;code&gt;View&lt;/code&gt; will be a &lt;code&gt;ConnectedSearch&lt;/code&gt;, which is what we want for the home page.&lt;/p&gt;
&lt;h1 id=&quot;ajax-actions&quot;&gt;AJAX Actions&lt;/h1&gt;
&lt;p&gt;The difficulty we encounter when trying to search for a movie (via an AJAX request) is that we can’t take the search action (&lt;code&gt;{ type: &amp;quot;SEARCH&amp;quot;, title: &amp;quot;Term&amp;quot; }&lt;/code&gt;) and update the UI state from that. We need to make an asynchronous request in the middle. &lt;/p&gt;
&lt;p&gt;Nearly every React application must overcome this difficulty. There are lots of different solution and I will present one. &lt;/p&gt;
&lt;p&gt;First, install &lt;a href=&quot;https://github.com/pburtchaell/redux-promise-middleware/blob/master/docs/introduction.md&quot;&gt;redux-promise-middleware&lt;/a&gt;. &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-bash&quot;&gt;$ npm install redux-promise-middleware --save
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;redux-promise-middleware&lt;/em&gt; is a library that intercepts actions that carry a promise (&lt;code&gt;SEARCH&lt;/code&gt;). When the promise resolves the library dispatches a new action with the result (&lt;code&gt;SEARCH_FULFILLED&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;We create a promise using the fetch API to make a request to omdbapi to search for movies by title. &lt;/p&gt;
&lt;p&gt;We dispatch:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;dispatch({
    &lt;span class=&quot;attr&quot;&gt;type&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'SEARCH'&lt;/span&gt;,
    &lt;span class=&quot;attr&quot;&gt;payload&lt;/span&gt;: fetch(&lt;span class=&quot;string&quot;&gt;`http://www.omdbapi.com/?apikey=8e4dcdac&amp;amp;s=&lt;span class=&quot;subst&quot;&gt;${&lt;span class=&quot;built_in&quot;&gt;encodeURIComponent&lt;/span&gt;(title)}&lt;/span&gt;`&lt;/span&gt;)
        .then(&lt;span class=&quot;function&quot;&gt;(&lt;span class=&quot;params&quot;&gt;response&lt;/span&gt;) =&amp;gt;&lt;/span&gt; response.json())
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and in the reducer look for &lt;code&gt;SEARCH_FULFILLED&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;searchReducer&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;state = {results: []}, action&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;switch&lt;/span&gt; (action.type) {
        &lt;span class=&quot;keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;SEARCH_FULFILLED&quot;&lt;/span&gt;:
            &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;built_in&quot;&gt;Object&lt;/span&gt;.assign(
                {}, 
                { &lt;span class=&quot;attr&quot;&gt;results&lt;/span&gt;: action.payload.Response 
                        ? action.payload.Search.filter(&lt;span class=&quot;function&quot;&gt;(&lt;span class=&quot;params&quot;&gt;{Poster}&lt;/span&gt;) =&amp;gt;&lt;/span&gt; Poster !== &lt;span class=&quot;string&quot;&gt;&quot;N/A&quot;&lt;/span&gt;) 
                        : []});
        &lt;span class=&quot;keyword&quot;&gt;default&lt;/span&gt;: &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; state;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Update the &lt;code&gt;Search&lt;/code&gt; component to display our recently acquired movie data:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Search&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;{ onSearch, results = [] }&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &amp;lt;div&amp;gt;
        &amp;lt;h1&amp;gt;Search&amp;lt;/h1&amp;gt;
        &amp;lt;SearchForm onSearch={onSearch} /&amp;gt;
        &amp;lt;div&amp;gt;
            {results.map(({Title,Poster,imdbID})=&amp;gt; 
                &amp;lt;img src={Poster} alt={Title} key={imdbID} /&amp;gt;)}
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now look at our amazing application!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2018-01-10-react-8-ajax-continued/terminator.png&quot; alt=&quot;Movie library search terminator&quot;&gt;&lt;/p&gt;
&lt;p&gt;The complete &lt;code&gt;Search.js&lt;/code&gt; is:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; React &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'react'&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; { connect } &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'react-redux'&lt;/span&gt;;

&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;SearchForm&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;React&lt;/span&gt;.&lt;span class=&quot;title&quot;&gt;Component&lt;/span&gt; &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;constructor&lt;/span&gt;(props) {
        &lt;span class=&quot;keyword&quot;&gt;super&lt;/span&gt;(props);
        &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.state = {&lt;span class=&quot;attr&quot;&gt;title&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;&quot;&lt;/span&gt;}
        &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.titleChange = &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.titleChange.bind(&lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;);
        &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.search = &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.search.bind(&lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;);
    }

    titleChange(event) {
        &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.setState({&lt;span class=&quot;attr&quot;&gt;title&lt;/span&gt;: event.target.value});
    }

    search(event) {
        event.preventDefault();
        &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.props.onSearch(&lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.state.title);
    }

    render() {
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &amp;lt;div&amp;gt;&amp;lt;form onSubmit={this.search}&amp;gt;
            &amp;lt;label htmlFor=&quot;title&quot;&amp;gt;Title: &amp;lt;/label&amp;gt;
            &amp;lt;input type=&quot;text&quot; name=&quot;title&quot; value={this.state.title} onChange={this.titleChange}/&amp;gt;
            &amp;lt;input type=&quot;submit&quot; value=&quot;Search&quot;/&amp;gt;
        &amp;lt;/form&amp;gt;
        &amp;lt;/div&amp;gt;;
    }
}

function Search({ onSearch, results = [] }) {
    return &amp;lt;div&amp;gt;
        &amp;lt;h1&amp;gt;Search&amp;lt;/h1&amp;gt;
        &amp;lt;SearchForm onSearch={onSearch} /&amp;gt;
        &amp;lt;div&amp;gt;
            {results.map(({Title,Poster,imdbID})=&amp;gt; &amp;lt;img src={Poster} alt={Title} key={imdbID} /&amp;gt;)}
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;;
}

export const ConnectedSearch = connect(
    function mapStateToProps(state) {
        return state.search;
    }, 
    function mapDispatchToProps(dispatch) {
        return {
            onSearch: (title)=&amp;gt; {
                dispatch({
                    type: 'SEARCH',
                    payload: fetch(`http://www.omdbapi.com/?apikey=8e4dcdac&amp;amp;s=${encodeURIComponent(title)}`)
                            .then((response) =&amp;gt; response.json())
                  });
            }
        };
    }
)(Search);

export function searchReducer(state = {results: []}, action) {
    switch (action.type) {
        case &quot;SEARCH_FULFILLED&quot;:
            return Object.assign(
                {}, 
                { results: action.payload.Response 
                        ? action.payload.Search.filter(({Poster}) =&amp;gt; Poster !== &quot;N/A&quot;) 
                        : []});
        default: return state;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id=&quot;summary&quot;&gt;Summary&lt;/h1&gt;
&lt;p&gt;First, we setup &lt;em&gt;redux-first-router&lt;/em&gt; and implemented the &lt;code&gt;HOME&lt;/code&gt; route. Then we introduced &lt;em&gt;redux-promise-middleware&lt;/em&gt; as a way of inserting asynchronous operations into the redux data cycle. &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Next: &lt;a href=&quot;http://withouttheloop.com/articles/2018-01-11-react-9-data-bound-routes/&quot;&gt;Learning React 9 - Data Bound Routes&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;get-the-code&quot;&gt;Get The Code&lt;/h2&gt;
&lt;p&gt;The code for this example is &lt;a href=&quot;https://github.com/liammclennan/movie-library&quot;&gt;on Github&lt;/a&gt;. You can access the code as it was at the completion of this step by cloning the repository and checking out the tag that corresponds to this post. &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-bash&quot;&gt;git &lt;span class=&quot;built_in&quot;&gt;clone&lt;/span&gt; https://github.com/liammclennan/movie-library.git
git checkout react8
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or browse at &lt;a href=&quot;https://github.com/liammclennan/movie-library/tree/c93c652fa1318ce6447d985e3f8b690386456565&quot;&gt;https://github.com/liammclennan/movie-library/tree/c93c652fa1318ce6447d985e3f8b690386456565&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Learning React 6 - React Router</title>
      <link>http://withouttheloop.com/articles/2018-01-08-react-6-react-router/</link>
      <pubDate>Mon, 08 Jan 2018 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2018-01-08-react-6-react-router/</guid>
      <author></author>
      <description>&lt;p&gt;&lt;a href=&quot;http://withouttheloop.com/articles/2018-01-05-react-5-react-redux/&quot;&gt;Learning React 5 - React-Redux&lt;/a&gt; explored the helpers provided by Redux for integration into a React application. Our today application is now using Redux to store and manage state. &lt;/p&gt;
&lt;p&gt;Applications designed for the web should be URL oriented. Adhering to this expectations enables navigation, caching, book marking and many other standard activities. Implmenting routing in a React application requires a routing library, and the most popular is &lt;a href=&quot;https://reacttraining.com/react-router/web/guides/quick-start&quot;&gt;React Router&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&quot;react-router&quot;&gt;React Router&lt;/h1&gt;
&lt;p&gt;In this post we will add routing, using React Router, to our today application. We will support URLs like,&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;localhost:3000/day/2018-03-20
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That will set the &lt;code&gt;day&lt;/code&gt; value to March 20. Instead of having to use the ‘Next’ button users will be able to navigate directly to day of their choosing, and instead of the ‘Next’ button being implemented as a state change it will become a simple navigation link to the next day. &lt;/p&gt;
&lt;p&gt;To start, as always, install the new library:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; npm install react-router-dom --save
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To add the router, without modifying the existing behaviour we: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;import some React Router functions&lt;/li&gt;
&lt;li&gt;add a &lt;code&gt;Router&lt;/code&gt; to our component tree&lt;/li&gt;
&lt;li&gt;add a &lt;code&gt;Route&lt;/code&gt; component that maps a URL to a component&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; { BrowserRouter &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; Router, Route } &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'react-router-dom'&lt;/span&gt;;

ReactDOM.render(
    &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;Provider&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;store&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;{store}&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;Router&lt;/span&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;Route&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;exact&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;path&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;/&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;component&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;{ConnectedToday}&lt;/span&gt; /&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;Router&lt;/span&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;Provider&lt;/span&gt;&amp;gt;&lt;/span&gt;, 
    document.getElementById('root'));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This declares that the root path (‘/‘) should result in the the &lt;code&gt;ConnectedToday&lt;/code&gt; component being rendered in the position specified. &lt;/p&gt;
&lt;p&gt;Now our application is using a router, but behaving exactly as before. &lt;/p&gt;
&lt;p&gt;Let’s add another route for &lt;strong&gt;/day/YYYY-MM-DD&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-html&quot;&gt;ReactDOM.render(
    &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;Provider&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;store&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;{store}&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;Router&lt;/span&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;Route&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;exact&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;path&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;/&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;component&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;{ConnectedToday}&lt;/span&gt; /&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;Route&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;path&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;/day/:datestring&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;component&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;{ConnectedToday}&lt;/span&gt; /&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;Router&lt;/span&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;Provider&lt;/span&gt;&amp;gt;&lt;/span&gt;,
    document.getElementById('root'));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that &lt;code&gt;:datestring&lt;/code&gt; represents a querystring parameter variable. Next, modify the &lt;code&gt;Today&lt;/code&gt; component to read its date from the router instead of from Redux:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Today&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;props&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; day = &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;built_in&quot;&gt;Date&lt;/span&gt;(props.match.params.datestring);
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;Today is {day.toString()} 
        &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;button&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;type&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;button&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;onClick&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;{props.onNext}&lt;/span&gt;&amp;gt;&lt;/span&gt;Next&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;button&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;React Router uses &lt;a href=&quot;https://reactjs.org/docs/context.html&quot;&gt;the same trick&lt;/a&gt; as Redux to supply route parameters to components without having to manually pass them as props. &lt;/p&gt;
&lt;p&gt;Now you can navigate to a URL like &lt;em&gt;&lt;a href=&quot;http://localhost:3000/day/1994-5-8&quot;&gt;http://localhost:3000/day/1994-5-8&lt;/a&gt;&lt;/em&gt; to get the Today component rendered for the 8th May 1994. We have broken the next button because it increments a &lt;code&gt;day&lt;/code&gt; value in the Redux store, but our component takes its day value from the router. Instead of incrementing a value in the store we can instead use a link to the next day:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Today&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;props&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; day = &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;built_in&quot;&gt;Date&lt;/span&gt;(props.match.params.datestring);
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; nextDay = &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;built_in&quot;&gt;Date&lt;/span&gt;(day.getTime() + (&lt;span class=&quot;number&quot;&gt;24&lt;/span&gt;*&lt;span class=&quot;number&quot;&gt;3600&lt;/span&gt;*&lt;span class=&quot;number&quot;&gt;1000&lt;/span&gt;));
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; tomorrowDateString = &lt;span class=&quot;string&quot;&gt;`&lt;span class=&quot;subst&quot;&gt;${nextDay.getFullYear()}&lt;/span&gt;-&lt;span class=&quot;subst&quot;&gt;${nextDay.getMonth()+&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;}&lt;/span&gt;-&lt;span class=&quot;subst&quot;&gt;${nextDay.getDate()}&lt;/span&gt;`&lt;/span&gt;;
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; (
        &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;Today is {day.toString()} 
            &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;Link&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;to&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;{&lt;/span&gt;&quot;/&lt;span class=&quot;attr&quot;&gt;day&lt;/span&gt;/&quot; + &lt;span class=&quot;attr&quot;&gt;tomorrowDateString&lt;/span&gt;}&amp;gt;&lt;/span&gt;Next&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;Link&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;Link&lt;/code&gt; is a React Router component used to generate links.&lt;/p&gt;
&lt;p&gt;Now our UI is bound to the URL. As we navigate through consecutive days you will see the URL change. Also, if you manually change the URL the UI is updated to match. To make our routing more interesting, let’s add a &lt;code&gt;Home&lt;/code&gt; component on the root URL:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-html&quot;&gt;ReactDOM.render(
    &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;Provider&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;store&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;{store}&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;Router&lt;/span&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;Route&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;exact&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;path&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;/&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;component&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;{Home}&lt;/span&gt; /&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;Route&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;path&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;/day/:datestring&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;component&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;{ConnectedToday}&lt;/span&gt; /&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;Router&lt;/span&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;Provider&lt;/span&gt;&amp;gt;&lt;/span&gt;,
    document.getElementById('root'));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;Home&lt;/code&gt; component should display a link to a randomly selected day:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Home&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; randomBetween = &lt;span class=&quot;function&quot;&gt;(&lt;span class=&quot;params&quot;&gt;min, max&lt;/span&gt;) =&amp;gt;&lt;/span&gt; &lt;span class=&quot;built_in&quot;&gt;Math&lt;/span&gt;.floor(&lt;span class=&quot;built_in&quot;&gt;Math&lt;/span&gt;.random() * (max-min+&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;) + min);
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; randomDateString = 
        &lt;span class=&quot;string&quot;&gt;`&lt;span class=&quot;subst&quot;&gt;${randomBetween(&lt;span class=&quot;number&quot;&gt;1900&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;2100&lt;/span&gt;)}&lt;/span&gt;-&lt;span class=&quot;subst&quot;&gt;${randomBetween(&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;12&lt;/span&gt;)}&lt;/span&gt;-&lt;span class=&quot;subst&quot;&gt;${randomBetween(&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;number&quot;&gt;28&lt;/span&gt;)}&lt;/span&gt;`&lt;/span&gt;;

    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;h1&lt;/span&gt;&amp;gt;&lt;/span&gt;Home&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;h1&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;Link&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;to&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;{&lt;/span&gt;`/&lt;span class=&quot;attr&quot;&gt;day&lt;/span&gt;/${&lt;span class=&quot;attr&quot;&gt;randomDateString&lt;/span&gt;}`}&amp;gt;&lt;/span&gt;{randomDateString}&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;Link&lt;/span&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With this completed we have a home component that links to a random day, that has a next button that advances (via the URL) to the next day. For this particular application at this time we could delete all of the Redux and Redux-router code, because we are no longer managing any state in Redux. &lt;/p&gt;
&lt;h1 id=&quot;redux-first-router&quot;&gt;redux-first-router&lt;/h1&gt;
&lt;p&gt;I chose Redux Router for this example because it is by far the most popular React router, but the awkwardness of integrating React Router and Redux into an application is bothersome. An alternative is to use a &lt;a href=&quot;https://github.com/faceyspacey/redux-first-router&quot;&gt;redux-first-router&lt;/a&gt; instead of React Router. redux-first-router does not bind routes to components, instead it binds routes to actions. When a route is matched redux-first-router dispatches an action to that effect and everything else is handled the Redux way with reducers. &lt;/p&gt;
&lt;h1 id=&quot;summary&quot;&gt;Summary&lt;/h1&gt;
&lt;p&gt;URLs are the central abstraction of a well-behaved web application. To achieve this with React we need a router. React router is the popular choice although it does have some friction with state management solutions like Redux. redux-first-router is another alternative. &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Next: &lt;a href=&quot;http://withouttheloop.com/articles/2018-01-10-react-7-ajax/&quot;&gt;Learning React 7 - AJAX&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;get-the-code&quot;&gt;Get The Code&lt;/h2&gt;
&lt;p&gt;The code for this example is &lt;a href=&quot;https://github.com/liammclennan/today-react-app&quot;&gt;on Github&lt;/a&gt;. You can access the code as it was at the completion of this step by cloning the repository and checking out the tag that corresponds to this post. &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-bash&quot;&gt;git &lt;span class=&quot;built_in&quot;&gt;clone&lt;/span&gt; https://github.com/liammclennan/today-react-app.git
git checkout react6
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or browse at &lt;a href=&quot;https://github.com/liammclennan/today-react-app/tree/4f53d611e3ecaa3d5bcfe92e970e56fcf6981860&quot;&gt;https://github.com/liammclennan/today-react-app/tree/4f53d611e3ecaa3d5bcfe92e970e56fcf6981860&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Learning React 4 - Redux</title>
      <link>http://withouttheloop.com/articles/2018-01-05-react-4-redux/</link>
      <pubDate>Fri, 05 Jan 2018 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2018-01-05-react-4-redux/</guid>
      <author></author>
      <description>&lt;p&gt;The post &lt;a href=&quot;http://withouttheloop.com/articles/2018-01-03-react-3-data-out/&quot;&gt;Learning React 3 - Data out with props&lt;/a&gt; finished with a 
component that is customised by data passed in, and that publishes user events, which modifies that application state, and causes the component to update. &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Today&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;{ day, onNext }&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
                Today is {day.toString()}
                &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;button&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;type&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;button&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;onClick&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;{onNext}&lt;/span&gt;&amp;gt;&lt;/span&gt;Next&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;button&lt;/span&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;;
}

&lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; day = &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;built_in&quot;&gt;Date&lt;/span&gt;(&lt;span class=&quot;number&quot;&gt;2018&lt;/span&gt;,&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;number&quot;&gt;20&lt;/span&gt;);

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;onNext&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
    day = &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;built_in&quot;&gt;Date&lt;/span&gt;(day.getTime() + (&lt;span class=&quot;number&quot;&gt;24&lt;/span&gt;*&lt;span class=&quot;number&quot;&gt;3600&lt;/span&gt;*&lt;span class=&quot;number&quot;&gt;1000&lt;/span&gt;)); 
    render();
}

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;render&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
    ReactDOM.render(&lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;Today&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;day&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;{day}&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;onNext&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;{onNext}&lt;/span&gt; /&amp;gt;&lt;/span&gt;, 
        document.getElementById('root'));
}
render();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To keep the &lt;code&gt;Today&lt;/code&gt; component simple and composable the state has been entirely pulled out of the component (into the &lt;code&gt;day&lt;/code&gt; variable).&lt;/p&gt;
&lt;p&gt;As applications become more complex it becomes more difficult to work with this external state and keep track of the modifications that need to be made in response to events. &lt;/p&gt;
&lt;h1 id=&quot;redux&quot;&gt;Redux&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://redux.js.org/docs/introduction/&quot;&gt;Redux&lt;/a&gt; is a tool for managing application state and controlling changes to that state. I find the Redux documentation unnecessarily confusing. All you really need to know to understand Redux is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Redux holds state in a single Javascript object, called a store.&lt;/li&gt;
&lt;li&gt;Redux uses functions (sometimes referred to as reducers) to apply events (sometimes called actions) to update the application state. &lt;/li&gt;
&lt;li&gt;Redux has a function &lt;code&gt;createStore&lt;/code&gt; that creates a store.&lt;/li&gt;
&lt;li&gt;Redux has a function &lt;code&gt;getState&lt;/code&gt; that gets the application state from the store.&lt;/li&gt;
&lt;li&gt;Redux has a function &lt;code&gt;subscribe&lt;/code&gt; that registers listeners to be called when the application state changes. &lt;/li&gt;
&lt;li&gt;Redux has a function &lt;code&gt;dispatch&lt;/code&gt; that is used to send an event (action) to the reducer to update the store.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Consider our Today component. First we add redux to our project:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; npm install redux --save
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now we can put our application state into a redux store:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;reducer&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;state = { day: new Date(&lt;span class=&quot;number&quot;&gt;2018&lt;/span&gt;,&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;number&quot;&gt;20&lt;/span&gt;&lt;/span&gt;) }, &lt;span class=&quot;title&quot;&gt;action&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; state;
}
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; store = createStore(reducer);

store.subscribe(&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt; =&amp;gt;&lt;/span&gt; {
    ReactDOM.render(&lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;Today&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;day&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;{store.getState().day}&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;onNext&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;{onNext}&lt;/span&gt; /&amp;gt;&lt;/span&gt;, 
        document.getElementById('root'));
});

store.dispatch({type: &quot;START&quot;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That is enough to get the application to render with its initial state. Note that the initial application state (&lt;code&gt;{ day: new Date(2018,2,20) }&lt;/code&gt;) is set as the default value of the &lt;code&gt;state&lt;/code&gt; argument. &lt;/p&gt;
&lt;p&gt;The event handling is broken because we can no longer directly modify the &lt;code&gt;day&lt;/code&gt; variable. Instead we must dispatch an appropriate action (&lt;code&gt;NEXT_DAY&lt;/code&gt;) to the redux store. In the reducer function, if we see our action (&lt;code&gt;NEXT_DAY&lt;/code&gt;) then we return a new application state with the &lt;code&gt;day&lt;/code&gt; value advanced by one day:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;onNext&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
    store.dispatch({&lt;span class=&quot;attr&quot;&gt;type&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;NEXT_DAY&quot;&lt;/span&gt;});
}

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;reducer&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;state = { day: new Date(&lt;span class=&quot;number&quot;&gt;2018&lt;/span&gt;,&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;number&quot;&gt;20&lt;/span&gt;&lt;/span&gt;) }, &lt;span class=&quot;title&quot;&gt;action&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;switch&lt;/span&gt; (action.type) {
        &lt;span class=&quot;keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;NEXT_DAY&quot;&lt;/span&gt;:
            &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; currentDay = store.getState().day;
            &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; { &lt;span class=&quot;attr&quot;&gt;day&lt;/span&gt;: &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;built_in&quot;&gt;Date&lt;/span&gt;(currentDay.getTime() + (&lt;span class=&quot;number&quot;&gt;24&lt;/span&gt;*&lt;span class=&quot;number&quot;&gt;3600&lt;/span&gt;*&lt;span class=&quot;number&quot;&gt;1000&lt;/span&gt;))};
        &lt;span class=&quot;keyword&quot;&gt;default&lt;/span&gt;: &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; state;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Both the state object and the action objects can be any Javascript value. It is a convention to include a &lt;code&gt;type&lt;/code&gt; property on action values. The &lt;code&gt;type&lt;/code&gt; property can then be used in reducer functions to determine which event/action has occurred so that the application state can be updated appropriately. &lt;/p&gt;
&lt;p&gt;The full program is now:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Today&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;{ day, onNext }&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;Today is {day.toString()}
        &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;button&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;type&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;button&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;onClick&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;{onNext}&lt;/span&gt;&amp;gt;&lt;/span&gt;Next&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;button&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;;
}

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;onNext&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
    store.dispatch({&lt;span class=&quot;attr&quot;&gt;type&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;NEXT_DAY&quot;&lt;/span&gt;});
}

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;reducer&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;state = { day: new Date(&lt;span class=&quot;number&quot;&gt;2018&lt;/span&gt;,&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;number&quot;&gt;20&lt;/span&gt;&lt;/span&gt;) }, &lt;span class=&quot;title&quot;&gt;action&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;switch&lt;/span&gt; (action.type) {
        &lt;span class=&quot;keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;NEXT_DAY&quot;&lt;/span&gt;:
            &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; currentDay = store.getState().day;
            &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; { &lt;span class=&quot;attr&quot;&gt;day&lt;/span&gt;: &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;built_in&quot;&gt;Date&lt;/span&gt;(currentDay.getTime() + (&lt;span class=&quot;number&quot;&gt;24&lt;/span&gt;*&lt;span class=&quot;number&quot;&gt;3600&lt;/span&gt;*&lt;span class=&quot;number&quot;&gt;1000&lt;/span&gt;))};
        &lt;span class=&quot;keyword&quot;&gt;default&lt;/span&gt;: &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; state;
    }
}
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; store = createStore(reducer);

store.subscribe(&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt; =&amp;gt;&lt;/span&gt; {
    ReactDOM.render(&lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;Today&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;day&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;{store.getState().day}&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;onNext&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;{onNext}&lt;/span&gt; /&amp;gt;&lt;/span&gt;, 
        document.getElementById('root'));
});

store.dispatch({type: &quot;START&quot;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id=&quot;summary&quot;&gt;Summary&lt;/h1&gt;
&lt;p&gt;Redux can be confusing, because of all the additional machinery that has accumulated around it, and because of the way the documentation is presented. At its core Redux is just a container for application state and a formalized way of modifying that application state.&lt;/p&gt;
&lt;p&gt;Good React components are simple, pure functions of their inputs (props). Redux is a helpful tool that makes this much easier.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Next: &lt;a href=&quot;http://withouttheloop.com/articles/2018-01-05-react-5-react-redux/&quot;&gt;Learning React 5 - React-redux&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;get-the-code&quot;&gt;Get The Code&lt;/h2&gt;
&lt;p&gt;The code for this example is &lt;a href=&quot;https://github.com/liammclennan/today-react-app&quot;&gt;on Github&lt;/a&gt;. You can access the code as it was at the completion of this step by cloning the repository and checking out the tag that corresponds to this post. &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-bash&quot;&gt;git &lt;span class=&quot;built_in&quot;&gt;clone&lt;/span&gt; https://github.com/liammclennan/today-react-app.git
git checkout react4
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or browse at &lt;a href=&quot;https://github.com/liammclennan/today-react-app/tree/9f17db0e8d19c505efaaa7e828cb71e535e2377a&quot;&gt;https://github.com/liammclennan/today-react-app/tree/9f17db0e8d19c505efaaa7e828cb71e535e2377a&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Learning React 5 - React-Redux</title>
      <link>http://withouttheloop.com/articles/2018-01-05-react-5-react-redux/</link>
      <pubDate>Fri, 05 Jan 2018 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2018-01-05-react-5-react-redux/</guid>
      <author></author>
      <description>&lt;p&gt;In &lt;a href=&quot;http://withouttheloop.com/articles/2018-01-05-react-4-redux/&quot;&gt;Learning React 4 - Redux&lt;/a&gt; we learnt about what Redux can do for your React 
application and how it can be integrated. The result was the following code:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Today&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;{ day, onNext }&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;Today is {day.toString()}
        &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;button&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;type&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;button&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;onClick&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;{onNext}&lt;/span&gt;&amp;gt;&lt;/span&gt;Next&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;button&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;;
}

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;onNext&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
    store.dispatch({&lt;span class=&quot;attr&quot;&gt;type&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;NEXT_DAY&quot;&lt;/span&gt;});
}

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;reducer&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;state = { day: new Date(&lt;span class=&quot;number&quot;&gt;2018&lt;/span&gt;,&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;number&quot;&gt;20&lt;/span&gt;&lt;/span&gt;) }, &lt;span class=&quot;title&quot;&gt;action&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;switch&lt;/span&gt; (action.type) {
        &lt;span class=&quot;keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;NEXT_DAY&quot;&lt;/span&gt;:
            &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; currentDay = store.getState().day;
            &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; { &lt;span class=&quot;attr&quot;&gt;day&lt;/span&gt;: &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;built_in&quot;&gt;Date&lt;/span&gt;(currentDay.getTime() + (&lt;span class=&quot;number&quot;&gt;24&lt;/span&gt;*&lt;span class=&quot;number&quot;&gt;3600&lt;/span&gt;*&lt;span class=&quot;number&quot;&gt;1000&lt;/span&gt;))};
        &lt;span class=&quot;keyword&quot;&gt;default&lt;/span&gt;: &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; state;
    }
}
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; store = createStore(reducer);

store.subscribe(&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt; =&amp;gt;&lt;/span&gt; {
    ReactDOM.render(&lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;Today&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;day&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;{store.getState().day}&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;onNext&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;{onNext}&lt;/span&gt; /&amp;gt;&lt;/span&gt;, 
        document.getElementById('root'));
});

store.dispatch({type: &quot;START&quot;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that the &lt;code&gt;Today&lt;/code&gt; component is not coupled to the Redux store (which is good), but also that we are manually passing data into and out of the &lt;code&gt;Today&lt;/code&gt; component. This is fine for our example but typically a component is contained many levels deep in a component hierarchy. The design we have so far would require us to pass the &lt;code&gt;day&lt;/code&gt; prop manually down through each level of the hierarchy and the &lt;code&gt;onNext&lt;/code&gt; prop manually back up through each level of the hierarchy. &lt;/p&gt;
&lt;h1 id=&quot;react-redux&quot;&gt;React-redux&lt;/h1&gt;
&lt;p&gt;React, and Redux, provide a solution to this problem, implemented in a package called &lt;a href=&quot;https://github.com/reactjs/react-redux&quot;&gt;React-redux&lt;/a&gt;. Install in the usual way:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; npm install react-redux --save
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;React-redux provides a way to connect a component’s props to the pieces of the Redux state that the component cares about. When creating a component you get this work by:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;defining the mapping from the Redux state to the components &lt;code&gt;props&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;defining the mapping from the components props to actions dispatched to the Redux store&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The above mappings are combined with an existing component to produce a new component, that is connected to Redux. For the &lt;code&gt;Today&lt;/code&gt; component this is:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; { connect, Provider } &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'react-redux'&lt;/span&gt;;

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Today&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;{ day, onNext }&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;Today is {day.toString()}
        &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;button&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;type&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;button&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;onClick&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;{onNext}&lt;/span&gt;&amp;gt;&lt;/span&gt;Next&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;button&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;;
}

&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; ConnectedToday = connect(
    &lt;span class=&quot;comment&quot;&gt;// Today uses the 'day' property of the Redux state. &lt;/span&gt;
    &lt;span class=&quot;comment&quot;&gt;// Which is the whole thing. &lt;/span&gt;
    &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;mapStateToProps&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;state&lt;/span&gt;) &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; state;
    }, 
    &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;mapDispatchToProps&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;dispatch&lt;/span&gt;) &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; {
            &lt;span class=&quot;comment&quot;&gt;// This 'onNext' function is provided as a prop to the 'Today' component, &lt;/span&gt;
            &lt;span class=&quot;comment&quot;&gt;// but with 'dispatch' in scope. &lt;/span&gt;
            onNext: &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt;=&amp;gt;&lt;/span&gt; { dispatch({&lt;span class=&quot;attr&quot;&gt;type&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;NEXT_DAY&quot;&lt;/span&gt;}); }
        };
    }
    )(Today);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;ConnectedToday&lt;/code&gt; is a new component that wraps the &lt;code&gt;Today&lt;/code&gt; component and connects it to the Redux store. Now when we &lt;code&gt;render&lt;/code&gt; our application we can use the &lt;code&gt;ConnectedToday&lt;/code&gt; component instead of the &lt;code&gt;Today&lt;/code&gt; component, and remove the props. &lt;/p&gt;
&lt;p&gt;To make it work we must wrap our component tree in a &lt;code&gt;Provider&lt;/code&gt;, that makes the store available to connected components. We can also drop the subscription to the store (React-redux takes care of this for us):&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;ReactDOM.render(
    &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;Provider&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;store&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;{store}&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;ConnectedToday&lt;/span&gt; /&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;Provider&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;, 
    &lt;span class=&quot;built_in&quot;&gt;document&lt;/span&gt;.getElementById(&lt;span class=&quot;string&quot;&gt;'root'&lt;/span&gt;));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we have achieved our goal. The today component is still independent of the Redux store, and we have avoided manually passing state and events up and down the component hierarchy. Here is the final code:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; React &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'react'&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; ReactDOM &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'react-dom'&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'./index.css'&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; registerServiceWorker &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'./registerServiceWorker'&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; { createStore } &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'redux'&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; { connect, Provider } &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'react-redux'&lt;/span&gt;;

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Today&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;{ day, onNext }&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;Today is {day.toString()} 
        &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;button&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;type&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;button&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;onClick&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;{onNext}&lt;/span&gt;&amp;gt;&lt;/span&gt;Next&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;button&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;;
}

&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; ConnectedToday = connect(
    &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;mapStateToProps&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;state&lt;/span&gt;) &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; state;
    }, 
    &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;mapDispatchToProps&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;dispatch&lt;/span&gt;) &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; {
            &lt;span class=&quot;attr&quot;&gt;onNext&lt;/span&gt;: &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt;=&amp;gt;&lt;/span&gt; { dispatch({&lt;span class=&quot;attr&quot;&gt;type&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;NEXT_DAY&quot;&lt;/span&gt;}); }
        };
    }
    )(Today);

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;reducer&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;state = { day: new Date(&lt;span class=&quot;number&quot;&gt;2018&lt;/span&gt;,&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;number&quot;&gt;20&lt;/span&gt;&lt;/span&gt;) }, &lt;span class=&quot;title&quot;&gt;action&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;switch&lt;/span&gt; (action.type) {
        &lt;span class=&quot;keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;NEXT_DAY&quot;&lt;/span&gt;:
            &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; currentDay = store.getState().day;
            &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; { &lt;span class=&quot;attr&quot;&gt;day&lt;/span&gt;: &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;built_in&quot;&gt;Date&lt;/span&gt;(currentDay.getTime() + (&lt;span class=&quot;number&quot;&gt;24&lt;/span&gt;*&lt;span class=&quot;number&quot;&gt;3600&lt;/span&gt;*&lt;span class=&quot;number&quot;&gt;1000&lt;/span&gt;))};
        &lt;span class=&quot;keyword&quot;&gt;default&lt;/span&gt;: &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; state;
    }
}
&lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; store = createStore(reducer);

ReactDOM.render(
    &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;Provider&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;store&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;{store}&lt;/span&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;ConnectedToday&lt;/span&gt; /&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;Provider&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;, 
    &lt;span class=&quot;built_in&quot;&gt;document&lt;/span&gt;.getElementById(&lt;span class=&quot;string&quot;&gt;'root'&lt;/span&gt;));

store.dispatch({&lt;span class=&quot;attr&quot;&gt;type&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;START&quot;&lt;/span&gt;});

registerServiceWorker();
&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id=&quot;summary&quot;&gt;Summary&lt;/h1&gt;
&lt;p&gt;When React and Redux are used together ‘React-redux’ is usually used as a convenient way to join them together. It is simply a matter of:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Wrapping the component tree in a &lt;code&gt;&amp;lt;Provider/&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Providing a &lt;code&gt;mapStateToProps&lt;/code&gt; and &lt;code&gt;mapDispatchToProps&lt;/code&gt; function for each connected component&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Next: &lt;a href=&quot;http://withouttheloop.com/articles/2018-01-08-react-6-react-router/&quot;&gt;Learning React 6 - React Router&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;get-the-code&quot;&gt;Get The Code&lt;/h2&gt;
&lt;p&gt;The code for this example is &lt;a href=&quot;https://github.com/liammclennan/today-react-app&quot;&gt;on Github&lt;/a&gt;. You can access the code as it was at the completion of this step by cloning the repository and checking out the tag that corresponds to this post. &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-bash&quot;&gt;git &lt;span class=&quot;built_in&quot;&gt;clone&lt;/span&gt; https://github.com/liammclennan/today-react-app.git
git checkout react-5
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or browse at &lt;a href=&quot;https://github.com/liammclennan/today-react-app/tree/18a03e73197b15eef0746a01fdd111942ff1a2d3&quot;&gt;https://github.com/liammclennan/today-react-app/tree/18a03e73197b15eef0746a01fdd111942ff1a2d3&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Learning React 3 - Data out with props</title>
      <link>http://withouttheloop.com/articles/2018-01-03-react-3-data-out/</link>
      <pubDate>Wed, 03 Jan 2018 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2018-01-03-react-3-data-out/</guid>
      <author></author>
      <description>&lt;p&gt;&lt;a href=&quot;http://withouttheloop.com/articles/2018-01-03-react-2-props/&quot;&gt;Learing React 2 - Data in with props&lt;/a&gt; showed how to reuse a component by passing data in to that component. This post will show how to pass data back out of a component, again using props.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Data is passed out of a React component by calling functions passed in as props&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Recall our &lt;code&gt;Today&lt;/code&gt; component:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Today&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;{ day }&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;Today is {day.toString()}&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We add a button:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Today&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;{ day }&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
                Today is {day.toString()}
                &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;button&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;type&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;button&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;Next&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;button&lt;/span&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now our UI has a button. Let’s modify the usage of &lt;code&gt;Today&lt;/code&gt; to pass a function that will be called when the ‘Next’ button is clicked:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;onNext&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;built_in&quot;&gt;console&lt;/span&gt;.log(&lt;span class=&quot;string&quot;&gt;'Next!'&lt;/span&gt;);
}

ReactDOM.render(&lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;Today&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;day&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;{new&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Date&lt;/span&gt;(&lt;span class=&quot;attr&quot;&gt;2018&lt;/span&gt;, &lt;span class=&quot;attr&quot;&gt;2&lt;/span&gt;, &lt;span class=&quot;attr&quot;&gt;20&lt;/span&gt;)} &lt;span class=&quot;attr&quot;&gt;onNext&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;{onNext}&lt;/span&gt; /&amp;gt;&lt;/span&gt;, 
    document.getElementById('root'));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and connect this to the &lt;code&gt;onClick&lt;/code&gt; event of the button:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Today&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;{ day, onNext }&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;
                Today is {day.toString()}
                &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;button&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;type&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;button&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;onClick&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;{onNext}&lt;/span&gt;&amp;gt;&lt;/span&gt;Next&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;button&lt;/span&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now when the button is clicked the text ‘Next!’ is written to the console. By passing arguments to the &lt;code&gt;onNext&lt;/code&gt; function we have a mechanism for getting events and data out of our component.&lt;/p&gt;
&lt;p&gt;Now we can use the &lt;code&gt;onNext&lt;/code&gt; event to modify the &lt;code&gt;day&lt;/code&gt; value and update the UI, completing the circle of data flow.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; day = &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;built_in&quot;&gt;Date&lt;/span&gt;(&lt;span class=&quot;number&quot;&gt;2018&lt;/span&gt;,&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;,&lt;span class=&quot;number&quot;&gt;20&lt;/span&gt;);

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;onNext&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
    day = &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;built_in&quot;&gt;Date&lt;/span&gt;(day.getTime() + (&lt;span class=&quot;number&quot;&gt;24&lt;/span&gt;*&lt;span class=&quot;number&quot;&gt;3600&lt;/span&gt;*&lt;span class=&quot;number&quot;&gt;1000&lt;/span&gt;)); 
    render();
}

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;render&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
    ReactDOM.render(&lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;Today&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;day&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;{day}&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;onNext&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;{onNext}&lt;/span&gt; /&amp;gt;&lt;/span&gt;, 
        document.getElementById('root'));
}
render();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that I had to move the call to &lt;code&gt;ReactDOM.render&lt;/code&gt; into a function and call that function after updating the value of &lt;code&gt;day&lt;/code&gt;. This is because React does not automatically now that its model data has changed and it needs to re-render. &lt;/p&gt;
&lt;h1 id=&quot;summary&quot;&gt;Summary&lt;/h1&gt;
&lt;p&gt;Data is passed into a React component as a value supplied as props. Data is passed out of a React component by calling a function passed in as props. Components created in this style have a wonderful simplicity. Their interface is defined entirely by props. You should try to code all of your React components in this way. &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Next: &lt;a href=&quot;http://withouttheloop.com/articles/2018-01-05-react-4-redux/&quot;&gt;Learning React 4 - Redux&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;get-the-code&quot;&gt;Get The Code&lt;/h2&gt;
&lt;p&gt;The code for this example is &lt;a href=&quot;https://github.com/liammclennan/today-react-app&quot;&gt;on Github&lt;/a&gt;. You can access the code as it was at the completion of this step by cloning the repository and checking out the tag that corresponds to this post. &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-bash&quot;&gt;git &lt;span class=&quot;built_in&quot;&gt;clone&lt;/span&gt; https://github.com/liammclennan/today-react-app.git
git checkout react3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or browse at &lt;a href=&quot;https://github.com/liammclennan/today-react-app/tree/b59c3dbeb3597395d6c0c7d9b2831bf3999e870a&quot;&gt;https://github.com/liammclennan/today-react-app/tree/b59c3dbeb3597395d6c0c7d9b2831bf3999e870a&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Learning React 2 - Data in with props</title>
      <link>http://withouttheloop.com/articles/2018-01-03-react-2-props/</link>
      <pubDate>Tue, 02 Jan 2018 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2018-01-03-react-2-props/</guid>
      <author></author>
      <description>&lt;p&gt;In &lt;a href=&quot;http://withouttheloop.com/articles/2018-01-03-react-1/&quot;&gt;Learning React 1 - A first component&lt;/a&gt; I showed how to bootstrap a React application and implement a simple component that displays the current date.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;Today&lt;/code&gt; component is highly specialized. It displays the current date, but can’t do anything else. Often we would like to generalize a component to increase the opportunities for reuse. This requires the capability to pass data into a React component. &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Data is passed to a React component using ‘props’&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Props are specified when the component is used, as attributes. We can pass a date to the &lt;code&gt;Today&lt;/code&gt; component like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;ReactDOM.render(&lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;Today&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;day&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;{new&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Date&lt;/span&gt;(&lt;span class=&quot;attr&quot;&gt;2018&lt;/span&gt;, &lt;span class=&quot;attr&quot;&gt;2&lt;/span&gt;, &lt;span class=&quot;attr&quot;&gt;20&lt;/span&gt;)} /&amp;gt;&lt;/span&gt;, document.getElementById('root'));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then in the &lt;code&gt;Today&lt;/code&gt; component this value is available on the props object passed to the function:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Today&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;props&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;Today is {props.day.toString()}&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now the output is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Today is Tue Mar 20 2018 00:00:00 GMT+1000 (AEST)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you are wondering why it is Mar 20 and not Feb 20, it is because &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date&quot;&gt;JavaScript uses 0 based indexing for months&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;When reading other peoples React code you will often see &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Object_destructuring&quot;&gt;Object destructuring&lt;/a&gt; used to show what is expected in &lt;code&gt;props&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Today&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;{ day }&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;Today is {day.toString()}&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is a purely syntactical change. The program behaves exactly the same as before. &lt;/p&gt;
&lt;h1 id=&quot;summary&quot;&gt;Summary&lt;/h1&gt;
&lt;p&gt;By introducing &lt;code&gt;props&lt;/code&gt; to our React component we have generalized it to work with any date. This is the mechanism by which data is passed to React components, and passed down a hierarchy of React components. &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Next: &lt;a href=&quot;http://withouttheloop.com/articles/2018-01-03-react-3-data-out/&quot;&gt;Learning React 3 - Data out with props&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;get-the-code&quot;&gt;Get The Code&lt;/h2&gt;
&lt;p&gt;The code for this example is &lt;a href=&quot;https://github.com/liammclennan/today-react-app&quot;&gt;on Github&lt;/a&gt;. You can access the code as it was at the completion of this step by cloning the repository and checking out the tag that corresponds to this post. &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-bash&quot;&gt;git &lt;span class=&quot;built_in&quot;&gt;clone&lt;/span&gt; https://github.com/liammclennan/today-react-app.git
git checkout react2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or browse at &lt;a href=&quot;https://github.com/liammclennan/today-react-app/tree/6c4a389b57211a3c894db10c34f444d37e6b3c69&quot;&gt;https://github.com/liammclennan/today-react-app/tree/6c4a389b57211a3c894db10c34f444d37e6b3c69&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Learning React 1 - A first component</title>
      <link>http://withouttheloop.com/articles/2018-01-03-react-1/</link>
      <pubDate>Mon, 01 Jan 2018 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2018-01-03-react-1/</guid>
      <author></author>
      <description>&lt;p&gt;While doing some maintenance on my Pluralsight course, &lt;a href=&quot;https://www.pluralsight.com/courses/react-fundamentals&quot;&gt;React Fundamentals&lt;/a&gt; I have been thinking about how to teach good front-end development skills. At first I was puzzled as to why people struggled, when React is fundamentally very simple. &lt;/p&gt;
&lt;p&gt;To build a complete application, React is not enough. You have to add supporting tools to help with routing, bundling, state management and other services not provided by React itself. These additional tools add a lot of complexity, and they are presented to learners in their final, complete and extremely confusing way. Between the React ‘Hello World’ demo and a completed, ready-for-production application there is a chasm that seems to be ignored by the standard documentation. &lt;/p&gt;
&lt;p&gt;In this post, and more to follow I intend to show how a React application is built up from first principles. I will try to add complexity gradually and explain why the different pieces are necessary. Let’s begin with a first component.&lt;/p&gt;
&lt;h1 id=&quot;a-first-component&quot;&gt;A First Component&lt;/h1&gt;
&lt;p&gt;Let us create a React component that displays today’s date. We will use &lt;a href=&quot;https://github.com/facebookincubator/create-react-app&quot;&gt;create-react-app&lt;/a&gt; because it is a good starting point and a defacto standard.&lt;/p&gt;
&lt;p&gt;First, install create-react-app if you don’t have it already:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; npm install -g create-react-app
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then scaffold a new application:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; create-react-app a-first-component
&amp;gt; cd a-first-component
&amp;gt; npm start
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You will see the default application scaffold rendered in your browser. &lt;/p&gt;
&lt;p&gt;Open the file &lt;code&gt;src/index.js&lt;/code&gt;. It should look like:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; React &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'react'&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; ReactDOM &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'react-dom'&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'./index.css'&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; App &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'./App'&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; registerServiceWorker &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'./registerServiceWorker'&lt;/span&gt;;

ReactDOM.render(&lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;App&lt;/span&gt; /&amp;gt;&lt;/span&gt;, document.getElementById('root'));
registerServiceWorker();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A React component is just a function that returns some HTML (technically JSX which is a HTML-like markup language that is compiled to JavaScript). A React component that shows the current date is:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Today&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;Today is {new Date().toString()}&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Putting that into &lt;code&gt;src/index.js&lt;/code&gt; and rendering it instead of &lt;code&gt;&amp;lt;App /&amp;gt;&lt;/code&gt; we now have &lt;code&gt;src/index.js&lt;/code&gt; containing:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;comment&quot;&gt;// ... imports as above&lt;/span&gt;

&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Today&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;Today is {new Date().toString()}&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;div&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;;
}

ReactDOM.render(&lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;Today&lt;/span&gt; /&amp;gt;&lt;/span&gt;, document.getElementById('root'));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the browser renders our app as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Today is Wed Jan 03 2018 15:16:43 GMT+1000 (AEST)
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&quot;summary&quot;&gt;Summary&lt;/h1&gt;
&lt;p&gt;Creating a React app with the most basic component I can think of is simple. In future posts I will build on this on step at a time until we have a viable application.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Next: &lt;a href=&quot;http://withouttheloop.com/articles/2018-01-03-react-2-props/&quot;&gt;Learning React 2 - Data in with props&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
</description>
    </item>
    <item>
      <title>Goals, Strategic Planning and Product Road Maps</title>
      <link>http://withouttheloop.com/articles/2017-11-16-product-planning/</link>
      <pubDate>Thu, 16 Nov 2017 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2017-11-16-product-planning/</guid>
      <author></author>
      <description>&lt;p&gt;The product development process, left to its own devices, does not proceed with order and efficiency to the ideal output. Without constant guidance, and vigilance, progress will be retarded by individual interests, disproportionate reactions, responding to stakeholder requests, scope creep, over-engineering and decisions made without all of the necessary context.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Successful teams optimize their path to agreed goals by minimizing waste. Build only what is absolutely necessary, when it is absolutely necessary.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Product delivery management happens at two levels. The low-level management of planning the next sprint has been well understood, but focuses on activity over outcome. The higher-level view of why we are doing what we are doing is typically neglected and defaults to a shopping list of features that someone high in the org chart thinks are desirable. &lt;/p&gt;
&lt;p&gt;At &lt;a href=&quot;https://startsat60.com/&quot;&gt;Starts at 60&lt;/a&gt;, we have developed a simple and effective process with three principal steps:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#identify-goals&quot;&gt;Identify the goals&lt;/a&gt; that the product serves. All activity must be mapped to at least one goal.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#derive-strategic-initiatives-from-the-goals&quot;&gt;Use Impact Mapping to derive strategic initiatives from the goals&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#create-a-roadmap&quot;&gt;Organise the strategic initiatives into a highly-visible, living roadmap that forces prioritization&lt;/a&gt;. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2017-11-16-product-planning/Redacted.jpg&quot; alt=&quot;Roadmaps&quot;&gt;&lt;/p&gt;
&lt;h1 id=&quot;identify-goals&quot;&gt;Identify Goals&lt;/h1&gt;
&lt;p&gt;The first and most important step is to pick your goals. A good team working to clear goals will get buy without anything else. Choosing goals sounds easy but it is not. &lt;a href=&quot;https://withouttheloop.com/articles/2016-08-24-goaltree/&quot;&gt;The Goal Tree&lt;/a&gt; describes a process for getting to real business goals. &lt;/p&gt;
&lt;h2 id=&quot;guidelines-for-goal-selection&quot;&gt;Guidelines for Goal Selection&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Keep the list of goals small. Goals will tend to conflict with each other and if the set of possible conflicts is large things become unmanageable. We work to 4 goals and I think that is about the practical limit. The following graph shows how quickly the number of potential conflicts increases as the number of goals increases.
 &lt;img src=&quot;/articles/2017-11-16-product-planning/conflicts.png&quot; alt=&quot;Possible conflicts to number of goals&quot;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Goals will often be financial and there is nothing wrong with that. &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Beware of features expressed as a goal. If a feature is suggested ask &lt;em&gt;why&lt;/em&gt; that feature is desirable. Unearthing the goal gives the team the opportunity to replace the selected feature with a better one. &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Goals should be SMART (specific, measurable, achievable, relevant and time-bound). When the goal is defined also define when the metric will be measured, how it will be measured and what the expected value should be. &lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id=&quot;derive-strategic-initiatives-from-the-goals&quot;&gt;Derive Strategic Initiatives from the Goals&lt;/h1&gt;
&lt;p&gt;Goals define where you want to go. &lt;a href=&quot;https://www.impactmapping.org/&quot;&gt;Impact Mapping&lt;/a&gt; is a collaborative, strategic planning technique that helps a team to determine which initiatives will have the most impact, as defined by the agreed goals.&lt;/p&gt;
&lt;p&gt;The impact mapping process is:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Identify the actors who can help or hinder our progress to the goals.&lt;/li&gt;
&lt;li&gt;For each actor, list the behaviour change we would like them to make.&lt;/li&gt;
&lt;li&gt;Brainstorm initiatives that could be undertaken to achieve the desired behaviour changes.&lt;/li&gt;
&lt;li&gt;Choose which of the initiatives identified are the most appropriate to pursue. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Much of the impact mapping process relies on &lt;em&gt;assumptions&lt;/em&gt; that should be made explicit and documented. The impact map is a living document that must be updated as circumstances change or assumptions are dis-proven. &lt;/p&gt;
&lt;p&gt;The output of the impact mapping process is the set of initiatives most likely (according to the information on hand) to result in hitting our goals.&lt;/p&gt;
&lt;h1 id=&quot;create-a-roadmap&quot;&gt;Create a Roadmap&lt;/h1&gt;
&lt;p&gt;Once we know the things we should do we need to prioritize them into a roadmap. At &lt;a href=&quot;https://startsat60.com/&quot;&gt;Starts at 60&lt;/a&gt; we have two products: a &lt;a href=&quot;https://startsat60.com/&quot;&gt;media site&lt;/a&gt; and a &lt;a href=&quot;https://travel.startsat60.com/&quot;&gt;travel site&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://startsat60.com/&quot;&gt;&lt;img src=&quot;/articles/2017-11-16-product-planning/sas.png&quot; alt=&quot;Starts at 60&quot;&gt;&lt;/a&gt;
&lt;em&gt;Starts at 60&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://travel.startsat60.com/&quot;&gt;&lt;img src=&quot;/articles/2017-11-16-product-planning/tas.png&quot; alt=&quot;Travel at 60&quot;&gt;&lt;/a&gt;
&lt;em&gt;Travel at 60&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The technology team has commandeered a wall to display a simple roadmap. Each column is a product (TAS &amp;amp; SAS). Planned initiatives are represented by coloured cards and ordered by priority. The top row shows which initiatives are currently being developed (in progress). Each in progress initiative has a headshot of the person responsible for delivery attached.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2017-11-16-product-planning/Redacted.jpg&quot; alt=&quot;Roadmaps&quot;&gt;&lt;/p&gt;
&lt;p&gt;This information was originally captured in a Trello board, but it did not work. People only engage with Trello if they choose to pull the information (by going to the Trello board). The advantage of a large, wall display is that it pushes the information to stakeholders, whether they want it or not ;)&lt;/p&gt;
&lt;p&gt;In a startup things can change quickly. The huge-visible-roadmap is a great tool to at least document what the current plan is. Keep a stack of cards and some markers handy.&lt;/p&gt;
&lt;h1 id=&quot;dealing-with-great-new-ideas&quot;&gt;Dealing with Great New Ideas&lt;/h1&gt;
&lt;p&gt;The curse of any roadmap, or any product planning, is the “great new idea”. When a great new idea is presented to the delivery team the default assumption is always that it will happen, and that it will not affect the delivery of all the initiatives already in progress. The process detailed above provides tools for dealing with this situation. &lt;/p&gt;
&lt;p&gt;Firstly, the great new idea must be worked into the Impact Map, so that it can be mapped to the agreed business goals. This will weed out those great ideas that won’t contribute to the goals. &lt;/p&gt;
&lt;p&gt;Assuming the “great new idea” is in fact going to have a significant impact then the roadmap wall forces the decision about where to put the “great new idea”. Does it go at the top, displacing all other initiatives? Or does it go at the end of the line? Any choice is acceptable, the import thing is that a choice is made.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Hugo is not breathing. Come home quick.</title>
      <link>http://withouttheloop.com/articles/2017-08-31-terror-call/</link>
      <pubDate>Thu, 31  Aug 2017 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2017-08-31-terror-call/</guid>
      <author></author>
      <description>&lt;p&gt;It was towards the end of Monday morning peak hour. I had just arrived at the train station on my way to work when my phone rang.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Should I do CPR?&lt;/p&gt;
&lt;p&gt;Hugo’s not breathing. &lt;/p&gt;
&lt;p&gt;Come home quick.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That was it verbatim. I did not get a word in. The caller was my wife. Hugo is our one year old child. &lt;/p&gt;
&lt;p&gt;I took my wife’s suggestion and began to run home (I walk to the train station). My backpack full of computers was slowing me so I paused on my way paste a large tree, took my car keys out of the bag, and then tossed the rest as deep as I could under the tree’s folliage. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2017-08-31-terror-call/tree.jpg&quot; alt=&quot;tree&quot;&gt;&lt;/p&gt;
&lt;p&gt;Thus unencumbered, my progress home was more rapid. I was terrified, thinking that Hugo was dead or dying.&lt;/p&gt;
&lt;p&gt;I passed one block, then a second, before I saw my neighbour’s SUV screeching to a halt, on the wrong side of the road, across an intersection. I jumped in the passenger seat and barely had time to fail to close the door properly before we were off with a tyre howl and a petrol roar. &lt;/p&gt;
&lt;p&gt;When I got inside Hugo was on my bed, lying on his side, moving in and out conciousness. His breathing was faint but detectable. His seizure had lasted five minutes and included two minutes without breathing. The ambulance had been called so we watched him and waited. After forty minutes I started to worry that the ambulance service had somehow lost track of us, so I called again. The lady I spoke to assured me that the ambulance would be there as soon as possible and asked me a silly question, “is he breathing?”. After forty minutes without breathing they could have told the ambulance to slow down. &lt;/p&gt;
&lt;p&gt;One hour and ten minutes after we called, the ambulance arrived. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2017-08-31-terror-call/ambulance.jpg&quot; alt=&quot;Ambulance&quot;&gt;&lt;/p&gt;
&lt;p&gt;The paramedics were kind and helpful. They took my wife and child to the new Children’s Hospital. I followed in the car. The paramedics told me it would take a while to get processed through emergency so I stopped by the train station and retrieved my bag from under the tree. &lt;/p&gt;
&lt;p&gt;We spent most of the day in the Emergency Department with a grumpy toddler. He alternated between sleep and extreme irritability. I am told that following his seizure he would have a headache and a metallic taste in his mouth. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2017-08-31-terror-call/h.jpg&quot; alt=&quot;Hugo in hospital&quot;&gt;&lt;/p&gt;
&lt;p&gt;Eventually we were released with a diagnosis of “febrile convulsion”, a condition associated with rapid change in fever temperature in young children. This was odd because Hugo did not have a temperature when he had his seizure.&lt;/p&gt;
&lt;p&gt;The next day it was my turn. I was carrying Hugo because he would scream if I put him down when my daughter called me to the bathroom for some toilet emergency. I put Hugo down and noticed it was odd that he refused to stand on his feet. I lowered him into a sitting position and went to help my daughter. In the corner of my eye I saw Hugo gently lie down, extend his arms like a cartoon Egyptian mummy and begin to convulse. It was like &lt;a href=&quot;https://www.youtube.com/watch?v=7rK6-JpxR7s&quot;&gt;this&lt;/a&gt; youtube video (or &lt;a href=&quot;https://www.youtube.com/watch?v=aIcYPQsnXV4&quot;&gt;this one&lt;/a&gt;), but with his eyes rolled back so I only saw the whites. That lasted about a minute followed by a period of eerie stillness with Hugo completely still between breaths 20 seconds apart. &lt;/p&gt;
&lt;p&gt;We went back to the hospital and again we were released after a few hours. It is easy to diagnose a seizure. It is much harder to diagnose the cause so Hugo will be having some tests when we can get him booked in. Here he is the day after his second seizure, starting to feel a little better, and demonstrating static electricity. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2017-08-31-terror-call/crazy.jpg&quot; alt=&quot;Hugo on trampoline&quot;&gt;&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Komo Passwordless Authentication - Simplified Onboarding</title>
      <link>http://withouttheloop.com/articles/2017-08-01-simplified-onboarding/</link>
      <pubDate>Tue, 01  Aug 2017 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2017-08-01-simplified-onboarding/</guid>
      <author></author>
      <description>&lt;p&gt;&lt;a href=&quot;https://komo.tech/&quot;&gt;Komo&lt;/a&gt; was already a secure and easy way to add passwordless authentication to web applications. However, it is now even easier. &lt;/p&gt;
&lt;p&gt;The process of adding Komo passwordless authentication to a web applications has been reduced to two steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Add the form code to your application&lt;/p&gt;
&lt;p&gt; The Komo dashboard shows the source code for the required login form. Simply copy and paste the form code into your application where you would like your login form to appear.&lt;/p&gt;
&lt;p&gt; &lt;img src=&quot;/articles/2017-08-01-simplified-onboarding/form.png&quot; alt=&quot;Login form code&quot;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement a webhook&lt;/p&gt;
&lt;p&gt; Your webhook endpoint is sent an authentication token. Post the token to &lt;code&gt;https://komo.tech/verify&lt;/code&gt;. The response will look something like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; {
     &amp;quot;isValid&amp;quot;: true,
     &amp;quot;email&amp;quot;: &amp;quot;john@adomain.com&amp;quot;,
     &amp;quot;message&amp;quot;: &amp;quot;&amp;quot;
 }
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt; See the &lt;a href=&quot;https://app.swaggerhub.com/apis/liammclennan/Komo/1.0.0&quot;&gt;full API documentation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt; If &lt;code&gt;isValid&lt;/code&gt; is true, then you have verified that the current user has access to the email address in the response (&lt;code&gt;john@adomain.com&lt;/code&gt; in the example above) and may login the user using your web framework. &lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;See &lt;a href=&quot;https://glitch.com/edit/#!/immense-sneeze?path=server.js:22:11&quot;&gt;https://glitch.com/edit/#!/immense-sneeze?path=server.js:22:11&lt;/a&gt; for a full working example.&lt;/p&gt;
&lt;p&gt;(Note: It is also possible to directly verify the &lt;a href=&quot;https://en.wikipedia.org/wiki/JSON_Web_Token&quot;&gt;JWT token&lt;/a&gt; if you wish to avoid the network request to &lt;code&gt;https://komo.tech/verify&lt;/code&gt;.)&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Nginx Lets Encrypt SSL Reverse Proxy for Azure Web Apps</title>
      <link>http://withouttheloop.com/articles/2017-07-23-nginx-letsencrypt-azure-web-app/</link>
      <pubDate>Sun, 23 Jul 2017 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2017-07-23-nginx-letsencrypt-azure-web-app/</guid>
      <author></author>
      <description>&lt;p&gt;In 2017, deploying a new web site realistically means having a custom domain name and secure connection (SSL). Unfortunately for Microsoft Azure users custom domains and SSL are two of the segmentation triggers that push you out of the free tier and into higher priced plans. &lt;/p&gt;
&lt;p&gt;Without a custom domain name or SSL I can host my application for free. Adding a custom domain name will cost $15/month extra for hosting (plus the cost of the domain and DNS). SSL support pushes me to $54/month for very similar hardware (1 CPU, 1.75GB RAM). &lt;/p&gt;
&lt;h1 id=&quot;my-situation&quot;&gt;My Situation&lt;/h1&gt;
&lt;p&gt;I wish to deploy a .net application written in F#. At the time of writing deploying F# to linux is not a good option as I am not prepared to waste huge amounts of time. Therefore, the simplest hosting option is to use an Azure Web App. I can deploy by pushing to a git branch and the hosting will just work for a .net application. &lt;/p&gt;
&lt;p&gt;To avoid the costs described above in configuring Azure for a custom domain and SSL I thought I’d try using an existing nginx server as a reverse proxy.&lt;/p&gt;
&lt;h1 id=&quot;my-solution&quot;&gt;My Solution&lt;/h1&gt;
&lt;h2 id=&quot;dns&quot;&gt;DNS&lt;/h2&gt;
&lt;p&gt;Firstly, I purchased a domain name (&lt;code&gt;komo.tech&lt;/code&gt;) and configured the DNS to point the domain name to a Digital Ocean Linux server running nginx. &lt;/p&gt;
&lt;h2 id=&quot;nginx&quot;&gt;nginx&lt;/h2&gt;
&lt;p&gt;Next, I added a new site to the nginx configuration. The site won’t actually host any local content it simply receives requests and forwards them on to the Azure Web App, thus, it is a reverse proxy. &lt;/p&gt;
&lt;p&gt;In the nginx configuration I specified the underlying host that nginx will be proxying for. &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;upstream app_komo {                           
    server simpleauth1.azurewebsites.net:443; 
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;simpleauth1.azurewebsites.net&lt;/code&gt; is the domain name of the Azure Web App. &lt;code&gt;443&lt;/code&gt; is the port to use because I want a secure connection. Later I will specify the protocol.&lt;/p&gt;
&lt;p&gt;Next, I created a &lt;code&gt;location&lt;/code&gt;, telling nginx to proxy all requests, from the root (&lt;code&gt;/&lt;/code&gt;) to the previously declared upstream (the Azure Web App):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;location / {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host simpleauth1.azurewebsites.net;
    proxy_set_header X-Forwarded-Proto $scheme;
    #proxy_set_header X-NginX-Proxy true;

    proxy_ssl_session_reuse off;
    proxy_pass https://app_komo/;
    proxy_redirect off;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;At first my configuration did not work. I got an error from Azure about the site not existing. This was happening because the forwarded requests were arriving at Azure as requests for &lt;code&gt;komo.tech&lt;/code&gt;, a domain that Azure knows nothing about. The solution was to add the line &lt;code&gt;proxy_set_header Host simpleauth1.azurewebsites.net;&lt;/code&gt;. This means that when a request passes through the reverse proxy the host is changed from &lt;code&gt;komo.tech&lt;/code&gt; to &lt;code&gt;simpleauth1.azurewebsites.net&lt;/code&gt;, a domain that Azure knows how to handle. &lt;/p&gt;
&lt;h2 id=&quot;https-ssl-with-let-s-encrypt&quot;&gt;https (SSL) with Let’s Encrypt&lt;/h2&gt;
&lt;p&gt;The final step was to secure the connection between user’s browsers and the reverse proxy with SSL. To do this I used the free service &lt;a href=&quot;https://letsencrypt.org/&quot;&gt;Let’s Encrypt&lt;/a&gt;. For my setup (nginx on Ubuntu 14.04) the steps were:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Install certbot with apt-get&lt;/li&gt;
&lt;li&gt;Run certbot &lt;code&gt;certbox --nginx&lt;/code&gt; and follow the prompts to specify which sites require certificates.&lt;/li&gt;
&lt;li&gt;Add nginx configuration to redirect http traffic to https &lt;pre&gt;&lt;code&gt; server {                                       
     listen 80;                                 
     server_name komo.tech;                     
     return 301 https://$host$request_uri;      
 }
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;Restart nginx &lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;It is not the ultimate configuration by an means, but proxying via nginx is simple and effective. It also saved me some hosting cost. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>Authentication for the modern web</title>
      <link>http://withouttheloop.com/articles/2017-07-21-passwordless/</link>
      <pubDate>Fri, 21 Jul 2017 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2017-07-21-passwordless/</guid>
      <author></author>
      <description>&lt;p&gt;&lt;img src=&quot;/articles/2017-07-21-passwordless/parc.jpg&quot; alt=&quot;Xerox PARC&quot;&gt;&lt;/p&gt;
&lt;p&gt;April 1971, here at Xerox PARC, the Austrian-born computer scientist Hanz Scmitfilgerz connects to the latest in mainframe computer technology. &lt;/p&gt;
&lt;p&gt;To establish his identity to the satisfaction of the computer he authenticates by providing a combination of: a username that identifies him, and a password that only he knows. His password is a unique, long, high-entropy string of characters known only to Dr Scmitfilgerz, and stored only in his memory. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2017-07-21-passwordless/mainframe.jpg&quot; alt=&quot;mainframe&quot;&gt;&lt;/p&gt;
&lt;p&gt;That pleasent spring morning of 1971 is the last time that password authentication worked well for anyone. &lt;/p&gt;
&lt;h1 id=&quot;why-passwords-are-not-secure&quot;&gt;Why passwords are not secure&lt;/h1&gt;
&lt;p&gt;Real users are not like Dr Scmitfilgerz. They can’t be in an age where the &lt;em&gt;average&lt;/em&gt; person has dozens if not hundreds of online user accounts. It is beyond our capability to remember all those passwords so, people typically &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;reuse the same password or &lt;/li&gt;
&lt;li&gt;store their passwords somewhere&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Reusing passwords is perhaps the most significant password security problem today. At regular intervals a large password database is compromised and released on the internet (recent examples include linkedin, adobe, sony). Criminals then take those public credentials and attempt, often successfully, to access other services such as email or online banking. &lt;/p&gt;
&lt;p&gt;Storing passwords can be OK, but it does introduce a massive vulnerability. If the mechanism used to store your passwords is compromised then all of your accounts are compromised. An incident like this is unlikely but catastrophic. &lt;/p&gt;
&lt;h1 id=&quot;why-passwords-are-a-bad-user-experience&quot;&gt;Why passwords are a bad user experience&lt;/h1&gt;
&lt;p&gt;IT professionals often solve the password proliferation and storage problem with an online product like Lastpass or 1Password. For the typicall consumer internet user these products are confusing and too hard to use. I will never be able to train my parents to use a password manager. &lt;/p&gt;
&lt;p&gt;Assuming we do not reuse passwords (for the reason detailed above) then each time I want to access a new service I have the additional burden of coming up with a new password, and remebering it somehow. I have to fight my way through the services password complexity tests (your pasword must include lower case, uppercase, numeric characters and a gang sign). &lt;/p&gt;
&lt;p&gt;It is too hard. Non-technical people don’t do it. They reuse the same awful password (like ‘password’) or variations of the same password.&lt;/p&gt;
&lt;h1 id=&quot;modern-authentication-authentication-2-0-&quot;&gt;Modern authentication (Authentication 2.0)&lt;/h1&gt;
&lt;p&gt;Recognizing the limitation of password-based authentication, some organisations like &lt;a href=&quot;https://blog.medium.com/signing-in-to-medium-by-email-aacc21134fcd&quot;&gt;medium&lt;/a&gt; and &lt;a href=&quot;https://slack.com/&quot;&gt;Slack&lt;/a&gt; are abandoning passwords in favour of email-based authentication. Users are authenticated by proving they have access to an email inbox. In practice, the workflow is:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A user visits a site they wish to login to&lt;/li&gt;
&lt;li&gt;They enter their email address&lt;/li&gt;
&lt;li&gt;The site sends a special “magic link” to their email address&lt;/li&gt;
&lt;li&gt;The user accesses their email, clicks on the “magic link” and is authenticated&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This workflow is simple and fast. For most users it is vastly more secure than a password based system and easier to use. For website owners it &lt;a href=&quot;https://komo.tech/increase-registrations&quot;&gt;results in more signups&lt;/a&gt; and less password related support. &lt;/p&gt;
&lt;h1 id=&quot;introducing-komo-https-komo-tech-&quot;&gt;Introducing &lt;a href=&quot;https://komo.tech&quot;&gt;Komo&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;A number of providers offer a hosted email authentication service that website owners can use to add passwordless authentication to their site. I’ve built another (&lt;a href=&quot;https://komo.tech&quot;&gt;Komo&lt;/a&gt;) that offers a slightly different service.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;It is focused purely on passwordless authentication, without all the expensive add-ons that usually comes with Identity and Access Management (IAM) SaaS providers. &lt;/li&gt;
&lt;li&gt;The core functionality of passwordless email authentication is, and always will be, completely free (with reasonable volume limits).&lt;/li&gt;
&lt;li&gt;Komo is designed to integrate properly with your web framework’s authentication support. It is not an awkward JavaScript bolt-on. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;a href=&quot;https://komo.tech&quot;&gt;&lt;img src=&quot;/articles/2017-07-21-passwordless/komo.png&quot; alt=&quot;Komo passwordless authentication&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Komo is available and ready to provide email authentication for your site. Just &lt;a href=&quot;https://komo.tech/signup?returnUrl=/dashboard&quot;&gt;sign up&lt;/a&gt;. The Komo login process uses Komo for authentication (of course). &lt;/p&gt;
&lt;p&gt;You can also try a &lt;a href=&quot;https://immense-sneeze.glitch.me/&quot;&gt;a demo site&lt;/a&gt; that uses Komo for login, and &lt;a href=&quot;https://glitch.com/edit/#!/immense-sneeze&quot;&gt;browse the source&lt;/a&gt; to see how it is implemented.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Reactpress - React templates and universal / isomorphic rendering for Wordpress</title>
      <link>http://withouttheloop.com/articles/2017-06-01-react-wordpress-themes/</link>
      <pubDate>Thu, 01 Jun 2017 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2017-06-01-react-wordpress-themes/</guid>
      <author></author>
      <description>&lt;p&gt;&lt;a href=&quot;https://github.com/liammclennan/Reactpress&quot;&gt;https://github.com/liammclennan/Reactpress&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;what&quot;&gt;What&lt;/h2&gt;
&lt;p&gt;ReactPress is a standalone server that pulls content from the wordpress API and renders views using React.js. The views are rendered and returned from the server and then the React components are re-attached in the browser. This provides the benefits of server rendering (speed and SEO) with the benefits of React in the browser (interactivity). It also allows Wordpress to be used for content creation without requiring Wordpress or php for rendering. &lt;/p&gt;
&lt;h2 id=&quot;why-&quot;&gt;Why?&lt;/h2&gt;
&lt;p&gt;I’m really not sure. Because we can? Not because it is easy, but because it is hard?&lt;/p&gt;
&lt;h2 id=&quot;get-started&quot;&gt;Get Started&lt;/h2&gt;
&lt;p&gt;Create a wordpress instance, standalone or on &lt;a href=&quot;https://wordpress.com&quot;&gt;wordpress.com&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Implement the &lt;a href=&quot;https://codex.wordpress.org/Theme_Development#Template_Files_List&quot;&gt;wordpress template files&lt;/a&gt; as React components. E.g. to render a post create a file &lt;code&gt;Single.tsx&lt;/code&gt; with content like:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; * &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; React &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;react&quot;&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; * &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; ReactDOM &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;react-dom&quot;&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; { Menu } &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;./Menu&quot;&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; {Timer} &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;./supporting/Timer&quot;&lt;/span&gt;;

&lt;span class=&quot;keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;render&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;getPost, getCategories&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;built_in&quot;&gt;Promise&lt;/span&gt;.all([getPost(), getCategories()])
        .then(&lt;span class=&quot;function&quot;&gt;(&lt;span class=&quot;params&quot;&gt;[post, categories]&lt;/span&gt;) =&amp;gt;&lt;/span&gt; {
            &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; {
                &lt;span class=&quot;attr&quot;&gt;component&lt;/span&gt;: Single,
                &lt;span class=&quot;attr&quot;&gt;props&lt;/span&gt;: { post, categories }
            };
        });
}

&lt;span class=&quot;keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Single&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;{post, categories}&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; (&amp;lt;div&amp;gt;
        &amp;lt;Menu model={categories} /&amp;gt;
        &amp;lt;Post model={post} /&amp;gt;
        &amp;lt;Timer /&amp;gt;
    &amp;lt;/div&amp;gt;);
}

export function Post(props) {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1 dangerouslySetInnerHTML={{__html: props.model.title.rendered}}&amp;gt;&amp;lt;/h1&amp;gt;
      &amp;lt;p&amp;gt;{props.model.date}&amp;lt;/p&amp;gt;
      &amp;lt;p dangerouslySetInnerHTML={{__html: props.model.excerpt.rendered}} /&amp;gt;
      &amp;lt;div dangerouslySetInnerHTML={{__html: props.model.content.rendered}} /&amp;gt;
    &amp;lt;/div&amp;gt;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is regular React code with no restrictions, other than being able to run in the browser. &lt;/p&gt;
&lt;p&gt;&lt;code&gt;getPost&lt;/code&gt; and &lt;code&gt;getCategories&lt;/code&gt; functions provide access to wordpress data. &lt;code&gt;getPost&lt;/code&gt; returns data for the post identified by the posts slug, extracted from the url. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>Making a Single Page Application</title>
      <link>http://withouttheloop.com/articles/2017-02-05-making-a-single-page-app/</link>
      <pubDate>Sun, 05 Feb 2017 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2017-02-05-making-a-single-page-app/</guid>
      <author></author>
      <description>&lt;h1 id=&quot;should-i-&quot;&gt;Should I?&lt;/h1&gt;
&lt;p&gt;Conventional wisdom holds that in 2017 all applications are best implemented as single page applications (SPAs). Having seen the transformation from server-side MVC to client-side single page applications the cynical part of me wonders if the preference for SPAs has more to do with developer career planning that technical merits. &lt;/p&gt;
&lt;p&gt;Some hard truths. SPAs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;are more complicated &lt;/li&gt;
&lt;li&gt;take longer to build&lt;/li&gt;
&lt;li&gt;are much slower to render database content &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So, for me, applications that primarily publish content and have simple user interaction are much better as server side MVC applications. Applications requiring rich user interaction need to be SPAs. Everything else is somewhere in the middle. &lt;/p&gt;
&lt;h2 id=&quot;get-started-with-a-starter-kit&quot;&gt;Get Started With A Starter Kit&lt;/h2&gt;
&lt;p&gt;There are many prebuilt application starter kits available for building SPAs. They typically solve the modern nightmare of configuring a JavaScript build process and maybe throw in a few other goodies. &lt;/p&gt;
&lt;p&gt;For Angular there is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/angular/quickstart&quot;&gt;the Angular Quickstart Seed&lt;/a&gt;. This an official Angular (Google) published quickstart repository. &lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/angular/angular-cli&quot;&gt;Angular cli&lt;/a&gt; includes a way to setup new projects. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For React we have:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/mozilla/neo&quot;&gt;Mozilla Neo&lt;/a&gt;, a fully featured and opinionated application generator.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/facebookincubator/create-react-app&quot;&gt;create-react-app&lt;/a&gt; the facebook idea of what a starter kit should be. Neat, but extremely minimal.   &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are hundreds of others available. Unfortunately, evaluating them is more difficult than you might think. The relative strenghts and weaknesses of these systems often don’t present themself until a project is well underway, or when the developer decides that it is necessary to deviate in some way from the choices made by their chosen starter kit. &lt;/p&gt;
&lt;p&gt;I like React, and I think there is a lot of benefit in choosing the “official” starter kit creted and maintained by Facebook and the React team. The trouble with create-react-app is that it includes the absolute minimum required to make React work, which is not enough to build an application. For example, there is no routing, validation or application state management included. &lt;/p&gt;
&lt;p&gt;The best of both worlds then is to chose a minimal starter kit, upgrade it to include your favourite tools and match your preferences, then publish that as your own custom starter kit. This lets consumers use your starter kit as a single dependency in their applications, just as create-react-app does. It also means that starter kits are composable, and someone could further customise your starter kit into their own starter kit. &lt;/p&gt;
&lt;h2 id=&quot;what-i-did-to-create-react-app&quot;&gt;What I Did To create-react-app&lt;/h2&gt;
&lt;p&gt;I used create-react-app as the basis for my starter kit. Then proceeded to add react-router for routing, bootstrap for styles and redux for state management. &lt;/p&gt;
&lt;h3 id=&quot;adding-react-router&quot;&gt;Adding React router&lt;/h3&gt;
&lt;p&gt;The easy and obvious start is to install react-router:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm install react-router --save
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The fundamental abstraction of a web application is the resource (or page) identified by a URL. This is why routing is so important. Each application state should be addressable by an unique URL. If you don’t have this then your application fails to meet the expectations of the web, such as a working back button, pages that can be bookmarked etc. To capture this I like to create page components that export everything required to hook a new page into the application, including a route string and a factory for creating the React component that represents the page. For example, the component for an about page might be:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; AboutPage = {

    &lt;span class=&quot;comment&quot;&gt;// function that returns the React component for the page&lt;/span&gt;
    pageFactory: aboutPageFactory,

    &lt;span class=&quot;comment&quot;&gt;// the route to match to this page&lt;/span&gt;
    route: &lt;span class=&quot;string&quot;&gt;'about'&lt;/span&gt;
};
&lt;span class=&quot;keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;default&lt;/span&gt; AboutPage;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When rendering the application (this happens in &lt;code&gt;index.js&lt;/code&gt; for create-react-app) we now have everything we need to connect routes to pages.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;ReactDOM.render(
    &amp;lt;Router history={browserHistory} &amp;gt;
        &amp;lt;Route path=&quot;/&quot; component={Layout}&amp;gt;
            &amp;lt;IndexRoute component={Home}/&amp;gt;
            {[aboutPage, loginPage].map(page =&amp;gt; 
                &amp;lt;Route key={page.route} path={page.route} component={page.pageFactory(store, page.sideEffects)} /&amp;gt;
            )}    
        &amp;lt;/Route&amp;gt;
    &amp;lt;/Router&amp;gt;,
    document.getElementById('root')
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For the about page, this means that the route &lt;code&gt;/about&lt;/code&gt; will cause the about page component (returned from aboutPageFactory) to render within the &lt;code&gt;Layout&lt;/code&gt; component. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>On Developer Testing</title>
      <link>http://withouttheloop.com/articles/2017-01-28-on-developer-testing/</link>
      <pubDate>Sat, 28 Jan 2017 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2017-01-28-on-developer-testing/</guid>
      <author></author>
      <description>&lt;h1 id=&quot;on-developer-testing&quot;&gt;On Developer Testing&lt;/h1&gt;
&lt;h2 id=&quot;why&quot;&gt;Why&lt;/h2&gt;
&lt;p&gt;A developer’s responsibility is to create software that works. &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If it has not been tested it has not been shown to work. &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As part of the planning for implementing a new feature the developer should think about and plan how the feature will be tested, and have agreement from the product owner (or appropriate stakeholder). This is sometimes called documenting acceptance criteria.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://web.archive.org/web/20130729213428id_/http://itc.conversationsnetwork.org/shows/detail301.html&quot;&gt;More information on developer testing&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;test-design-prior-to-implementation&quot;&gt;Test Design Prior to Implementation&lt;/h2&gt;
&lt;p&gt;Acceptance criteria may be recorded in the classic BDD syntax:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-gherkin&quot;&gt;GIVEN some preconditions
WHEN an action happens
THEN a result occurs
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example,&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-gherkin&quot;&gt;GIVEN an authenticated user
WHEN they submit the enquiry form
THEN the contents of their enquiry is sent to info&lt;span class=&quot;meta&quot;&gt;@acme.com&lt;/span&gt;
AND a copy is stored in the database
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Repeat until all scenarios have been described. This process ensures: that developers and their stakeholders share an understanding of what is to be built, that the developer has thought through the alternatives that must be accounted for in the implementation. &lt;/p&gt;
&lt;h2 id=&quot;test-implementation&quot;&gt;Test Implementation&lt;/h2&gt;
&lt;p&gt;Theoretically, tests should exist for all enumerated scenarios. In practice some may be difficult to implement or may have insufficient value to justify their existence. Having tests for all scenarios provides a convenient scaffold for the developer. They begin with a complete set of unimplemented tests, make progress by implementing the scenarios, and have confidence that the implementation task is complete when all scenarios have passing tests. &lt;/p&gt;
&lt;p&gt;Good tests should only fail because the code they test is wrong. Therefore, most tests should be &lt;a href=&quot;http://withouttheloop.com/articles/2013-04-07-unit-tests/&quot;&gt;‘unit’ tests&lt;/a&gt;. Integration tests can fail for many reasons so they are undesirable. However, the value of a small number of integration tests is extremely high, as they show that the system functions together as a unit. Start with a small number of end-to-end integration tests, then favour small, focused unit tests. &lt;/p&gt;
&lt;h2 id=&quot;code-for-testing&quot;&gt;Code for Testing&lt;/h2&gt;
&lt;p&gt;Write code that is easy to test. The easiest code to test is code that transforms an input to an output, e.g. a function. Separate computation from side effects, and test the computation (testing side effects pushes you into an integration test). Although this is counterintuitive it leaves more testable and maintainable code that is also more reusable (via composition). It is a happy coincidence that good code and testabe code happen to be the same thing.&lt;/p&gt;
&lt;p&gt;Here is an example of how computation and side effects are commonly mixed:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;built_in&quot;&gt;Date&lt;/span&gt;().getHours() &amp;gt; &lt;span class=&quot;number&quot;&gt;11&lt;/span&gt;) {
    &lt;span class=&quot;built_in&quot;&gt;console&lt;/span&gt;.log(&lt;span class=&quot;string&quot;&gt;&quot;Good afternoon&quot;&lt;/span&gt;);
} &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt; {
    &lt;span class=&quot;built_in&quot;&gt;console&lt;/span&gt;.log(&lt;span class=&quot;string&quot;&gt;&quot;Good morning&quot;&lt;/span&gt;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Accessing the current date via &lt;code&gt;new Date()&lt;/code&gt; is a side effect that introduces a hidden variable that a test cannot control. Producing a result via &lt;code&gt;console.log&lt;/code&gt; similarly prevents a test from evaluating behaviour. The computation here is choosing a greeting based on the time of day, so extract that and test it.&lt;/p&gt;
&lt;p&gt;A better version is:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;comment&quot;&gt;// this is a testable function&lt;/span&gt;
&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;chooseGreeting&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;hourOfDay&lt;/span&gt;) &lt;/span&gt;{
  &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; isAfternoon = hourOfDay &amp;gt; &lt;span class=&quot;number&quot;&gt;11&lt;/span&gt;;
  &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; isAfternoon 
    ? &lt;span class=&quot;string&quot;&gt;&quot;Good afternoon&quot;&lt;/span&gt;
    : &lt;span class=&quot;string&quot;&gt;&quot;Good morning&quot;&lt;/span&gt;;    
}

&lt;span class=&quot;comment&quot;&gt;// group the side effects together&lt;/span&gt;
&lt;span class=&quot;built_in&quot;&gt;console&lt;/span&gt;.log(chooseGreeting(&lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;built_in&quot;&gt;Date&lt;/span&gt;().getHours()));
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;test-execution&quot;&gt;Test Execution&lt;/h2&gt;
&lt;p&gt;The goal is to know as early as possible when a mistake has been made. This is one reason why a good type system is surperior to any testing. I like to say,&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;every test is an admission of failure.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;What I mean is that any other technique for preventing errors is surperior to testing. This could be a static type checker, design-by-contract, transactions or some particular design. When those techniques have been exhausted then we must fallback to testing. &lt;/p&gt;
&lt;p&gt;The strength of testing is its flexibility to detect any type of errors (not just type errors). The weakness of testing is its inability to give any information about anything other than the exact scenario tested (hence the power of &lt;a href=&quot;https://en.wikipedia.org/wiki/QuickCheck&quot;&gt;property testing&lt;/a&gt;). &lt;/p&gt;
&lt;p&gt;To receive the test results as early as possible it is helpful to have a system that runs the tests when changes are detected that may change the test results. Since tests are primarily a function of source code this is usually implemented via a file system watcher that detects changes to the tests or the code that they test, and reruns the tests. &lt;/p&gt;
&lt;p&gt;Each developer should check the tests, and not commit code that causes a test to fail, however, human discipline is flawed and we should only rely upon it when there is no alternative. In the case of testing the usual solution is to make test execution part of the continuous integration build process triggered by every code commit to the shared main branch, which should happen at least once every day. This guarantees that all deployment candidates have passed all tests. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>New year, new job</title>
      <link>http://withouttheloop.com/articles/2017-01-04-new-year-new-job/</link>
      <pubDate>Wed, 04 Jan 2017 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2017-01-04-new-year-new-job/</guid>
      <author></author>
      <description>&lt;p&gt;&lt;img src=&quot;hand_with_glass.jpg&quot; align=&quot;right&quot; alt=&quot;time to relax&quot; style=&quot;width:auto;margin-left:10px&quot;&gt;Next week, two months shy of five years, I will complete my employment with Readify. I stayed so long, far longer than I ever thought I would, because I continued to learn and it continued to be fun. Over this time I have worked with many amazing individuals, who taught me everything I know. I have tried to repay the debt by passing on what I learned to others, and I know that I am leaving behind a highly capable team. &lt;/p&gt;
&lt;p&gt;When I first joined I worked on some incredible teams helping to deliver solutions for customers. When I needed more challenge there was an opportunity to take responsibility for delivery and to lead teams of Readify developers. Eventually I took on the Principal Consultant role and its responsibility for deliverying a portfolio of solutions across a number of customers. Most recently I joined the Queensland management team because I saw an opportunity to create the best place for software developers to work in Queensland. I have enjoyed being in an environment with an unusual tendency towards common sense that rewards hard work and success. &lt;/p&gt;
&lt;h1 id=&quot;you-should-try-consulting-at-least-once&quot;&gt;You Should Try Consulting, at Least Once&lt;/h1&gt;
&lt;p&gt;I did not enjoy my first consulting experience. I was young and felt the frustration of knowing better than everyone else. ;) I wanted to get things done and didn’t feel that my customers were aligned. So I went and worked on products for half a decade. &lt;/p&gt;
&lt;p&gt;Then I joined Readify, and re-entered the world of consulting, with a better attitude and a better approach. The job of the consultant is to help customers to reach their goals, often in spite of themselves. It involves understanding, empathy, education and even a little manipulation (the good kind). The consulting skillset is invaluable in all aspects of life that involves &lt;em&gt;getting things done&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The consulting life involves a huge variety of domains, technology, personalities and environments, often over a relatively brief period of time. This accelerates the learning of consultants who chose to embrace the opportunity. &lt;/p&gt;
&lt;p&gt;Unless you aim to be a developer who hides in the dark and never talks to anyone, consulting is a wonderful opportunity to learn new skills and become more valuable. I recommend that all software developers &lt;a href=&quot;https://join.readify.net/&quot;&gt;give it a go&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&quot;what-s-next-&quot;&gt;What’s Next?&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;wilderness.jpg&quot; alt=&quot;wilderness&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I will be CTO at &lt;a href=&quot;https://startsat60.com/&quot;&gt;Starts at 60&lt;/a&gt;, the leading online community and digital media provider for baby boomers in Australia and New Zealand. So far the business has focused on media and discussion but we are now moving into other areas, like travel. &lt;/p&gt;
&lt;p&gt;The company is established and rapidly growing but still feels very startup, with a lot of experimentation and expansion happening. I look forward to mixing my experience into this exciting and talented group to create something amazing. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>Redux in React and Angular 2</title>
      <link>http://withouttheloop.com/articles/2016-12-21-redux-in-react-and-angular-2/</link>
      <pubDate>Wed, 21 Dec 2016 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2016-12-21-redux-in-react-and-angular-2/</guid>
      <author></author>
      <description>&lt;p&gt;Earlier this month I presented at &lt;a href=&quot;http://dddbrisbane.com/&quot;&gt;dddbrisbane&lt;/a&gt; about simplifying UI programming and I included the simplest React + Redux application I could come up with.&lt;/p&gt;
&lt;h1 id=&quot;the-simplest-react-redux-application-i-could-come-up-with&quot;&gt;The simplest React + Redux application I could come up with&lt;/h1&gt;
&lt;p&gt;It displays a random number. Clicking the text generates a new random number. Toggle the &lt;code&gt;Result&lt;/code&gt; button to see the code more easily. &lt;/p&gt;
&lt;p&gt;&lt;p data-height=&quot;265&quot; data-theme-id=&quot;0&quot; data-slug-hash=&quot;xRrzXO&quot; data-default-tab=&quot;js,result&quot; data-user=&quot;liammclennan&quot; data-embed-version=&quot;2&quot; data-pen-title=&quot;FknRooowwwmmm&quot; class=&quot;codepen&quot;&gt;See the Pen &lt;a href=&quot;http://codepen.io/liammclennan/pen/xRrzXO/&quot;&gt;FknRooowwwmmm&lt;/a&gt; by Liam McLennan (&lt;a href=&quot;http://codepen.io/liammclennan&quot;&gt;@liammclennan&lt;/a&gt;) on &lt;a href=&quot;http://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/p&gt;&lt;/p&gt;
&lt;script async src=&quot;https://production-assets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;

&lt;p&gt;It uses the &lt;a href=&quot;https://facebook.github.io/react/docs/components-and-props.html&quot;&gt;React function component syntax&lt;/a&gt; to define the component as a function from UI state (&lt;code&gt;props&lt;/code&gt;) to HTML (a H1 tag).&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-js&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;HelloNumber&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;props&lt;/span&gt;) &lt;/span&gt;{
  &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;handleClick&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;e&lt;/span&gt;) &lt;/span&gt;{
    store.dispatch({&lt;span class=&quot;attr&quot;&gt;type&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;'MAKE_A_NEW_NUMBER'&lt;/span&gt;});
  }
  &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;h1&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;onClick&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;{handleClick}&lt;/span&gt;&amp;gt;&lt;/span&gt;A random number {props.number}&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;h1&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;onClick&lt;/code&gt; handler dispatches a &lt;code&gt;MAKE_A_NEW_NUMBER&lt;/code&gt; action to the redux store. &lt;/p&gt;
&lt;p&gt;The UI state for the application is an object with a property &lt;code&gt;number&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-js&quot;&gt;{ &lt;span class=&quot;attr&quot;&gt;number&lt;/span&gt;: &lt;span class=&quot;built_in&quot;&gt;Math&lt;/span&gt;.random() }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;a href=&quot;http://redux.js.org/docs/basics/Reducers.html&quot;&gt;redux reducer&lt;/a&gt; (function responsibile for applying actions to the state to make a new state) handles the &lt;code&gt;MAKE_A_NEW_NUMBER&lt;/code&gt; number by setting it to a new random number. &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-js&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; store = Redux.createStore(&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; (&lt;span class=&quot;params&quot;&gt;state = { number: Math.random(&lt;/span&gt;) }, &lt;span class=&quot;title&quot;&gt;action&lt;/span&gt;) &lt;/span&gt;{
  &lt;span class=&quot;keyword&quot;&gt;switch&lt;/span&gt; (action.type) {
    &lt;span class=&quot;keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'MAKE_A_NEW_NUMBER'&lt;/span&gt;:
      &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;built_in&quot;&gt;Object&lt;/span&gt;.assign({},state, {&lt;span class=&quot;attr&quot;&gt;number&lt;/span&gt;:&lt;span class=&quot;built_in&quot;&gt;Math&lt;/span&gt;.random()});
    &lt;span class=&quot;keyword&quot;&gt;default&lt;/span&gt;: &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; state;
  }
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now dispatching an application has updated the state, but we still need to have state changes trigger the UI to update, which is done via the &lt;code&gt;subscribe&lt;/code&gt; method:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-js&quot;&gt;store.subscribe(&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt;=&amp;gt;&lt;/span&gt;{
  ReactDOM.render(
    &lt;span class=&quot;xml&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;HelloNumber&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;number&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;{store.getState().number}&lt;/span&gt;  /&amp;gt;&lt;/span&gt;, 
    document.getElementById('container')
  );
});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and finally prime the whole thing by an initial dispatch&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-js&quot;&gt;store.dispatch({&lt;span class=&quot;attr&quot;&gt;type&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;'MAKE_A_NEW_NUMBER'&lt;/span&gt;});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is not strictly necessary but it is an easy way to trigger the &lt;code&gt;subscribe&lt;/code&gt; callback and cause the initial render. &lt;/p&gt;
&lt;h1 id=&quot;the-simplest-angular-2-redux-application-i-could-come-up-with&quot;&gt;The simplest Angular 2 + Redux application I could come up with&lt;/h1&gt;
&lt;p&gt;What would the equivalent Angular 2 application look like?&lt;/p&gt;
&lt;p&gt;I couldn’t find a simple way to develop an Angular 2 application in Codepen or similar so instead I worked locally, starting with the &lt;a href=&quot;https://angular.io/docs/ts/latest/quickstart.html&quot;&gt;Angular 2 Quickstart&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;To reproduce the random number display functionality in Angular 2 I found that I needed a component hierarchy (parent + child). &lt;/p&gt;
&lt;p&gt;The child component contains the header and dispatches a &lt;code&gt;NEW_RANDOM_NUMBER&lt;/code&gt; action when clicked, just like the React component. Two values are passed into the child component, from the parent, via &lt;code&gt;@Input()&lt;/code&gt; decorators: the application state (&lt;code&gt;appState&lt;/code&gt;) and the redux store dispatch function (&lt;code&gt;dispatch&lt;/code&gt;).  &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-js&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; { Component,Input } &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'@angular/core'&lt;/span&gt;;

@Component({
  &lt;span class=&quot;attr&quot;&gt;selector&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'my-child'&lt;/span&gt;,
  &lt;span class=&quot;attr&quot;&gt;template&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;`&amp;lt;h1 (click)=&quot;onClickMe()&quot;&amp;gt;A random number {{appState.number}}&amp;lt;/h1&amp;gt;`&lt;/span&gt;,
})
&lt;span class=&quot;keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;ChildComponent&lt;/span&gt;  &lt;/span&gt;{ 
    @Input() appState:any;
    @Input() dispatch: &lt;span class=&quot;function&quot;&gt;(&lt;span class=&quot;params&quot;&gt;action:any&lt;/span&gt;) =&amp;gt;&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;void&lt;/span&gt;;

    onClickMe() {
        &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.dispatch({&lt;span class=&quot;attr&quot;&gt;type&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;'NEW_RANDOM_NUMBER'&lt;/span&gt;});
    }
 }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The parent component (&lt;code&gt;AppComponent&lt;/code&gt;) creates  the redux store, using the same reducer as the React version. The UI state is copied to a local field (&lt;code&gt;appState&lt;/code&gt;) and updated whenever the store’s state changes. The &lt;code&gt;appState&lt;/code&gt; and redux &lt;code&gt;dispatch&lt;/code&gt; function are bound to the child component (&lt;code&gt;&amp;lt;my-child/&amp;gt;&lt;/code&gt;). &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-js&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; { Component,Input } &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'@angular/core'&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; { ChildComponent } &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'./child.component'&lt;/span&gt;;
&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; { createStore } &lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'redux'&lt;/span&gt;

interface HasANumber {
  &lt;span class=&quot;attr&quot;&gt;number&lt;/span&gt;: number;
}
interface Action {
  &lt;span class=&quot;attr&quot;&gt;type&lt;/span&gt;: string;
}

@Component({
  &lt;span class=&quot;attr&quot;&gt;selector&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'my-app'&lt;/span&gt;,
  &lt;span class=&quot;attr&quot;&gt;template&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;`&amp;lt;my-child [appState]=&quot;appState&quot; [dispatch]=&quot;store.dispatch&quot;&amp;gt;&amp;lt;/my-child&amp;gt;`&lt;/span&gt;
})
&lt;span class=&quot;keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;AppComponent&lt;/span&gt;  &lt;/span&gt;{ 
  store = createStore&amp;lt;HasANumber&amp;gt;(&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; (&lt;span class=&quot;params&quot;&gt;state = {number:Math.random(&lt;/span&gt;)}, &lt;span class=&quot;title&quot;&gt;action&lt;/span&gt;:&lt;span class=&quot;title&quot;&gt;Action&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;switch&lt;/span&gt; (action.type) {
      &lt;span class=&quot;keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;NEW_RANDOM_NUMBER&quot;&lt;/span&gt;: 
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; {&lt;span class=&quot;attr&quot;&gt;number&lt;/span&gt;:&lt;span class=&quot;built_in&quot;&gt;Math&lt;/span&gt;.random()};
      &lt;span class=&quot;keyword&quot;&gt;default&lt;/span&gt;: &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; state;
    }
  });
  appState = &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.store.getState();

  &lt;span class=&quot;keyword&quot;&gt;constructor&lt;/span&gt;() {
    &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.store.subscribe(&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt;=&amp;gt;&lt;/span&gt; {
      &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.appState = &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.store.getState();      
    });
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id=&quot;final-thoughts&quot;&gt;Final Thoughts&lt;/h1&gt;
&lt;p&gt;Having Typescript easily available in Angular 2 was nice. Further, I found that Angular 2 is at its best when imitating my very strict React style. Both frameworks work well with Redux and the uni-directional data flow idea. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>Document Storage in Sql Server 2016 (JSON) and Postresql</title>
      <link>http://withouttheloop.com/articles/2016-11-12-working-with-documents/</link>
      <pubDate>Sat, 12 Nov 2016 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2016-11-12-working-with-documents/</guid>
      <author></author>
      <description>&lt;style&gt;
table {
    text-align: left;
    font-size: small;
    font-family: consolas;
    background-color: #eee;
    margin-bottom: 15px;
}
td {padding: 4px;}
&lt;/style&gt;

&lt;h1 id=&quot;why-&quot;&gt;Why?&lt;/h1&gt;
&lt;p&gt;Some problems map well to documents, or resources. When your data is a set of relatively independent collections then document storage will be much easier than relational. Anywhere that REST makes sense for resources documents make sense for data storage. Jeremy Miller &lt;a href=&quot;https://jeremydmiller.com/2016/06/14/schema-management-with-marten-why-document-databases-rock/&quot;&gt;wrote a bit about why workring with documents can be efficient&lt;/a&gt; in the context of Marten, the .net document database and event store library for Postresql. If you are not ready to embrace Marten it is possible to start working with documents, in Sql Server or Postresql, easily. &lt;/p&gt;
&lt;h1 id=&quot;sqldoc&quot;&gt;SqlDoc&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/liammclennan/SqlDoc&quot;&gt;SqlDoc&lt;/a&gt; is sort of like Marten, but far less ambitious. It just does document data, in fact it is currently limited to these operations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;run an arbitrary script &lt;/li&gt;
&lt;li&gt;create a table to store documents&lt;/li&gt;
&lt;li&gt;insert a document&lt;/li&gt;
&lt;li&gt;update a document&lt;/li&gt;
&lt;li&gt;delete a document&lt;/li&gt;
&lt;li&gt;retrieve a document&lt;/li&gt;
&lt;li&gt;query for a documents using database indexes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It is a limited feature set but sufficient for a large class of applications. &lt;/p&gt;
&lt;p&gt;I am writing about SqlDoc again because I have recently added support for storing documents as JSON in Sql Server 2016, bringing the storage options to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;postgresql 9.3 or greater&lt;/li&gt;
&lt;li&gt;Sql Server 2005 or greater (XML)&lt;/li&gt;
&lt;li&gt;Sql Server 2016 or greater (JSON)&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;storing-document-data-in-sql-server-2016-as-json&quot;&gt;Storing Document Data in Sql Server 2016 as JSON&lt;/h1&gt;
&lt;p&gt;The first step is to create a table to store documents. SqlDoc expects a table per type stored. To store a type called &lt;code&gt;Person&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CREATE TABLE [dbo].[Person](
    [Id] [uniqueidentifier] NOT NULL,
    [Data] [nvarchar](max) NOT NULL,
 CONSTRAINT [PK_person] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;What the &lt;code&gt;Person&lt;/code&gt; type is does not matter, because it will be serialized and stored as text in the &lt;code&gt;[Data]&lt;/code&gt; column of the &lt;code&gt;Person&lt;/code&gt; table. For this example let’s use:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Person 
{
    public Guid _id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
    public string[] FavouriteThings { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To work with our document database we create an &lt;code&gt;IDocumentSession&lt;/code&gt; from a Sql Server connection string, like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var _documentSession =
            new DocumentSession&amp;lt;Guid&amp;gt;(SqlConnection.From(
                ConfigurationManager.AppSettings[&amp;quot;ConnSqlXml&amp;quot;]))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;IDocumentSession&lt;/code&gt; contains the obvious thing, and is defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public interface IQuerySession&amp;lt;TKey&amp;gt;
{
    TVal Load&amp;lt;TVal&amp;gt;(TKey id) where TVal : class;
    IEnumerable&amp;lt;TVal&amp;gt; Query&amp;lt;TVal&amp;gt;(string sql, Dictionary&amp;lt;string, object&amp;gt; parameters = null);
}
public interface IDocumentSession&amp;lt;TKey&amp;gt; : IQuerySession&amp;lt;TKey&amp;gt;
{
    void Delete(TKey id, object datum);
    void SaveChanges();
    void Store&amp;lt;TVal&amp;gt;(TKey id, TVal entity) where TVal : class;
    void Update&amp;lt;TVal&amp;gt;(TKey id, TVal entity) where TVal : class;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;TKey&lt;/code&gt; is the type of the field used as a primary key. &lt;code&gt;Guid&lt;/code&gt; is a good choice. So with an &lt;code&gt;IDocumentSession&lt;/code&gt; we can insert, update, delete, load and query documents. An insert is done like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var _aDocument = new PersonCs
{
    _id = Guid.NewGuid(),
    Name = &amp;quot;Docsesh&amp;quot;,
    Age = 90,
    FavouriteThings = new[] { &amp;quot;Golf&amp;quot;, &amp;quot;Statue of liberty&amp;quot; }
};
_documentSession.Store(_aDocument._id, _aDocument);
_documentSession.SaveChanges();
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Of course we can enqueue many operations before calling &lt;code&gt;SaveChanges()&lt;/code&gt; to persist the changes in a transaction. The &lt;code&gt;Person&lt;/code&gt; table will now contain the following data:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Id&lt;/th&gt;
&lt;th&gt;Data&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;7BC6192F-1B78-4C31-9537-088EA4205871&lt;/td&gt;
&lt;td&gt;{“_id”:”7bc6192f-1b78-4c31-9537-088ea4205871”,”Age”:90,”Name”:”Docsesh”,”FavouriteThings”: [“Golf”,”Statue of liberty”]}&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;SqlDoc serialized the &lt;code&gt;Person&lt;/code&gt; object to JSON, then inserted it into a table with the same name as the type (Person).&lt;/p&gt;
&lt;p&gt;Updates are hopefully obvious:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;_aDocument.Age += 1;
_documentSession.Update(_aDocument._id, _aDocument);
_documentSession.SaveChanges();
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now the database has:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Id&lt;/th&gt;
&lt;th&gt;Data&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;7BC6192F-1B78-4C31-9537-088EA4205871&lt;/td&gt;
&lt;td&gt;{“_id”:”7bc6192f-1b78-4c31-9537-088ea4205871”,”Age”:91,”Name”:”Docsesh”,”FavouriteThings”: [“Golf”,”Statue of liberty”]}&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;To delete a document:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;_documentSession.Delete(_aDocument._id, _aDocument);
_documentSession.SaveChanges();
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To load a document by its primary key:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var fresh = _documentSession.Load&amp;lt;Person&amp;gt;(_aDocument._id);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note that this relies on the database primary key column being &lt;code&gt;Id&lt;/code&gt;. &lt;/p&gt;
&lt;h2 id=&quot;querying-on-indexes&quot;&gt;Querying on Indexes&lt;/h2&gt;
&lt;p&gt;Querying without an index means a table scan, which is too slow for real use. &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/mt612798.aspx&quot;&gt;MSDN describes the recommended strategy for indexing JSON data&lt;/a&gt;, essential define a computed column for the value to be indexed and index the computed column. &lt;/p&gt;
&lt;p&gt;For our person example, we might wish to query by &lt;code&gt;Name&lt;/code&gt;, so we start by adding a computed column:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ALTER TABLE person
ADD Name AS JSON_VALUE([Data], &amp;#39;$.name&amp;#39;)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The Sql Server table now appears as follows:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Id&lt;/th&gt;
&lt;th&gt;Data&lt;/th&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;7BC6192F-1B78-4C31-9537-088EA4205871&lt;/td&gt;
&lt;td&gt;{“_id”:”7bc6192f-1b78-4c31-9537-088ea4205871”,”Age”:91,”Name”:”Docsesh”,”FavouriteThings”: [“Golf”,”Statue of liberty”]}&lt;/td&gt;
&lt;td&gt;Docsesh&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;And we have a &lt;code&gt;Name&lt;/code&gt; column that can be indexed for querying according to the usual practice in Sql Server. &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CREATE NONCLUSTERED INDEX IX_Person_Name
ON Person ([Name])
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Finally, we can query our index to search by name:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var result = _documentSession.Query&amp;lt;PersonCs&amp;gt;(
    &amp;quot;SELECT [Data] from person where [Name] = @name&amp;quot;,
    new Dictionary&amp;lt;string, object&amp;gt; { { &amp;quot;name&amp;quot;, _aDocument.Name } });
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;alternative-api&quot;&gt;Alternative API&lt;/h2&gt;
&lt;p&gt;Most people seem to like the &lt;code&gt;IDocumentSession&lt;/code&gt; API (inspired by Marten and RavenDB) for working with document storage. There is an alternative API based on accumulating operations in a queue, and then commiting those operations.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var connection = SqlConnection.From(ConfigurationManager.AppSettings[&amp;quot;ConnSqlXml&amp;quot;]);
var _uow = new Queue&amp;lt;Operation&amp;lt;Guid&amp;gt;&amp;gt;();
_uow.Enqueue(Operation.Insert(_aDocument._id, _aDocument));
UnitOfWork.Commit(connection, _uow);

var resultst = QueryFor&amp;lt;Person&amp;gt;.For(
    connection,
    &amp;quot;SELECT [Data] from person where [Name] = @name&amp;quot;,
    new Dictionary&amp;lt;string, object&amp;gt; { { &amp;quot;name&amp;quot;, _aDocument.Name } });
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Both APIs accomplish the same goal. The difference may come down to how much you like dependency injection. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>Introducing Children to Charity</title>
      <link>http://withouttheloop.com/articles/2016-09-13-children-charity/</link>
      <pubDate>Tue, 13 Sep 2016 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2016-09-13-children-charity/</guid>
      <author></author>
      <description>&lt;p&gt;My favourite podcast at the moment is Sam Harris’ &lt;a href=&quot;https://www.samharris.org/podcast&quot;&gt;Waking Up&lt;/a&gt;. Recently Sam interviewed &lt;a href=&quot;https://en.wikipedia.org/wiki/William_MacAskill&quot;&gt;William MacAskill&lt;/a&gt; &lt;a href=&quot;https://www.samharris.org/podcast/item/being-good-and-doing-good&quot;&gt;about the effective altuism movement&lt;/a&gt;. Effective altruism “applies evidence and reason to determining the most effective ways to improve the world”. An example is the organisation &lt;a href=&quot;http://www.givewell.org/&quot;&gt;givewell.org&lt;/a&gt; that researches and ranks charities by the positive effect that would be achieved by increasing their funding. They currently identify 4 top charities based on “the value of filling their remaining funding gaps, which derives from the overall quality and cost-effectiveness of the organization’s work, as well as what additional funding will enable the organization to do”.&lt;/p&gt;
&lt;p&gt;Sam and William gave an example of the moral culpability of 18th century French nobility, who protected their wealth while the people starved. The contention was that this is no different to the 1st world’s neglect of our poorer cousins. There was also an interesting discussion about an idea attributed to &lt;a href=&quot;https://en.wikipedia.org/wiki/Peter_Singer&quot;&gt;Peter Singer&lt;/a&gt;, that to let people suffer and die in other countries whom we could have helped (as we all do, every day) is morally equivalent to seeing a person drowning and doing nothing. All of this reminded me of my good fortune and responsibility to help other people how I can. &lt;/p&gt;
&lt;h1 id=&quot;children-and-charity&quot;&gt;Children and Charity&lt;/h1&gt;
&lt;p&gt;I have three children, currently aged 4, 2 and &amp;lt; 1. I want to teach them that all lives are equally valuable, and that the way to their own happiness paradoxically requires them to balance their own needs (toys) with the needs of other people. To this end I decided to involve them in an effective altruism project. I selected the top two charities from givewell.org, added on of my other favourites (&lt;a href=&quot;https://www.rmhc.org.au/&quot;&gt;Ronald McDonald House&lt;/a&gt;) and printed representative images on a sheet of paper. &lt;/p&gt;
&lt;p&gt;For Ronald McDonald House I used a photo of a sick child with a family symbol adjacent, so that I could explain to my children that Ronald McDonald House helps sick children by making it possible for their families to stay with them when they are in hospital. For the Against Malaria Foundation I used a photo of a girl with Malaria and an graphic of a net so that I could explain that in some countries mosquitos make people sick and that we can help by providing bed nets to stop the mosquitos biting people when they sleep (approx. $5 / net). For the Schistosomiasis Control Initiative (SCI) I used a photo of two girls infected by parasitic worms, with their abdomens clearly deformed, and a graphic of the worm. I explained that the worms make people sick and that we can help by providing medicine that gets rid of the worms (approx. $0.50 / treatment). &lt;/p&gt;
&lt;p&gt;Here is the graphic that I showed to my two eldest kids:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2016-09-13-children-charity/charities.png&quot; alt=&quot;Three charities&quot;&gt;&lt;/p&gt;
&lt;p&gt; I gave each person in my family two coins, representing the contribution we can make to the three charities and asked them to place their coins where they would like their contribution to go. Both children placed coins on the girls with parasitic worms. One also chose to support Ronald McDonald House. Once my wife and I added our choices there was a fairly even distribution across all three charities and we had all had the opportunity to actively participate in the process. &lt;/p&gt;
&lt;p&gt; I have now made payments to each charity, according to the ratios determined by my family and will keep them informed of the results. &lt;/p&gt;
&lt;p&gt; I believe the children empathised with the groups we discussed and understood that helping them consumes resources that we will no longer have for ourselves. My eldest child was initially alarmed because he assumed it was an all or nothing transfer. He asked me, “how will we buy things from the shop?”. When I explained that we will have enough left to be able to continue to buy things from the shop he was satisfied. &lt;/p&gt;
&lt;p&gt;Our donation to Against Malaria has been allocated to &lt;a href=&quot;https://www.againstmalaria.com/Distribution1.aspx?DistributionID=867&amp;amp;ProposalID=207&quot;&gt;an early 2017 distribution in Uganda&lt;/a&gt;. I will show the kids where Uganda is on their map and also let them know when their nets have been distributed to families. &lt;/p&gt;
&lt;p&gt;Overall I think the process was successful and I hope to do it again in a few months time. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>The Timeline Backlog</title>
      <link>http://withouttheloop.com/articles/2016-09-02-timeline-backlog/</link>
      <pubDate>Fri, 02 Sep 2016 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2016-09-02-timeline-backlog/</guid>
      <author></author>
      <description>&lt;p&gt;An agile product &lt;strong&gt;backlog&lt;/strong&gt; is a prioritized list of uncompleted work. It can include features, bugs and other tasks. Good backlog items are as small as possible why still being &lt;em&gt;independently valuable&lt;/em&gt;. They also have an associated effort estimate that helps the product owner to decide if and when the work should be completed. &lt;/p&gt;
&lt;p&gt;Prioritizing the backlog means sorting the items from highest priority to lowest priority. &lt;em&gt;Priority&lt;/em&gt; is generally a combination of value to effort ratio and risk. That is, we should work first on the items that have the best “bang for buck” and the highest risk. High risk items come first so that the risk can be dealt with. Leaving all the risky items until the end of a project would make failure likely.&lt;/p&gt;
&lt;h1 id=&quot;what-is-good-about-the-backlog-&quot;&gt;What is good about the Backlog?&lt;/h1&gt;
&lt;p&gt;The product backlog is a central artifact for an agile project around which work is organised. It provides a basis for conversations with the product owner and subject matter experts. It guides the work of the team and enables project delivery to be projected into the future.&lt;/p&gt;
&lt;h1 id=&quot;what-is-missing-from-the-backlog-&quot;&gt;What is missing from the Backlog?&lt;/h1&gt;
&lt;p&gt;The backlog doesn’t communicate anything about time, and doesn’t visualize relative effort. In short, the backlog is missing the kind of information that we might get from a timeline - so let’s add one.&lt;/p&gt;
&lt;p&gt;Consider the following fictitious backlog for a file backup application:&lt;/p&gt;
&lt;p&gt;&lt;style&gt;
table&amp;gt;td,table&amp;gt;th { border: 1px solid }
&lt;/style&gt;&lt;/p&gt;
&lt;table border=&quot;1&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Story&lt;/th&gt;
&lt;th&gt;Effort (days)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;In order to not lose data as a computer user I want to be able to save backups of selected files&lt;/td&gt;&lt;td&gt;6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;In order to not lose data as a computer user I want to have a configured portion of a filesystem automatically backed up continuously&lt;/td&gt;&lt;td&gt;12&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;In order to recover from a data failure as a computer user I want to be able to retrieve files that were backed up&lt;/td&gt;&lt;td&gt;10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;In order to save money as a computer user I want old copies of backed up files to be purged&lt;/td&gt;&lt;td&gt;5&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt; 

&lt;p&gt;&lt;br/&gt;Further suppose that we have a cost of $2000 / day and therefore a total cost estimate of $66,000. We’d like to see how that time and cost compares to our backlog. How much can I get for half that? Roughly when might a particular story be delivered? To answer these questions we can superimpose the backlog onto a timeline. &lt;/p&gt;
&lt;h1 id=&quot;visualizing-a-backlog-over-time&quot;&gt;Visualizing a backlog over time&lt;/h1&gt;
&lt;p&gt;Each story is shown as a row of a table, with the height scaled proportional to the effort for that story. If one story requires twice as much effort as another then its row is twice as high. A column to the right of the table shows how the budget is consumed over time, with label markers at 25%, 50% and 75% and 100%. This is enough detail to answer the timing questions listed above, but not so much detail that the product owner might infer that estimates have a higher precision than they really do.  &lt;/p&gt;
&lt;p&gt;The resulting visualization is as follows:&lt;/p&gt;
&lt;iframe width=&quot;100%&quot; height=&quot;760&quot; src=&quot;//jsfiddle.net/69z2wepo/54979/embedded/result/&quot; allowfullscreen=&quot;allowfullscreen&quot; frameborder=&quot;0&quot;&gt;&lt;/iframe&gt; 

&lt;p&gt;Interested parties can look at the timeline backlog and understand approximately when features will appear over time. Changes to the backlog are immediately understood as changes to the schedule. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>Blackstar CMS Documentation</title>
      <link>http://withouttheloop.com/articles/2016-08-30-blackstar-documentation/</link>
      <pubDate>Tue, 30  Aug 2016 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2016-08-30-blackstar-documentation/</guid>
      <author></author>
      <description>&lt;p&gt;Blackstar CMS now has a &lt;a href=&quot;https://blackstarcms.net/docs/&quot;&gt;proper documentation site&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It is a work in progress, however, the &lt;a href=&quot;https://blackstarcms.net/docs/client/dotnetclient/&quot;&gt;.net client&lt;/a&gt;, &lt;a href=&quot;https://blackstarcms.net/docs/client/javascriptclient/&quot;&gt;JavaScript client&lt;/a&gt;, &lt;a href=&quot;https://blackstarcms.net/docs/server/security/&quot;&gt;security&lt;/a&gt; and &lt;a href=&quot;https://blackstarcms.net/docs/admin/apikeys/&quot;&gt;API/Keys&lt;/a&gt; are all populated.  &lt;/p&gt;
</description>
    </item>
    <item>
      <title>Seeking Beta Partners for Blackstar CMS</title>
      <link>http://withouttheloop.com/articles/2016-08-28-blackstar-partners/</link>
      <pubDate>Sun, 28  Aug 2016 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2016-08-28-blackstar-partners/</guid>
      <author></author>
      <description>&lt;p&gt;Development of &lt;a href=&quot;https://blackstarcms.net/&quot;&gt;Blackstar CMS&lt;/a&gt; has progressed well and we now have a product that is ready for early users. Recently, we have added &lt;a href=&quot;http://withouttheloop.com/articles/2016-07-03-blackstar-backup/&quot;&gt;a backup system&lt;/a&gt;, &lt;a href=&quot;http://withouttheloop.com/articles/2016-07-04-blackstar-ssl/&quot;&gt;secure connections via SSL/TLS&lt;/a&gt; and &lt;a href=&quot;http://withouttheloop.com/articles/2016-08-05-blackstar-security/&quot;&gt;security features for authentication and authorization&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Beta partners will receive a free 12-month license and personal assistance integrating Blackstar CMS into their application. &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If you have a application that will benefit from content management please reply to this email and request access to the beta program.  &lt;/p&gt;
&lt;p&gt;If you would like to trial Blackstar CMS outside of the beta program you can &lt;a href=&quot;https://blackstarcms.net/install.html&quot;&gt;download the latest builds for Windows and Linux&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Email &lt;img src=&quot;email.jpg&quot; alt=&quot;email&quot; align=&quot;middle&quot; style=&quot;margin:10px;width:auto;display:inline;&quot;/&gt; to participate. &lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;&quot; src=&quot;https://gallery.mailchimp.com/4c9086940c1cc2e74eb2526b9/images/4be86817-e21a-40f5-9388-154a9e9c8516.png&quot; style=&quot;max-width: 2397px;padding-bottom: 0;display: inline !important;vertical-align: bottom;border: 0;height: auto;outline: none;text-decoration: none;-ms-interpolation-mode: bicubic;&quot; class=&quot;mcnImage&quot; align=&quot;middle&quot; width=&quot;564&quot;&gt;&lt;/p&gt;
</description>
    </item>
    <item>
      <title>The Goal Tree</title>
      <link>http://withouttheloop.com/articles/2016-08-24-goaltree/</link>
      <pubDate>Wed, 24  Aug 2016 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2016-08-24-goaltree/</guid>
      <author></author>
      <description>&lt;p&gt;A good software development team is faster than a not-so-good one. Maybe twice as fast, but there is a definite limit. The &lt;strong&gt;real&lt;/strong&gt; productivity difference that experienced developers learn is to minimize waste. &lt;em&gt;It’s all about what you don’t build&lt;/em&gt;. &lt;/p&gt;
&lt;p&gt;Assuming that the customer knows what they want and simply doing what you are told is the surest way to fail. &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Truly productive software development teams optimize their customer’s path to their goal.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;To do that you have to understand what the goal is, and how to get there. &lt;/p&gt;
&lt;style&gt;
img {
    width: auto !important;
}
&lt;/style&gt;

&lt;h1 id=&quot;the-goal-tree&quot;&gt;The Goal Tree&lt;/h1&gt;
&lt;p&gt;The goal tree is a simple exercise that can help take a customer from a specific stated requirement, to a more general and valuable goal, then back to the correct specific requirement. This is done to:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Establish that the stated requirement, and the real underlying goal (business goal) are in fact linked.&lt;/li&gt;
&lt;li&gt;To validate that the stated requirement is the correct one to pursue, or identify a better requirement.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;proceedure&quot;&gt;Proceedure&lt;/h2&gt;
&lt;p&gt;Start with the stated requirement: &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“we would like you to enhance our mobile application to send our customer’s customer’s push notifications when certain events happen”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Recursively ask, “yeah, but why?”&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://static.wixstatic.com/media/77e3fd_42de7891402b46b5af4242cbf9a90eb8.jpg&quot; alt=&quot;yeah but why&quot;&gt; &lt;/p&gt;
&lt;p&gt;and draw the hierarchy of goals.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Our competitors have the feature and we want parity”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2016-08-24-goaltree/parity.png&quot; alt=&quot;parity&quot;&gt;&lt;/p&gt;
&lt;p&gt;“Yeah, but why?”&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“From a traditional monopoly we are facing many emerging competitors and they are stealing market share. We want to stop that.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2016-08-24-goaltree/stop.png&quot; alt=&quot;stop emerging competitors&quot;&gt;&lt;/p&gt;
&lt;p&gt;“Yeah, but why?”&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Our business is software sales into a fixed market. Market share == profit, therefore we must maintain and grow market share”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2016-08-24-goaltree/growprofit.png&quot; alt=&quot;Grow profit&quot;&gt;&lt;/p&gt;
&lt;p&gt;“Yeah, but why?”&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Our MD would like a bigger boat”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2016-08-24-goaltree/biggerboat.png&quot; alt=&quot;bigger boat for MD&quot;&gt;&lt;/p&gt;
&lt;p&gt;At some point it always comes back to a boat for someone. Stop there. Search down the list of goals until you find the most useful strategic goal. It is not the &lt;em&gt;bigger boat for MD&lt;/em&gt; goal because that one is too likely to lead to a life of crime. In this example the most useful goal is:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“From a traditional monopoly we are facing many emerging competitors and they are stealing market share. We want to stop that.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Delete all the others. &lt;/p&gt;
&lt;p&gt;Perform an impact mapping to derive requirements from the identified goal. Compare it to the original starting position. &lt;/p&gt;
&lt;h2 id=&quot;the-impact-mapping&quot;&gt;The Impact mapping&lt;/h2&gt;
&lt;p&gt;Impact mapping is a technique designed to help us &lt;a href=&quot;https://www.impactmapping.org/delivering.html&quot;&gt;deliver business goals, not just software features&lt;/a&gt;. According to the website:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“impact maps allow us to maintain a dynamic roadmap that changes with our learning, keeping the goal in mind and making features and scope secondary to it. We visualise assumptions, which allows us to change direction once these assumptions are proven or discarded”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;goals&quot;&gt;Goals&lt;/h3&gt;
&lt;p&gt;Start with the selected goal. I have reframed it slightly.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2016-08-24-goaltree/defend.png&quot; alt=&quot;defend and increase market position&quot;&gt;&lt;/p&gt;
&lt;p&gt;Of course we should make our goals &lt;a href=&quot;https://en.wikipedia.org/wiki/SMART_criteria&quot;&gt;SMART&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2016-08-24-goaltree/cleargoal.png&quot; alt=&quot;clear goal&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;actors&quot;&gt;Actors&lt;/h3&gt;
&lt;p&gt;Next, we identify the actors who can influence (positively or negatively) the outcome.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2016-08-24-goaltree/actors.png&quot; alt=&quot;actors&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;impacts&quot;&gt;Impacts&lt;/h3&gt;
&lt;p&gt;For each actor list the &lt;strong&gt;impacts&lt;/strong&gt; that we are trying to create. How can that actor help us achieve our goal? How do we want their behaviour to change?&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2016-08-24-goaltree/impacts.png&quot; alt=&quot;impacts&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;deliverables&quot;&gt;Deliverables&lt;/h3&gt;
&lt;p&gt;Now we are finally approaching the level of software, where we started.&lt;/p&gt;
&lt;p&gt;Deliverables are the things we can do to support each impact. They often involve a hefty assumption that should be tracked and revisited. Does this deliverable really support its impact?&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2016-08-24-goaltree/full.png&quot; alt=&quot;Impact map&quot;&gt;&lt;/p&gt;
&lt;p&gt;The implication is that if we deliver the features listed at the bottom, then we will get the impacts identified for the actors, which leads to achieving the goal. &lt;/p&gt;
&lt;p&gt;Note that the original requirement does not appear in the impact map, suggesting that there may not be a clear chain of reasoning back to the actual goal. The three deliverables identified in the impact map may represent more valuable work items. &lt;/p&gt;
&lt;p&gt;The goal tree is one technique that can help high performance development teams to reduce waste and creates more value in less time.    &lt;/p&gt;
</description>
    </item>
    <item>
      <title>Why I Like Mathematics</title>
      <link>http://withouttheloop.com/articles/2016-08-09-mathematics/</link>
      <pubDate>Tue, 09  Aug 2016 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2016-08-09-mathematics/</guid>
      <author></author>
      <description>&lt;p&gt;The reason that I like and enjoy mathematics is epistemological. &lt;a href=&quot;https://en.wikipedia.org/wiki/Epistemology&quot;&gt;Epistemology&lt;/a&gt; is the branch of philosophy that deals with knowledge, including ideas of truth, belief and justification. &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I like mathematics because it is the only science that can ever prove a thing (proposition). &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Mathematics is able to make proofs because it deals with abstract ideas that we define completely - thus proof is possible. &lt;/p&gt;
&lt;p&gt;As a counter example, consider &lt;a href=&quot;https://en.wikipedia.org/wiki/Kepler%27s_laws_of_planetary_motion&quot;&gt;Kepler’s laws of planetary motion&lt;/a&gt;. Kepler reconcilled planetary observations with Isaac Newton’s laws of motion and &lt;a href=&quot;https://en.wikipedia.org/wiki/Newton%27s_law_of_universal_gravitation&quot;&gt;law of universal gravitation&lt;/a&gt; to provide a model for the motion of planets around the sun. It tells us that orbits are elliptical and that planets move faster when they are closer to the sun. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2016-08-09-mathematics/kepler.gif&quot; alt=&quot;Kepler&amp;#39;s laws of planetary motion&quot;&gt;
&lt;em&gt;&lt;a href=&quot;http://withouttheloop.com/articles/2016-08-09-mathematics/Gonfer&quot;&gt;https://en.wikipedia.org/wiki/User:Gonfer&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;It is the law that tells us that the sun will continue to rise each day. It is as close to an absolute truth that physics (the next best science) can get. But planets, and gravity, are not artificial abstractions that we created and thus we can never be sure that we have the complete picture. &lt;/p&gt;
&lt;p&gt;Kepler’s laws of planetary motion start to fail when we look at the orbit of Mercury. Mercury is close enough to the sun that the effect of general relativity (due to the mass of, and proximity to, the sun) cause variation from what is predicted by Kepler’s laws. Kepler and Newton felt, as we all do, that they existed in a regular, three dimensional space. Little did they know that the universe is four dimensional and even the orbit of planets is an illusion produced when straight motion in a four dimensional space is projected into three dimensions (or something). &lt;/p&gt;
&lt;p&gt;We don’t KNOW anything - except what we know via mathematics. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>Blackstar CMS Security</title>
      <link>http://withouttheloop.com/articles/2016-08-05-blackstar-security/</link>
      <pubDate>Fri, 05  Aug 2016 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2016-08-05-blackstar-security/</guid>
      <author></author>
      <description>&lt;p&gt;Previously, I demonstrated &lt;a href=&quot;http://withouttheloop.com/articles/2016-07-04-blackstar-ssl/&quot;&gt;how to configure Blackstar CMS to use SSL/TLS to secure connections&lt;/a&gt;. This post will describe the other security features of Blackstar CMS, principally authentication and authorization. &lt;/p&gt;
&lt;h1 id=&quot;security-settings&quot;&gt;Security Settings&lt;/h1&gt;
&lt;p&gt;The admin application has settings for controlling access to Blackstar CMS. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2016-08-05-blackstar-security/settings.png&quot; alt=&quot;Settings&quot;&gt;&lt;/p&gt;
&lt;p&gt;Access is restricted in two categories: editing and reading. For each category you can specify who has permission: everyone, all authenticated users, or a specific set of authenticated users. &lt;/p&gt;
&lt;p&gt;The above configuration restricts access to the admin application, and all editing functions, to the users &lt;code&gt;Liam&lt;/code&gt; and &lt;code&gt;Anne-Marie&lt;/code&gt;. Reading content via the API is open to everyone and does not require authentication. Many scenarios will use a similar setting - editing is restricted, reading is not.&lt;/p&gt;
&lt;p&gt;Where authentication is required, clients require an API key. The admin application has an API / Keys page where API keys can be created.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2016-08-05-blackstar-security/api.png&quot; alt=&quot;API / Keys Page&quot;&gt;&lt;/p&gt;
&lt;p&gt;Keys are given a name to help you remember what they are for. You should create one key per channel that accesses content, for example, one for your web application and one for your mobile application. Each key provides complete access to everything so they must be kept secret. &lt;/p&gt;
&lt;h1 id=&quot;api-security&quot;&gt;API Security&lt;/h1&gt;
&lt;p&gt;The API is Blackstar’s most important interface, so let’s start there. When connecting to the Blackstar API client’s may need to authenticate. Authentication is the process of establishing a trusted identity and is achieved using &lt;a href=&quot;https://jwt.io/introduction/&quot;&gt;JSON Web Tokens&lt;/a&gt; (JWT). A JWT is a cryptographically signed authentication claim. The client signs a claim using a secret API key. The server validates the token with the same API key. If the token validates then the server knows that the client has the same key and the claim can be trusted. &lt;/p&gt;
&lt;p&gt;Once the client has created a JWT it is then included with every request, in the &lt;code&gt;Authorization&lt;/code&gt; header, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiTGlhbSIsImlhdCI6MTQ3MDM3MTQ1MCwiZXhwIjoxNDcwNDU3ODUwfQ.Nl2k32tcAHWhxDURL_fN08bgbrxfA9CSXWeA0nDPwso
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Every request received by the server will check the authorization header and attempt to validate the token. The token includes the current user’s identifier, which can then be used for authorization. &lt;/p&gt;
&lt;p&gt;When using the &lt;a href=&quot;https://github.com/Blackstar-CMS/javascript-client&quot;&gt;Blackstar JavaScript client&lt;/a&gt; this is all taken care of for you. The only requirement is to supply a JWT when instantiating a new client, like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; blackstar = &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; Blackstar.Client(&lt;span class=&quot;string&quot;&gt;'https://demo.blackstarcms.net'&lt;/span&gt;, { 
  &lt;span class=&quot;attr&quot;&gt;showEditControls&lt;/span&gt;: &lt;span class=&quot;literal&quot;&gt;false&lt;/span&gt;,
  &lt;span class=&quot;attr&quot;&gt;token&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiTGlhbSIsImlhdCI6MTQ3MDM3MTQ1MCwiZXhwIjoxNDcwNDU3ODUwfQ.Nl2k32tcAHWhxDURL_fN08bgbrxfA9CSXWeA0nDPwso'&lt;/span&gt;,
  &lt;span class=&quot;attr&quot;&gt;authCallback&lt;/span&gt;: &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; (&lt;span class=&quot;params&quot;&gt;response&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;comment&quot;&gt;// do something if the server return 401 Unauthorized&lt;/span&gt;
  }
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To create a token in your application first acquire an API key from the Blackstar CMS admin application, then build a JWT token with a &lt;code&gt;name&lt;/code&gt; value containing the current user’s user name and an optional &lt;code&gt;expiresIn&lt;/code&gt; value. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;jwt.sign({ &lt;span class=&quot;attr&quot;&gt;name&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;liam&quot;&lt;/span&gt; }, &lt;span class=&quot;string&quot;&gt;&quot;BatrVb7cIh7QYA218iqM&quot;&lt;/span&gt;, {
    &lt;span class=&quot;attr&quot;&gt;expiresIn&lt;/span&gt;: &lt;span class=&quot;number&quot;&gt;3600&lt;/span&gt; * &lt;span class=&quot;number&quot;&gt;24&lt;/span&gt;
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(note: &lt;code&gt;&amp;quot;BatrVb7cIh7QYA218iqM&amp;quot;&lt;/code&gt; is the API key)&lt;/p&gt;
&lt;h1 id=&quot;admin-application-security&quot;&gt;Admin Application Security&lt;/h1&gt;
&lt;p&gt;To authenticate with the admin application simply append &lt;code&gt;?t=&amp;lt;JWT token&amp;gt;&lt;/code&gt; to the URL. If the user named in the token has the &lt;code&gt;editing&lt;/code&gt; permission then you will get access. This is the recommended way to access the admin application, however, if you have not yet setup your application to be able to produce the JWT token, then you can authenticate via the login page:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2016-08-05-blackstar-security/login.png&quot; alt=&quot;Login page&quot;&gt;&lt;/p&gt;
&lt;p&gt;The use of the login page is &lt;strong&gt;not recommended&lt;/strong&gt; because it requires knowledge of an API key, and they need to be kept secret. The login page simply creates a JWT token (as above) and redirects to &lt;code&gt;&amp;lt;url&amp;gt;?t=&amp;lt;JWT token&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;Blackstar CMS’s security features are designed to be simple, yet flexible. Please provide your feedback to &lt;code&gt;liam&lt;/code&gt; at &lt;code&gt;blackstarcms.net&lt;/code&gt;. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>Using TLS/SSL with Blackstar CMS</title>
      <link>http://withouttheloop.com/articles/2016-07-04-blackstar-ssl/</link>
      <pubDate>Mon, 04 Jul 2016 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2016-07-04-blackstar-ssl/</guid>
      <author></author>
      <description>&lt;p&gt;There are two primary architectures for using an API-first CMS like Blackstar CMS. &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Modern web applications built with Angular.js, React, Ember etc will tend to load their application data from their application server, and their content data directly from Blackstar CMS. This means that the end user’s browser connects directly to Blackstar CMS.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server rendered applications using Asp.net MVC, Rails, Django etc will load content from Blackstar CMS during the process of rendering the page. In this scenario Blackstar CMS is only accessed by the web server and can be deployed within a private network.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In both cases, and definitely the first, it may be advantageous to secure the connection to Blackstar CMS. Fortunately, the internet has a robust infrastructure for solving this problem. &lt;a href=&quot;https://en.wikipedia.org/wiki/Transport_Layer_Security&quot;&gt;TLS/SSL&lt;/a&gt; provides communication security by encrypting the communication, authenticating the identity of the server, and guaranteeing the integrity of the message. &lt;/p&gt;
&lt;h1 id=&quot;securing-connections-to-blackstar-cms&quot;&gt;Securing Connections to Blackstar CMS&lt;/h1&gt;
&lt;p&gt;To secure a connection you will need to obtain a private key and a certificate. There are several ways to do this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create a self-signed certificate. This will encrypt the connection but will fail to authenticate the identity of the server.&lt;/li&gt;
&lt;li&gt;Obtain a free certificate from &lt;a href=&quot;https://letsencrypt.org/&quot;&gt;Let’s Encrypt&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Purchase a certificate from a certifying authority. &lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;creating-a-self-signed-certificate&quot;&gt;Creating a Self-signed Certificate&lt;/h2&gt;
&lt;p&gt;For testing purposes a self-signed certificate may suffice. Do not attempt to use a self-signed certificate for production use.&lt;/p&gt;
&lt;p&gt;To create a self-signed certificate and private key:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Install OpenSSL (if you don’t have it already)&lt;/li&gt;
&lt;li&gt;Use the following command&lt;pre&gt;&lt;code&gt;openssl req \
    -newkey rsa:2048 -nodes -keyout domain.key \
    -x509 -days 365 -out domain.crt
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This certificate/key pair will be valid for 365 days. &lt;/p&gt;
&lt;h2 id=&quot;configure-blackstar-cms-to-use-tls-ssl&quot;&gt;Configure Blackstar CMS to use TLS/SSL&lt;/h2&gt;
&lt;p&gt;To configure Blackstar CMS to use a TLS secure connection you must firstly obtain a private key and certificate (see above). &lt;/p&gt;
&lt;p&gt;Next, edit your Blackstar CMS configuration file (&lt;code&gt;config.json&lt;/code&gt;) and set values for the &lt;code&gt;pathToKey&lt;/code&gt; and &lt;code&gt;pathToCert&lt;/code&gt; options. &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;{
  &lt;span class=&quot;string&quot;&gt;&quot;pathToKey&quot;&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;/home/fred/domain.key&quot;&lt;/span&gt;,
  &lt;span class=&quot;string&quot;&gt;&quot;pathToCert&quot;&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;/home/fred/domain.cert&quot;&lt;/span&gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then restart Blackstar CMS for the changes to take effect. &lt;/p&gt;
&lt;p&gt;When accessing Blackstar CMS you will now need to change the protocol from &lt;code&gt;http&lt;/code&gt; to &lt;code&gt;https&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If you used a self-signed certificate you will get an error because the certificate is not signed by a Certificate Authority (CA).&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2016-07-04-blackstar-ssl/chromeerror.png&quot; alt=&quot;Certificate error&quot;&gt;&lt;/p&gt;
&lt;p&gt;For testing purposes you can accept the error and proceed to access Blackstar CMS via an encrypted connection. For production, use Let’s Encrypt or a Certificate Authority to obtain a trusted certificate. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>Blackstar CMS Backup</title>
      <link>http://withouttheloop.com/articles/2016-07-03-blackstar-backup/</link>
      <pubDate>Sun, 03 Jul 2016 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2016-07-03-blackstar-backup/</guid>
      <author></author>
      <description>&lt;p&gt;One of the most requested features for Blackstar CMS has been backup. Blackstar is an operational system so backup is important to maximise uptime and minimize data loss. &lt;/p&gt;
&lt;h1 id=&quot;strategy&quot;&gt;Strategy&lt;/h1&gt;
&lt;p&gt;Blackstar stores all its data in a Sqlite database specifically to facilitate a simple backup process. We can get a complete backup simply by backing up the database. &lt;/p&gt;
&lt;p&gt;Of course you can manually backup the database yourself, but Blackstar CMS will do it for you automatically. &lt;/p&gt;
&lt;p&gt;Blackstar’s backup process is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;on a schedule (every 10 minutes by default) the database is exclusively locked for the backup process&lt;/li&gt;
&lt;li&gt;if the databse has changed since the last backup then&lt;ul&gt;
&lt;li&gt;copy the file to a backup location &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;release the lock so the application can continue running&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It is necessary to lock the database so that the copy doesn’t cause corruption. On a test database (1MB) the backup requires the database to be locked for 6ms, so the performance degredation is manageable. &lt;/p&gt;
&lt;h1 id=&quot;implementation-in-node-js&quot;&gt;Implementation in Node.js&lt;/h1&gt;
&lt;p&gt;The single threaded nature of node.js helps to make these sort of concurrent processes easy. When Blackstar starts it registers a callback on the backup frequency:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;setInterval(&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; (&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;comment&quot;&gt;// do backup&lt;/span&gt;
}, &lt;span class=&quot;number&quot;&gt;10&lt;/span&gt; * &lt;span class=&quot;number&quot;&gt;60&lt;/span&gt; * &lt;span class=&quot;number&quot;&gt;1000&lt;/span&gt; &lt;span class=&quot;comment&quot;&gt;/* 10 minutes */&lt;/span&gt;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To ensure a consistent backup the database needs to be locked for writes (reads are still OK). We can lock a sqlite database for writes using the &lt;code&gt;BEGIN IMMEDIATE&lt;/code&gt; command. If an error occurs while the database is locked we still want to ensure the lock is released, so the process is wrapped in &lt;code&gt;try {} finally {}&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;try&lt;/span&gt; {
    db.run(&lt;span class=&quot;string&quot;&gt;&quot;BEGIN IMMEDIATE&quot;&lt;/span&gt;);
    &lt;span class=&quot;comment&quot;&gt;// do things with an exclusive write lock&lt;/span&gt;
} &lt;span class=&quot;keyword&quot;&gt;finally&lt;/span&gt; {
    db.run(&lt;span class=&quot;string&quot;&gt;&quot;COMMIT&quot;&lt;/span&gt;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The whole thing is done synchronously, since we are blocking the server anyway. The file hash is calculated using node’s &lt;code&gt;crypto&lt;/code&gt; module, which delegates to OpenSSL.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;calculateHash&lt;/span&gt;(&lt;span class=&quot;params&quot;&gt;data:Buffer&lt;/span&gt;) : &lt;span class=&quot;title&quot;&gt;string&lt;/span&gt; &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;const&lt;/span&gt; hash = Crypto.createHash(&lt;span class=&quot;string&quot;&gt;'sha256'&lt;/span&gt;);
    hash.update(data);
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; hash.digest(&lt;span class=&quot;string&quot;&gt;'hex'&lt;/span&gt;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If the hash of the current database is different since the last time the backup function ran then the database is copied to the backup destination.&lt;/p&gt;
&lt;h1 id=&quot;summary&quot;&gt;Summary&lt;/h1&gt;
&lt;p&gt;The backup solution described above will be sufficient for most scenarios. For anything else it is easy enough to build your own backup process using a variation on the same technique (lock the database, take a copy, unlock the database). The &lt;a href=&quot;https://www.sqlite.org/backup.html&quot;&gt;sqlite online backup API&lt;/a&gt; provides some options. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>Blackstar CMS (Alpha) Installers Available</title>
      <link>http://withouttheloop.com/articles/2016-06-24-blackstar-installers-available/</link>
      <pubDate>Fri, 24 Jun 2016 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2016-06-24-blackstar-installers-available/</guid>
      <author></author>
      <description>&lt;h2 id=&quot;the-blackstar-cms-now-has-a-usable-feature-set-you-can-&quot;&gt;The Blackstar CMS now has a usable feature set. You can:&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Create and edit content, with &lt;a href=&quot;https://demo.blackstarcms.net/newChunk&quot;&gt;a fancy new markdown editor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://demo.blackstarcms.net/search&quot;&gt;Tag and search for content&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://demo.blackstarcms.net/media&quot;&gt;Work with media assets&lt;/a&gt; (non-image media still needs work)&lt;/li&gt;
&lt;li&gt;Pull content using the &lt;a href=&quot;https://github.com/Blackstar-CMS/javascript-client&quot;&gt;JavaScript client&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Pull content using the &lt;a href=&quot;https://github.com/Blackstar-CMS/dotnet-client&quot;&gt;.net client&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Install Blackstar CMS as a service on Windows or Linux (more on this later)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;things-that-blackstar-cms-still-cannot-do-but-will-soon-&quot;&gt;Things that Blackstar CMS still cannot do, but will soon:&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Be reliably used in production&lt;/li&gt;
&lt;li&gt;Provide authentication and authorization for content access and administration&lt;/li&gt;
&lt;li&gt;Provide built-in SSL/TLS support &lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;install-blackstar-cms-as-a-service-on-windows-or-linux&quot;&gt;Install Blackstar CMS as a service on Windows or Linux&lt;/h2&gt;
&lt;p&gt;Installation packages are now available for Windows and Linux. To receive access to the installation packages, along with install instructions, &lt;a href=&quot;https://blackstarcms.net/#stayintouch&quot;&gt;join the Blackstar CMS mailing list&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;If you are already on the list you will receive a link to the download soon.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Blackstar CMS Progress</title>
      <link>http://withouttheloop.com/articles/2016-06-09-blackstar-cms-progress/</link>
      <pubDate>Thu, 09 Jun 2016 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2016-06-09-blackstar-cms-progress/</guid>
      <author></author>
      <description>&lt;blockquote&gt;
&lt;p&gt;I &lt;a href=&quot;http://withouttheloop.com/articles/2016-04-27-headless-cms/&quot;&gt;announced Blackstar CMS&lt;/a&gt; 6 weeks ago. Since then the mailing list has grown steadily (join &lt;a href=&quot;http://blackstarcms.net/#stayintouch&quot;&gt;here&lt;/a&gt;) and the product has moved closer to release. &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Many things have changed in the last six weeks (try the &lt;a href=&quot;http://demo.blackstarcms.net/&quot;&gt;demo&lt;/a&gt;, here are some highlights:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;rich text editing&lt;/li&gt;
&lt;li&gt;media library&lt;/li&gt;
&lt;li&gt;sensible caching &lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;rich-text-editing&quot;&gt;Rich Text Editing&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;richtext.png&quot; alt=&quot;Rich text editing&quot;/&gt;&lt;/p&gt;
&lt;p&gt;Blackstar CMS now uses &lt;a href=&quot;https://prosemirror.net/&quot;&gt;ProseMirror&lt;/a&gt; for content editing. It is a simple, but pleasant, editing control. The intention is that basic editing can be done via the WYSIWIG editor, for anything more complicated it is better to work with the raw HTML directly. &lt;/p&gt;
&lt;h1 id=&quot;media-library&quot;&gt;Media Library&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;medialibrary.png&quot; alt=&quot;Media Library&quot; /&gt;&lt;/p&gt;
&lt;p&gt;A CMS is not that useful without support for images and other media. The &lt;em&gt;Media Library&lt;/em&gt; is Blackstar CMS’s central home for all media. Files can be uploaded by dragging onto the upload button, or by clicking the button and selecting one or more files from the file browser. &lt;/p&gt;
&lt;p&gt;The media library has a search field for finding assets in a large library.&lt;/p&gt;
&lt;p&gt;When editing content we can add media by launching the media library in a dialog:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;mediadialog.png&quot; alt=&quot;Media Dialog&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Being able to nest user interface components like this (this is the media library inside of the content editing component) is a fun design challenge for a rich web application. &lt;/p&gt;
&lt;h1 id=&quot;-sensible-caching&quot;&gt; Sensible Caching&lt;/h1&gt;
&lt;p&gt; Caching is an interesting challenge for a CMS. We want content cached, but we also want to always see the latest content. Ultimately, Blackstar CMS will allow caching to be configured for content. At the moment I have set the cache to a fixed time period (24 hours). Within that time period users will only download content once. Subsequent requests will use the cached copy without ever making a request to the Blackstar CMS server. Administrators can force a cache refresh by using the browser refresh feature (F5). &lt;/p&gt;
&lt;p&gt; Caching of media is simpler. Blackstar CMS associates a unique code with each asset, based on the content of the asset. All media are cached forever. If an image changes, upload a new asset and change the links that point to it. &lt;/p&gt;
&lt;h1 id=&quot;-what-s-next-&quot;&gt; What’s Next?&lt;/h1&gt;
&lt;p&gt; The work coming up includes providing raw HTML editing of content and a number of minor tweaks. Then I will build an installer and make it available for enthusiastic users. &lt;strong&gt;Please leave a comment if you have a preference for a linux or windows installer.&lt;/strong&gt;&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Automating the Deployment of Node.js Applications</title>
      <link>http://withouttheloop.com/articles/2016-05-26-automating-deployment-of-nodejs-applications/</link>
      <pubDate>Thu, 26 May 2016 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2016-05-26-automating-deployment-of-nodejs-applications/</guid>
      <author></author>
      <description>&lt;blockquote&gt;
&lt;p&gt;Have a build process to produce a deployable (non-development) package. Host on Linux with pm2 to manage processes and restarts. Move files with rsync. Perform installation activities with ssh. Reverse proxy through nginx for improved performance and SSL termination.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For information about &lt;em&gt;how&lt;/em&gt; to build a node.js web application see &lt;a href=&quot;http://withouttheloop.com/articles/2016-03-24-node-web-ts/&quot;&gt;Building a Web Application with Node and Typescript&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&quot;build-a-deployable-package&quot;&gt;Build a Deployable Package&lt;/h1&gt;
&lt;p&gt;Step 1 of a deployment process is to build a deployment specific package of your application. The needs of an application in production are very different to the needs during development. For example, a production application does not need all your development npm dependencies, or source maps, or unminified source files. &lt;/p&gt;
&lt;p&gt;I use &lt;a href=&quot;http://gulpjs.com/&quot;&gt;gulp&lt;/a&gt; for all my node.js scripting requirements. When combined with &lt;a href=&quot;https://github.com/shelljs/shelljs&quot;&gt;shelljs&lt;/a&gt; and &lt;a href=&quot;https://github.com/sun-zheng-an/gulp-shell&quot;&gt;gulp-shell&lt;/a&gt; for executing bash commands from gulp I find it to be an effective scripting platform and a reasonably reliable cross-platform solution (with some exceptions). &lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://withouttheloop.com/articles/2016-04-27-headless-cms/&quot;&gt;My application&lt;/a&gt; consists of a node.js server application and a React browser application. The client-side JavaScript is written in many files. For production I would like to concatenate them together to minimize the number of HTTP requests required and improve performance. To do this I use browserify, and a gulp task like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;gulp.task(&lt;span class=&quot;string&quot;&gt;'concatenate-client-javascript'&lt;/span&gt;, shell.task([
    &lt;span class=&quot;string&quot;&gt;'browserify src/app.js -o public/bundle.js'&lt;/span&gt;
]));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Browserify starts from the root of the application (&lt;code&gt;app.js&lt;/code&gt;) and recursively follows dependencies to build a graph of all the required code. It then concatenates it all into a single file (&lt;code&gt;bundle.js&lt;/code&gt;). &lt;/p&gt;
&lt;p&gt;To create my deployment package I copy the files that are required for deployment to a separate directory - mine is called &lt;code&gt;package&lt;/code&gt;. I do this with simple shell commands executed via shelljs or gulp-shell. &lt;/p&gt;
&lt;p&gt;At this point I have a directory &lt;code&gt;package&lt;/code&gt; containing my application as I would like it deployed to my server. &lt;/p&gt;
&lt;h1 id=&quot;hosting-on-linux-with-pm2&quot;&gt;Hosting on Linux with pm2&lt;/h1&gt;
&lt;p&gt;Deploying node.js applications to Linux is a good idea because:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;node.js works better on Linux than on Windows&lt;/li&gt;
&lt;li&gt;Linux is often cheaper&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Unfortunately, unlike Windows, Linux does not have a consistent mechanism for implementing servers. &lt;a href=&quot;https://github.com/Unitech/pm2&quot;&gt;pm2&lt;/a&gt; is a process manager that can help with this. To install pm2: &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ npm install pm2@latest -g
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Instead of starting our application directly like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ node app.js
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We use pm2 to host the process:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ pm2 start app.js
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;img src=&quot;start.png&quot; alt=&quot;pm2 start&quot; /&gt;&lt;/p&gt;
&lt;p&gt;pm2 immediately provides a number of benefits:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;it restarts the process if it crashes&lt;/li&gt;
&lt;li&gt;it handles logging &lt;/li&gt;
&lt;li&gt;it is able to manage many processes and control things like starting, stopping, memory use and uptime  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Detailed information about a process is retrieved with the &lt;code&gt;show&lt;/code&gt; command:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;$ pm2 show app
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;show.png&quot; alt=&quot;pm2 show&quot;/&gt;&lt;/p&gt;
&lt;p&gt;pm2’s real party trick is that it can be configured to start with the operating system. To do this, first save the current process list then use the &lt;code&gt;startup&lt;/code&gt; command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ pm2 save
$ pm2 startup
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The output will be a shell script to be executed as root that will cause pm2 to start when the OS boots and start its processes. Unfortunately, this does not work for Windows. &lt;/p&gt;
&lt;p&gt;Now we have a way to run our application, we just need to move the files to our server. &lt;/p&gt;
&lt;h1 id=&quot;move-files-with-rsync&quot;&gt;Move files with rsync&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Rsync&quot;&gt;rsync&lt;/a&gt; is a smart file synchronization tool that can be used to move your application from your development computer to your deployment server. By using delta encoding and compression rsync optimizes file transfer size and speed. &lt;/p&gt;
&lt;p&gt;Again, this is easily scripted with gulp.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;gulp.task(&lt;span class=&quot;string&quot;&gt;'deployapp'&lt;/span&gt;,[&lt;span class=&quot;string&quot;&gt;'package'&lt;/span&gt;], shell.task([
  &lt;span class=&quot;string&quot;&gt;&quot;rsync -azvP package username@yourdomain:location/to/deploy/to&quot;&lt;/span&gt;,
]));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This gulp task will copy our application directory (&lt;code&gt;package&lt;/code&gt;) to &lt;code&gt;~/location/to/deploy/to&lt;/code&gt; relative to the user’s home directory. You will obviously need to authenticate with the server to do this, which can be done with certificates or a password. &lt;/p&gt;
&lt;h1 id=&quot;perform-installation-activities-with-ssh&quot;&gt;Perform Installation Activities with SSH&lt;/h1&gt;
&lt;p&gt;With &lt;a href=&quot;https://en.wikipedia.org/wiki/Secure_Shell&quot;&gt;SSH&lt;/a&gt; we can run bash commands on a remote computer. For my application the post install steps are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Delete the database&lt;/li&gt;
&lt;li&gt;Restart the application process with pm2&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;My gulp task is something like:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;gulp.task(&lt;span class=&quot;string&quot;&gt;'postinstallsteps'&lt;/span&gt;,[&lt;span class=&quot;string&quot;&gt;'deployapp'&lt;/span&gt;], shell.task([
  &lt;span class=&quot;string&quot;&gt;'ssh username@yourdomain &quot;rm -f mydatabasefile.db &amp;amp;&amp;amp; pm2 restart myapplicationname&quot;'&lt;/span&gt;
]));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For more complicated scripts you can use SSH to execute a script file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ ssh username@yourdomain &amp;#39;bash -s&amp;#39; &amp;lt; myinstallscript.sh
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&quot;reverse-proxy-through-nginx-for-improved-performance-and-ssl-termination&quot;&gt;Reverse Proxy Through nginx for Improved Performance and SSL Termination&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;nginx.png&quot; alt=&quot;nginx&quot;/&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://nginx.org/en/&quot;&gt;nginx&lt;/a&gt; is a wonderful web server and proxy that handles most of the world’s web traffic. When hosting a node application we can chose to let clients connect directly or via a reverse proxy, such as nginx. nginx is much better than node.js at certain tasks, such as proxying, serving file system content and terminating SSL.&lt;/p&gt;
&lt;p&gt;I use the default ubuntu setup of nginx, which uses a file-per-site in &lt;code&gt;/etc/nginx/sites-enabled&lt;/code&gt; to configure nginx. My nginx configuration file is included in my deployment package as a text file, similar to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;upstream app_demo_blackstar {
    server 127.0.0.1:2999;
}

# the nginx server instance
server {
    listen 80;
    server_name demo.blackstarcms.net;
    access_log /var/log/nginx/demo-blackstarcms.log;

    # pass the request to the node.js server with the correct headers and much more can be added, see nginx config options
    location / {
      #proxy_set_header X-Real-IP $remote_addr;
      #proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      #proxy_set_header Host $http_host;
      #proxy_set_header X-NginX-Proxy true;

      proxy_pass http://app_demo_blackstar/;
      proxy_redirect off;
    }

    location ~* ^.+\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js)$ {
      root /path/to/static/content;
    }
 }
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt; The &lt;code&gt;server&lt;/code&gt; element defines a website at &lt;a href=&quot;http://demo.blackstarcms.net&quot;&gt;http://demo.blackstarcms.net&lt;/a&gt; on port 80. &lt;/p&gt;
&lt;p&gt; The &lt;code&gt;proxy_pass&lt;/code&gt; setting configures nginx as a reverse proxy for the upstream application &lt;code&gt;app_demo_blackstar&lt;/code&gt;, which is my pm2 hosted node.js application. &lt;/p&gt;
&lt;p&gt; The &lt;code&gt;location&lt;/code&gt; setting configures nginx to directly handle any requests for the listed file types. These requests will be handled by nginx and never forwarded to node.js. This improves performance and takes load off the node.js process. &lt;/p&gt;
&lt;p&gt; A problem remains - my nginx configuration file is in my application deployment package, but needs to be in &lt;code&gt;/etc/nginx/sites-enabled&lt;/code&gt; to be picked up by nginx. This is easily solved by creating a symbolic link in &lt;code&gt;/etc/nginx/sites-enabled&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; $ cd /etc/nginx/sites-enabled
 $ ln -s /path/to/app/package/nginx.config blackstarnginxconfig
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt; Nginx will only reload configuration when it is restarted, like so (on ubuntu):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; $ sudo service nginx restart
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt; To pick up nginx configuration changes automatically we could easily add this nginx restart step to our post install ssh commands. &lt;/p&gt;
&lt;h1 id=&quot;-summary&quot;&gt; Summary&lt;/h1&gt;
&lt;p&gt; With this setup in place I can deploy my application with a single gulp command. If my application crashes the output is logged and the application is restarted. If the server crashes my application is restarted when the server restarts. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>Blackstar CMS ASP.NET MVC Sample</title>
      <link>http://withouttheloop.com/articles/2016-05-20-blackstarcms-dotnetclient/</link>
      <pubDate>Fri, 20 May 2016 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2016-05-20-blackstarcms-dotnetclient/</guid>
      <author></author>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;http://blackstarcms.net/&quot;&gt;Blackstar CMS&lt;/a&gt; now has a &lt;a href=&quot;https://github.com/Blackstar-CMS/samples#net-aspnet-mvc&quot;&gt;public sample showing how to add managed content to an ASP.NET MVC web application&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Most, if not all, public facing web applications would benefit from some content management to give administrators a way to keep the content current and to experiment with different marketing material. &lt;a href=&quot;http://withouttheloop.com/articles/2016-04-26-blackstar-headless-cms/&quot;&gt;Building applications inside of a CMS has been tried and found wanting&lt;/a&gt;. Recently, I &lt;a href=&quot;http://withouttheloop.com/articles/2016-04-27-headless-cms/&quot;&gt;introduced Blackstar CMS&lt;/a&gt; as a solution to this problem.&lt;/p&gt;
&lt;p&gt;To help developers learn how to use Blackstar CMS to add managed content to their applications I am producing a number of samples, including one for ASP.NET MVC.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/Blackstar-CMS/samples#net-aspnet-mvc&quot;&gt;Blackstar CMS ASP.NET MVC Sample&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This sample is based on the ASP.NET MVC web project template. &lt;/p&gt;
&lt;p&gt;When you start the application you will see:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;dotnet1.png&quot; alt=&quot;Blackstarpedia .net sample&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This is an ASP.NET MVC web application featuring content loaded from Blackstar CMS. The content can be edited via the Blackstar CMS admin interface. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;dotnet2.png&quot; alt=&quot;Blackstar CMS Admin Interface&quot; /&gt;&lt;/p&gt;
&lt;h1 id=&quot;how-to-integrate-asp-net-mvc-and-blackstar-cms&quot;&gt;How to integrate ASP.NET MVC and Blackstar CMS&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Install the &lt;a href=&quot;https://www.nuget.org/packages/Blackstar/1.0.0&quot;&gt;Blackstar CMS .NET client&lt;/a&gt; from nuget&lt;/p&gt;
&lt;p&gt; &lt;code&gt;&amp;gt; Install-Package Blackstar&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Within &lt;a href=&quot;https://github.com/Blackstar-CMS/samples/blob/master/dotnet/dotnetSample/Controllers/HomeController.cs&quot;&gt;the MVC controller&lt;/a&gt; request the required content (e.g. all content with the ‘blackstarpedia’ tag).&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-C#&quot;&gt;public async Task&amp;lt;ActionResult&amp;gt; Index()
{
    var client = new BlackstarClient(&amp;quot;http://demo.blackstarcms.net&amp;quot;);
    var content = await client.GetByTagAsync(&amp;quot;blackstarpedia&amp;quot;);
    return View(HomeModel.FromContentChunks(content));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Within &lt;a href=&quot;https://github.com/Blackstar-CMS/samples/blob/master/dotnet/dotnetSample/Views/Home/Index.cshtml&quot;&gt;the view&lt;/a&gt; place the content in the correct locations.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; &amp;lt;h2&amp;gt;@Html.Raw(Model.smallerHeading)&amp;lt;/h2&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt; Note the use of &lt;code&gt;Html.Raw&lt;/code&gt; to prevent the content from being escaped. &lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;That’s it! For more information &lt;a href=&quot;https://github.com/Blackstar-CMS/samples&quot;&gt;grap the code from github, or have a look at one of the other sample projects&lt;/a&gt;. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>Blackstar CMS Angular2 (AngularJS) Sample</title>
      <link>http://withouttheloop.com/articles/2016-05-15-blackstar-angularjs/</link>
      <pubDate>Sun, 15 May 2016 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2016-05-15-blackstar-angularjs/</guid>
      <author></author>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;http://blackstarcms.net/&quot;&gt;Blackstar CMS&lt;/a&gt; now has a &lt;a href=&quot;https://github.com/Blackstar-CMS/samples#angular2-seed&quot;&gt;public sample showing how to add managed content to an Angular2 (AngularJS) application&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;logo.png&quot; alt=&quot;AngularJS&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Most, if not all, public facing web applications would benefit from some content management to give administrators a way to keep the content current and to experiment with different marketing material. &lt;a href=&quot;http://withouttheloop.com/articles/2016-04-26-blackstar-headless-cms/&quot;&gt;Building applications inside of a CMS has been tried and found wanting&lt;/a&gt;. Recently, I &lt;a href=&quot;http://withouttheloop.com/articles/2016-04-27-headless-cms/&quot;&gt;introduced Blackstar CMS&lt;/a&gt; as a solution to this problem.&lt;/p&gt;
&lt;p&gt;To help developers learn how to use Blackstar CMS to add managed content to their applications I am producing a number of samples, including one for AngularJS.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/Blackstar-CMS/samples#angular2-seed&quot;&gt;Blackstar CMS AngularJS Sample&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This sample is based on &lt;a href=&quot;https://github.com/angular/angular2-seed&quot;&gt;Google’s Angular2 seed sample&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Start the Angular2 sample with &lt;code&gt;npm start&lt;/code&gt; and you will see:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;home.png&quot; alt=&quot;Angular2 Seed Home&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The little pencil icons indicate the managed content. If I click the pencil icon next to the ‘Home Component’ heading I am taken to the Blackstar CMS edit page for that content:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;blackstaredit.png&quot; alt=&quot;Blackstar CMS Edit Page&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Now I can change the content to something more appropriate like ‘Angular2 Seed with Blackstar CMS’:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;blackstarupdated.png&quot; alt=&quot;Blackstar CMS Edit Page&quot; /&gt;&lt;/p&gt;
&lt;p&gt;and now the content has been changed:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;homeupdated.png&quot; alt=&quot;Blackstar CMS Edit Page&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The change to the Angular2 Seed sample to make this work was trivial. &lt;/p&gt;
&lt;h3 id=&quot;steps-used-to-integrate-angular2-and-blackstar-cms&quot;&gt;Steps used to integrate angular2 and Blackstar CMS&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Add the Blackstar CMS JavaScript Client&lt;/p&gt;
&lt;p&gt;&lt;code&gt;npm install blackstar-cms-client&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a typescript definition file (&lt;a href=&quot;https://github.com/Blackstar-CMS/samples/blob/master/angular2-seed/src/app/components/home/blackstar-cms-client.d.ts&quot;&gt;blackstar-cms-client.d.ts&lt;/a&gt;) for Blackstar CMS JavaScript client (included in the npm package). &lt;em&gt;This step is only necessary for projects that use Typescript&lt;/em&gt;.  &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Remove the hard coded content from &lt;a href=&quot;https://github.com/Blackstar-CMS/samples/blob/master/angular2-seed/src/app/components/home/home.html&quot;&gt;home.html&lt;/a&gt; and add &lt;code&gt;data-blackstar-name&lt;/code&gt; attributes with appropriate names:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-html&quot;&gt; &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;h3&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;data-blackstar-name&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;home-title&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;h3&lt;/span&gt;&amp;gt;&lt;/span&gt;
 &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;name&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;data-blackstar-name&lt;/span&gt;=&lt;span class=&quot;string&quot;&gt;&quot;home-content&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;name&quot;&gt;p&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create the content in the &lt;a href=&quot;http://demo.blackstarcms.net&quot;&gt;Blackstar CMS admin portal&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify the &lt;a href=&quot;https://github.com/Blackstar-CMS/samples/blob/master/angular2-seed/src/app/components/home/home.ts&quot;&gt;Home&lt;/a&gt; component to reference the type definition file and fetch content from Blackstar CMS and bind it to the UI:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-JavaScript&quot;&gt; &lt;span class=&quot;comment&quot;&gt;/// &amp;lt;reference path=&quot;blackstar-cms-client.d.ts&quot; /&amp;gt;&lt;/span&gt;

 ...

 export &lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Home&lt;/span&gt; &lt;/span&gt;{
     &lt;span class=&quot;keyword&quot;&gt;constructor&lt;/span&gt;() {
         &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; blackstar = &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; Blackstar.Client(&lt;span class=&quot;string&quot;&gt;'http://demo.blackstarcms.net/'&lt;/span&gt;, { &lt;span class=&quot;attr&quot;&gt;showEditControls&lt;/span&gt;: &lt;span class=&quot;literal&quot;&gt;true&lt;/span&gt; });
         blackstar.get({ &lt;span class=&quot;attr&quot;&gt;tags&lt;/span&gt;: [&lt;span class=&quot;string&quot;&gt;'angular2-seed-demo'&lt;/span&gt;] }).then(&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; (&lt;span class=&quot;params&quot;&gt;chunks&lt;/span&gt;) &lt;/span&gt;{
             blackstar.bind(chunks);     &lt;span class=&quot;comment&quot;&gt;// bind by matching data-blackstar-name values to chunk names &lt;/span&gt;
         });
     }
 }
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;There are other, more manually, ways to integrate Blackstar CMS content into an AngularJS application, but the technique shown here is an easy and effective way to get started. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>Blackstar, the API-first, headless CMS built for developers</title>
      <link>http://withouttheloop.com/articles/2016-04-27-headless-cms/</link>
      <pubDate>Wed, 27 Apr 2016 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2016-04-27-headless-cms/</guid>
      <author></author>
      <description>&lt;link rel=&quot;stylesheet&quot; href=&quot;prism.css&quot;&gt;

&lt;blockquote&gt;
&lt;p&gt;Managed content in custom applications is useful, but building applications inside of a CMS is unproductive and miserable. &lt;strong&gt;Blackstar CMS is an API-first, headless CMS, built for application developers.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;mac2.png&quot; alt=&quot;Blackstar CMS&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I recently wrote that &lt;a href=&quot;http://withouttheloop.com/articles/2016-04-26-blackstar-headless-cms/&quot;&gt;Hosting a custom application inside of a CMS is a terrible idea&lt;/a&gt;. Now, I present a solution. &lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://blackstarcms.net/&quot;&gt;Blackstar CMS&lt;/a&gt; is an API-first, headless CMS, built for application developers.&lt;/p&gt;
&lt;p&gt;It allows you to put content in your custom web application, and provide a delightful content management experience for application administrators.&lt;/p&gt;
&lt;p&gt;Blackstar CMS is currently in alpha preview. To access the alpha, signup for the Blackstar CMS newsletter below:&lt;/p&gt;
&lt;hr&gt;
&lt;!-- Begin MailChimp Signup Form --&gt;
&lt;p&gt;&lt;link href=&quot;//cdn-images.mailchimp.com/embedcode/horizontal-slim-10_7.css&quot; rel=&quot;stylesheet&quot; type=&quot;text/css&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#mc_embed_signup{background:#fff; clear:left; font:14px Helvetica,Arial,sans-serif; width:100%;}
/* Add your own MailChimp form style overrides in your site stylesheet or in this style block.
   We recommend moving this block and the preceding CSS link to the HEAD of your HTML file. */
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;/style&gt;&lt;/p&gt;
&lt;div id=&quot;mc_embed_signup&quot;&gt;
&lt;form action=&quot;//blackstarcms.us13.list-manage.com/subscribe/post?u=4c9086940c1cc2e74eb2526b9&amp;amp;id=080fe1a12f&quot; method=&quot;post&quot; id=&quot;mc-embedded-subscribe-form&quot; name=&quot;mc-embedded-subscribe-form&quot; class=&quot;validate&quot; target=&quot;_blank&quot; novalidate&gt;
    &lt;div id=&quot;mc_embed_signup_scroll&quot;&gt;
    &lt;label for=&quot;mce-EMAIL&quot;&gt;Newsletter&lt;/label&gt;
    &lt;input type=&quot;email&quot; value=&quot;&quot; name=&quot;EMAIL&quot; class=&quot;email&quot; id=&quot;mce-EMAIL&quot; placeholder=&quot;email address&quot; required&gt;
    &lt;!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups--&gt;
    &lt;div style=&quot;position: absolute; left: -5000px;&quot; aria-hidden=&quot;true&quot;&gt;&lt;input type=&quot;text&quot; name=&quot;b_4c9086940c1cc2e74eb2526b9_080fe1a12f&quot; tabindex=&quot;-1&quot; value=&quot;&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;clear&quot;&gt;&lt;input type=&quot;submit&quot; value=&quot;Subscribe&quot; name=&quot;subscribe&quot; id=&quot;mc-embedded-subscribe&quot; class=&quot;button&quot;&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/form&gt;
&lt;/div&gt;

&lt;hr&gt;
&lt;h1 id=&quot;a-tour-of-blackstar-cms&quot;&gt;A tour of Blackstar CMS&lt;/h1&gt;
&lt;p&gt;An application using Blackstar CMS to embed managed content might look something like this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;blackstarpedia.gif&quot; alt=&quot;Blackstarpedia&quot;/&gt;&lt;/p&gt;
&lt;p&gt;If I, as an application administrator, want to change the main heading, I click its edit link, and am taken to the blackstar edit page:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;edit.png&quot; alt=&quot;Edit&quot;/&gt; &lt;/p&gt;
&lt;p&gt;I can make a change, and see it reflected immediately:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;blackstarpedia2.png&quot; alt=&quot;Blackstarpedia updated&quot;/&gt;&lt;/p&gt;
&lt;p&gt;Some core design goals for blackstar are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;it should be simple for developers to integrate into their application and simple for administrators to use to manage content&lt;/li&gt;
&lt;li&gt;it should be deployed on premise (see Why a SaaS CMS is not for everyone)&lt;/li&gt;
&lt;li&gt;it should be simple to deploy and administer&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;the-developer-experience&quot;&gt;The Developer Experience&lt;/h1&gt;
&lt;p&gt;There are different ways to integrate with Blackstar CMS. For a SPA type application this can be done by including elements decorated with the &lt;code class=&quot; language-markup&quot;&gt;data-blackstar-name&lt;/code&gt; attribute. This tells Blackstar the name of the content chunk that should be inserted into that element. Here is an example from the BlackstarPedia demo.&lt;/p&gt;&lt;/p&gt;
&lt;pre class=&quot; language-markup&quot;&gt;&lt;code class=&quot; language-markup&quot;&gt;&amp;lt;h2 data-blackstar-name=&quot;smaller-heading&quot;/&amp;gt;
&amp;lt;div data-blackstar-name=&quot;second-content&quot;/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code class=&quot; language-markup&quot;&gt;smaller-heading&lt;/code&gt; and &lt;code class=&quot; language-markup&quot;&gt;second-content&lt;/code&gt; are the names of Blackstar content chunks. &lt;/p&gt;

&lt;p&gt;Next, add the Blackstar client script, create a client, and specify what content should be bound to this page (all chunks with the tag &lt;code class=&quot; language-markup&quot;&gt;blackstarpedia&lt;/code&gt;). &lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot; language-javascript&quot;&gt;&amp;lt;script src=&quot;blackstar-cms-client.js&quot;&amp;gt;&amp;lt;/script&amp;gt;

var blackstar = new Blackstar.Client('http://localhost:2999/', { showEditControls: true });
blackstar.get({ tags: ['blackstarpedia'] }).then(function (chunks) {
  blackstar.bind(chunks);     // bind by matching data-blackstar-name values to chunk names 
});
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That’s enough to populate the page with content and allow application administrators access to create and edit content. &lt;/p&gt;
&lt;p&gt;Blackstar CMS content can also be accessed via HTTP or a &lt;a href=&quot;https://github.com/Blackstar-CMS/javascript-client/blob/master/api.md&quot;&gt;JavaScript client&lt;/a&gt; (browser or node.js). &lt;/p&gt;
&lt;h1 id=&quot;why-a-saas-cms-is-not-for-everyone&quot;&gt;Why a SaaS CMS is not for everyone&lt;/h1&gt;
&lt;p&gt;When I searched for a developer-oriented CMS designed for adding manageable content to custom applications I found a crowded market of hosted solutions (SaaS) and very little support for self-hosting. There are three reasons why I think that a hosted CMS is a bad idea for most situations.&lt;/p&gt;
&lt;h2 id=&quot;1-it-is-an-operational-dependency&quot;&gt;1. It is an operational dependency&lt;/h2&gt;
&lt;p&gt;If your hosted CMS goes down, then your application becomes unavailable, or at least has no content.   &lt;/p&gt;
&lt;h2 id=&quot;2-you-depend-upon-continued-operation-of-the-service&quot;&gt;2. You depend upon continued operation of the service&lt;/h2&gt;
&lt;p&gt;Hundreds of thousands of applications depended on a backend-as-a-service called &lt;em&gt;Parse&lt;/em&gt;. In January 2016 &lt;a href=&quot;http://blog.parse.com/announcements/moving-on/&quot;&gt;Facebook shutdown Parse&lt;/a&gt;, leaving all those customers stranded. It probably made sense for Facebook, but it left their customers with no options. Other SaaS products like &lt;a href=&quot;https://unicornfree.com/2013/why-we-shut-down-charm-on-the-eve-of-public-launch-at-48kyear-and-growing&quot;&gt;Charm shutdown before they even launch&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;When you depend upon a third-party service for the runtime operation of your application you lose control of your own destiny. &lt;/p&gt;
&lt;h2 id=&quot;3-latency&quot;&gt;3. Latency&lt;/h2&gt;
&lt;p&gt;Web applications always have &lt;em&gt;some&lt;/em&gt; latency. It’s the time it takes for a request to travel from the client to your server, and then back again. &lt;/p&gt;
&lt;p&gt;Using a SaaS CMS adds the latency of another network request. Now a request has to travel from the client, to your server, to your SaaS CMS server, back to your server, then back to the client. And that makes your app feel &lt;strong&gt;S  L  O  W&lt;/strong&gt;.  &lt;/p&gt;
&lt;p&gt;Blackstar CMS is currently in alpha preview. To access the alpha, signup for the Blackstar CMS newsletter below:&lt;/p&gt;
&lt;hr&gt;
&lt;!-- Begin MailChimp Signup Form --&gt;
&lt;p&gt;&lt;link href=&quot;//cdn-images.mailchimp.com/embedcode/horizontal-slim-10_7.css&quot; rel=&quot;stylesheet&quot; type=&quot;text/css&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#mc_embed_signup{background:#fff; clear:left; font:14px Helvetica,Arial,sans-serif; width:100%;}
/* Add your own MailChimp form style overrides in your site stylesheet or in this style block.
   We recommend moving this block and the preceding CSS link to the HEAD of your HTML file. */
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;/style&gt;&lt;/p&gt;
&lt;div id=&quot;mc_embed_signup&quot;&gt;
&lt;form action=&quot;//blackstarcms.us13.list-manage.com/subscribe/post?u=4c9086940c1cc2e74eb2526b9&amp;amp;id=080fe1a12f&quot; method=&quot;post&quot; id=&quot;mc-embedded-subscribe-form&quot; name=&quot;mc-embedded-subscribe-form&quot; class=&quot;validate&quot; target=&quot;_blank&quot; novalidate&gt;
    &lt;div id=&quot;mc_embed_signup_scroll&quot;&gt;
    &lt;label for=&quot;mce-EMAIL&quot;&gt;Newsletter&lt;/label&gt;
    &lt;input type=&quot;email&quot; value=&quot;&quot; name=&quot;EMAIL&quot; class=&quot;email&quot; id=&quot;mce-EMAIL&quot; placeholder=&quot;email address&quot; required&gt;
    &lt;!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups--&gt;
    &lt;div style=&quot;position: absolute; left: -5000px;&quot; aria-hidden=&quot;true&quot;&gt;&lt;input type=&quot;text&quot; name=&quot;b_4c9086940c1cc2e74eb2526b9_080fe1a12f&quot; tabindex=&quot;-1&quot; value=&quot;&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;clear&quot;&gt;&lt;input type=&quot;submit&quot; value=&quot;Subscribe&quot; name=&quot;subscribe&quot; id=&quot;mc-embedded-subscribe&quot; class=&quot;button&quot;&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/form&gt;
&lt;/div&gt;

&lt;hr&gt;
&lt;script src=&quot;prism.js&quot;&gt;&lt;/script&gt;</description>
    </item>
    <item>
      <title>Hosting a custom application inside of a CMS is a terrible idea</title>
      <link>http://withouttheloop.com/articles/2016-04-26-blackstar-headless-cms/</link>
      <pubDate>Tue, 26 Apr 2016 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2016-04-26-blackstar-headless-cms/</guid>
      <author></author>
      <description>&lt;blockquote&gt;
&lt;p&gt;Building applications inside of a content management system is now a failed experiment. A new style of api-first, headless content management systems inverts the relationship and provides a pleasant and productive development process. &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;dolls.jpg&quot; alt=&quot;Russian dolls&quot;/&gt;&lt;/p&gt;
&lt;h1 id=&quot;the-benefits-of-app-in-cms&quot;&gt;The Benefits of App-In-CMS&lt;/h1&gt;
&lt;p&gt;The appeal of building an application inside of a CMS is that you get stuff for free. We greedy software developers cannot resist pre-built authentication, security, widgets and of course content management. For very simple, short-lived applications where control over the output or quality engineering are not important then app-in-cms may be OK. &lt;/p&gt;
&lt;h1 id=&quot;hosting-a-custom-application-inside-of-a-cms-is-a-terrible-idea&quot;&gt;Hosting a custom application inside of a CMS is a terrible idea&lt;/h1&gt;
&lt;p&gt;The old idea about how to merge user editable content into custom applications was to build applications inside of content management systems. Early productivity advantages (such as built-in user management and authentication) are soon overtaken by compromises required to stay within the CMS framework and challenges related to versioning and deployment. Architectural and functional compromises soon leak out and affect the user. It is common to get three months into a CMS-based application development project only to realise that it should have been a standalone application and that the CMS framework is now a liability. When designing and building software applications we should try to avoid such architectural dead ends.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;deadend.jpg&quot; alt=&quot;Dead end&quot;/&gt;&lt;/p&gt;
&lt;p&gt;The biggest problem with app-in-cms is that the application developer surrenders control of the application. The CMS is a framework that you must work within and this leads to hacks, compromise and compounding technical debt. &lt;/p&gt;
&lt;h1 id=&quot;confessions-of-an-app-in-cms-developer&quot;&gt;Confessions of an app-in-cms developer&lt;/h1&gt;
&lt;p&gt;I know that app-in-cms is a bad idea, because I have done it, and seen it done. For me, this was DotNetNuke. I have seen the same experiment repeated with Sharepoint, Sitefinity, Kentico and Umbraco. The result is a predictable, rapid accumulation of unresolvable technical debt.  &lt;/p&gt;
&lt;p&gt;Years after my last DotNetNuke project I worked on a large ecommerce application. Because it was a business to consumer ecommerce application, marketing was a primary concern, and that means that the ability to manage content was essential. The problem was solved by reserving fixed banner ads throughout the site. When the marketing team wished to modify content they would create new banner ads of the prescribed dimensions and upload them to the site. When the user’s cache expired they would receive the new banner ad with its new content. This process was labour intensive, horribly inflexible and bad for users who were subjected to too much tiny, low resolution text in banner ad images. The landing page of the site, and some associated content pages, were served from a CMS system. When the user started an ecommerce process they transitioned into a custom application that had to be synchronized to the CMS front-end so that the transition was not obvious to the user. What a mess. &lt;/p&gt;
&lt;p&gt;More recently I was involved in another business-to-consumer project that required content managemed by the marketing department. After investigating possible integration with a content management system the team decided to instead build their own micro CMS features into the application so that application administrators could modify certain pieces of content. This is a better solution than replaceable banner ads but it is still inflexible and costly, having consumed some $10k of the project’s budget. &lt;/p&gt;
&lt;p&gt;Hopefully I have given sufficient examples to demonstrate that content management within custom applications is a common problem, and the traditional app-in-cms is not the answer.&lt;/p&gt;
&lt;h1 id=&quot;the-headless-cms-solution&quot;&gt;The headless CMS solution&lt;/h1&gt;
&lt;p&gt;A headless CMS looks after managing content and delivers it &lt;strong&gt;via an API&lt;/strong&gt;. The CMS is not your application, it is not responsible for rendering pages, it simply makes content available. It has no templates, themes or views. It has only content with metadata, a way to get that content, and a way to maintain that content. For example, here is a simple request made to a headless CMS for all content tagged &lt;em&gt;index-page&lt;/em&gt;. Note that the response (lower right) is an array of JSON data containing the content:&lt;/p&gt;
&lt;iframe src=&quot;http://wurl.io/template/1ef1756b-379c-4a27-8c7d-568c2f61c775&quot; style=&quot;width: 100%;height:400px;&quot; frameborder=&quot;0&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;Within a custom application you then have the responsibility of transforming the json content into an acceptable view. But now application administrators have the ability to maintain content without affecting the development team. &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;For custom applications, a headless CMS is a much better solution than the traditional full CMS.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This inverts the APP &amp;lt;-&amp;gt; CMS relationship, putting the application back in charge, with embedded CMS content. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;dolls2.jpg&quot; alt=&quot;russian dolls again&quot;/&gt;&lt;/p&gt;
&lt;h1 id=&quot;summary&quot;&gt;Summary&lt;/h1&gt;
&lt;p&gt;An api-first, headless CMS is a good choice for adding managed content to web applications, and many web applications, especially those that are public facing, would benefit from managed content. The alternative, building an application inside of a CMS platform, leads to hacks, compromise and compounding technical debt.  &lt;/p&gt;
</description>
    </item>
    <item>
      <title>React Forms</title>
      <link>http://withouttheloop.com/articles/2016-04-15-react-forms/</link>
      <pubDate>Fri, 15 Apr 2016 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2016-04-15-react-forms/</guid>
      <author></author>
      <description>&lt;p&gt;&lt;img src=&quot;spider.jpg&quot; alt=&quot;spider (Argiope bullocki)&quot; style=&quot;width:300px&quot; align=&quot;right&quot;/&gt;&lt;/p&gt;
&lt;p&gt;As I have &lt;a href=&quot;http://withouttheloop.com/articles/2014-05-29-react-flux-etc/&quot;&gt;said before&lt;/a&gt;, React focuses on mapping user interface state to the DOM and publishing events. It doesn’t try to help with common application tasks like routing, http requests, or managing forms. So how do we work with forms in React?&lt;/p&gt;
&lt;h1 id=&quot;the-basic-react-form-pattern&quot;&gt;The Basic React Form Pattern&lt;/h1&gt;
&lt;p&gt;The design of React leads to a curious contradiction for forms. &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If the user interface is a transformation of the user interface state then it should not be possible to modify the content of a form without updating the application state&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And this is exactly where we start with React forms. Here is the most basic form implementation possible. The application model is bound to the form fields. Note that it is not possible for the user to modify the content of the form (see the ‘Result’ tab). It would not make sense because the form is supposed to be a reflection of the application state. &lt;/p&gt;
&lt;iframe width=&quot;100%&quot; height=&quot;300&quot; src=&quot;//jsfiddle.net/69z2wepo/38770/embedded/js,result/&quot; allowfullscreen=&quot;allowfullscreen&quot; frameborder=&quot;0&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;The way to solve this problem is to break one of my own rules of working with React - we let the component maintain local state. The risk here is that the content of the form could become inconsistent with the application state. For the content of a form, this is something that I can live with. The above example, modified to use local component state for the content of the form is:&lt;/p&gt;
&lt;iframe width=&quot;100%&quot; height=&quot;300&quot; src=&quot;//jsfiddle.net/69z2wepo/38772/embedded/js,result/&quot; allowfullscreen=&quot;allowfullscreen&quot; frameborder=&quot;0&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;The form fields are no longer bound to the components properties. Instead they are bound to local state, that is copied from the components properties (in the &lt;code&gt;getInitialState()&lt;/code&gt; lifecycle method). That provides one-way binding from the state to the form. To bind changes to the form back to the component state we need the &lt;code&gt;bindState&lt;/code&gt; method. &lt;code&gt;bindState&lt;/code&gt; creates event handlers that push changes to the form back to the component state. Everytime the user modifies a character in a form field it is pushed back to the component state, which causes the component to re-render with the new form content. We now have a form that allows the user to change form field values. &lt;/p&gt;
&lt;p&gt;We can then add a form submission handler to deal with changes to the form when it is submitted. &lt;/p&gt;
&lt;iframe width=&quot;100%&quot; height=&quot;300&quot; src=&quot;//jsfiddle.net/69z2wepo/38773/embedded/js,result/&quot; allowfullscreen=&quot;allowfullscreen&quot; frameborder=&quot;0&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;Because we have been synchronizing the form to the component state on every character change we already have the latest content of the form in the state. So what do we do with it?&lt;/p&gt;
&lt;h1 id=&quot;what-to-do-with-form-submissions&quot;&gt;What To Do With Form Submissions&lt;/h1&gt;
&lt;p&gt;There are two ways to handle form submission. Which you chose depends on the type of component. If I was building a reusable widget (like a calendar or something) then I would express all results as calls to a property of the component.&lt;/p&gt;
&lt;iframe width=&quot;100%&quot; height=&quot;300&quot; src=&quot;//jsfiddle.net/69z2wepo/38774/embedded/js,result/&quot; allowfullscreen=&quot;allowfullscreen&quot; frameborder=&quot;0&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;Note how &lt;code&gt;onSubmit&lt;/code&gt; is a callback function passed to the &lt;code&gt;PersonForm&lt;/code&gt; component as a prop. When the form is ready to publish its result it simply calls the supplied &lt;code&gt;onSubmit&lt;/code&gt; function and passes its result. &lt;/p&gt;
&lt;p&gt;This approach has elegance. Components designed in this way are perfectly composable. The flipside is that components exist in a heirarchy, and results communicated via callbacks must be bounced all the way up the heirarchy to the top. Applying this strategy everywhere is a productivity and maintenance nightmare, leading to the rule:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;use callbacks to communicate results only for re-usable, widget-style components&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For other components, publish results out of your React component heirarchy to a state management solution like &lt;a href=&quot;http://withouttheloop.com/articles/2015-12-28-tetris3/&quot;&gt;redux&lt;/a&gt; to merge the changes into your application state.&lt;/p&gt;
&lt;iframe width=&quot;100%&quot; height=&quot;300&quot; src=&quot;//jsfiddle.net/69z2wepo/38776/embedded/js,result/&quot; allowfullscreen=&quot;allowfullscreen&quot; frameborder=&quot;0&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;Note that the value passed to &lt;code&gt;dispatch&lt;/code&gt; is an object of the form &lt;code&gt;{ type: &amp;#39;&amp;#39;, ... }&lt;/code&gt;. This is a redux convention. The general idea of libraries like redux/flux etc is that they take these actions, update the application state and re-render the entire application component graph, preserving the symmetry between the application state and the DOM. &lt;/p&gt;
&lt;h1 id=&quot;higher-level-form-abstractions&quot;&gt;Higher-level Form Abstractions&lt;/h1&gt;
&lt;p&gt;A great way to avoid this issue all together is to use one of many libraries providing higher-level form abstractions. Typically, the library generates an appropriate form based on a supplied piece of state. Such libraries are terrific for productivity but are at their best when you do not require precise control over the form. Once you start having to invest effort in customizing how a tool generates forms for you I think you are better off reverting to building the form yourself.  &lt;/p&gt;
&lt;h1 id=&quot;validation&quot;&gt;Validation&lt;/h1&gt;
&lt;p&gt;I wrote recently about &lt;a href=&quot;http://withouttheloop.com/articles/2016-04-14-javascript-object-validation/&quot;&gt;JavaScript object validation with JSON Schema&lt;/a&gt; so I have covered how to validate objects. The form approach described above covers how to bind objects to and from forms with React. The missing piece then is just how to trigger validation and handle displaying any validation errors to the user. I will investigate this in a future post. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>JavaScript object validation with JSON Schema</title>
      <link>http://withouttheloop.com/articles/2016-04-14-javascript-object-validation/</link>
      <pubDate>Thu, 14 Apr 2016 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2016-04-14-javascript-object-validation/</guid>
      <author></author>
      <description>&lt;p&gt;Recently I wrote about &lt;a href=&quot;http://withouttheloop.com/articles/2016-03-24-node-web-ts/&quot;&gt;Building a Web Application with Node and Typescript&lt;/a&gt;. One of the advantages of having JavaScript (Typescript) on both the client and server is that we can share validation logic between the two. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;validate.jpg&quot; alt=&quot;validating parking&quot; style=&quot;width:236px;margin:auto;&quot;/&gt;&lt;/p&gt;
&lt;h1 id=&quot;javascript-object-validation&quot;&gt;JavaScript Object Validation&lt;/h1&gt;
&lt;p&gt;There are many ways of validating JavaScript objects. &lt;/p&gt;
&lt;p&gt;The Hapi framework includes a library called &lt;a href=&quot;https://github.com/hapijs/joi&quot;&gt;Joi&lt;/a&gt; that validates objects this way:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var Joi = require(&amp;#39;joi&amp;#39;);

var schema = Joi.object().keys({
    name: Joi.string().alphanum().min(3).max(30).required(),
    age: Joi.number().integer().min(0)
}).with(&amp;#39;name&amp;#39;, &amp;#39;age&amp;#39;);

Joi.validate({ name: &amp;#39;abc&amp;#39;, age: 103 }, schema, function (err, value) { });
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Another popular choice is &lt;a href=&quot;https://github.com/flatiron/revalidator&quot;&gt;Flatiron Revalidator&lt;/a&gt;, which validates objects like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var revalidator = require(&amp;#39;revalidator&amp;#39;);

console.dir(revalidator.validate({ name: &amp;#39;abc&amp;#39;, age: 103 }, {
    properties: {
        name: {
        type: &amp;#39;string&amp;#39;,
        required: true,
        minLength: 3,
        maxLength: 30
        },
        age: {
        type: &amp;#39;integer&amp;#39;,
        minimum: 0,
        required: true
        }
    }
}));
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Years ago I even &lt;a href=&quot;http://withouttheloop.com/articles/2013-02-24-dbc/&quot;&gt;wrote my own&lt;/a&gt; &lt;a href=&quot;https://github.com/liammclennan/dbc&quot;&gt;object validation library called dbc&lt;/a&gt;. It served me well and is still powering validation on many public web applications. I would not use dbc today as there are now better options available. Dbc has some novel features that the other libraries don’t have, such as creating auto-validating objects:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var AjaxOptions = dbc.makeConstructor({
        type:       [
                        {validator:&amp;#39;type&amp;#39;, args:[&amp;#39;string&amp;#39;]},
                        {validator:&amp;#39;oneOf&amp;#39;, args:[[&amp;#39;GET&amp;#39;,&amp;#39;POST&amp;#39;,&amp;#39;PUT&amp;#39;,&amp;#39;DELETE&amp;#39;]]}
                    ],
        url:        [{validator:&amp;#39;type&amp;#39;,args:[&amp;#39;string&amp;#39;]}],
        dataType:   [{validator:&amp;#39;type&amp;#39;,args:[&amp;#39;string?&amp;#39;]}]
    });
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here, &lt;code&gt;AjaxOptions&lt;/code&gt; is a new JavaScript ‘class’ that will automatically validate when an object is created from it. &lt;/p&gt;
&lt;p&gt;It also has a feature that enforces function argument and return type validation. The following code adds validation to a function and guarantees that its argument is a &lt;code&gt;string&lt;/code&gt; and its return value is an &lt;code&gt;AjaxOptions&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;AjaxOptions.fromCorsRequest = dbc.wrap(function (corsRequestText) {
        return new AjaxOptions(new CorsRequest(corsRequestText).getJSON());
    }, {
        0: [{validator:&amp;#39;type&amp;#39;, args:[&amp;#39;string&amp;#39;]}]
    }, [{validator:&amp;#39;isInstance&amp;#39;,args:[AjaxOptions]}]);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Everyone has their own way of declaratively specifying what a valid object looks like. If only there was some kind of standard….&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;chello.jpg&quot; alt=&quot;chello&quot;/&gt;&lt;/p&gt;
&lt;h1 id=&quot;json-schema&quot;&gt;JSON Schema&lt;/h1&gt;
&lt;p&gt;JSON Schema is a standard that defines, among other things, a declarative format for specifying object validation rules. JSON Schemas are themselves defined in JSON, leading to the delightful situation of having &lt;a href=&quot;http://json-schema.org/schema&quot;&gt;a JSON Schema that defines the schema for all JSON schemas&lt;/a&gt;. JSON schema is well considered and standardised making it an excellent choice for JavaScript object validation. Now all we need is a library that can validate a JavaScript object against a JSON schema. &lt;/p&gt;
&lt;h2 id=&quot;jsonschema&quot;&gt;Jsonschema&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/tdegrunt/jsonschema&quot;&gt;Jsonschema&lt;/a&gt; is a library that validates javascript options against JSON schemas. &lt;/p&gt;
&lt;pre&gt;&lt;code&gt; var validate = require(&amp;#39;jsonschema&amp;#39;).validate;

  var schema = {
    &amp;quot;type&amp;quot;: &amp;quot;object&amp;quot;,
    &amp;quot;properties&amp;quot;: {
      &amp;quot;name&amp;quot;: {
        &amp;quot;type&amp;quot;: &amp;quot;string&amp;quot;,
        &amp;quot;minLength&amp;quot;: 3,
        &amp;quot;maxLength&amp;quot;: 30
      },
      &amp;quot;age&amp;quot;: {&amp;quot;type&amp;quot;: &amp;quot;integer&amp;quot;, minimum:0}
    },
    &amp;quot;required&amp;quot;: [&amp;quot;name&amp;quot;,&amp;quot;age&amp;quot;]
  };

  console.log(validate({ name: &amp;#39;abc&amp;#39;, age: 103 }, schema));
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;With this we have a standard, reusable validation strategy that we can use in the browser or in node. &lt;/p&gt;
&lt;p&gt;We can make things a little neater with a bit of convention. Here’s a way of validating objects that have a &lt;code&gt;schema&lt;/code&gt; method (code is ES2015):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import {validate} from &amp;#39;jsonschema&amp;#39;;

class Person {
    constructor(name,age) {
        this.name = name;
        this.age = age;
    }
    schema() {
        return {
            &amp;quot;type&amp;quot;: &amp;quot;object&amp;quot;,
            &amp;quot;properties&amp;quot;: {
            &amp;quot;name&amp;quot;: {
            &amp;quot;type&amp;quot;: &amp;quot;string&amp;quot;,&amp;quot;minLength&amp;quot;: 3,&amp;quot;maxLength&amp;quot;: 30
            },
            &amp;quot;age&amp;quot;: {&amp;quot;type&amp;quot;: &amp;quot;integer&amp;quot;, minimum:0}
            },
            &amp;quot;required&amp;quot;: [&amp;quot;name&amp;quot;,&amp;quot;age&amp;quot;]
        }
    }   
}

function validateObjectWithSchema(obj) {
    return validate(obj, obj.schema());
}

let p = new Person(&amp;quot;abc&amp;quot;,103);
console.log(validateObjectWithSchema(p));
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&quot;final-thoughts&quot;&gt;Final Thoughts&lt;/h1&gt;
&lt;p&gt;To benefit from validation we need to hook it into our application. Common places to do this are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;form validation in the browser&lt;/li&gt;
&lt;li&gt;request validation on the server&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Both of these are fairly simple. I will show some examples in future posts.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Building a Web Application with Node and Typescript</title>
      <link>http://withouttheloop.com/articles/2016-03-24-node-web-ts/</link>
      <pubDate>Thu, 24 Mar 2016 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2016-03-24-node-web-ts/</guid>
      <author></author>
      <description>&lt;p&gt;For the purpose of this article I define a &lt;em&gt;web application&lt;/em&gt; as a HTTP network service, such as what we might build with Asp.NET MVC, Ruby on Rails, Django, Php etc. This article will demonstrate how to write a web application in Typescript that runs on Node.js. &lt;/p&gt;
&lt;h1 id=&quot;why-do-this-&quot;&gt;Why do this?&lt;/h1&gt;
&lt;p&gt;Running as much of an application as possible on the client creates a richer user experience and a better perception of performance. Unfortunately, the client cannot be trusted so enevitably a lot of an application’s logic must remain on the server, within the circle of trust. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2016-03-24-node-web-ts/circle.jpg&quot; alt=&quot;Circle of trust&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;enable-code-sharing&quot;&gt;Enable code sharing&lt;/h2&gt;
&lt;p&gt;This unpleasent client/server split can be made a little more bearable by sharing code between the two halves of the application, and this is easier if the code on both sides is written in the same programming language. Useful things to share include types, validation and application specific computations.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2016-03-24-node-web-ts/share.jpg&quot; alt=&quot;Sharing&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;benefits-of-node&quot;&gt;Benefits of Node&lt;/h2&gt;
&lt;p&gt;Node has some advantages as a web server. It is fast, simple and inherently  safely asynchronous. &lt;/p&gt;
&lt;p&gt;Node enables cross platform development and deployment by running well on windows, mac and linux. &lt;/p&gt;
&lt;p&gt;Node has the fastest growing, if not the best quality, package repository. It is a vibrant and creative ecosystem of people who are excited about programming. Consequently, they &lt;a href=&quot;https://www.reddit.com/r/learnprogramming/comments/4bo951/eli5_this_whole_fiasco_with_javascript_node_and/&quot;&gt;wet their pants&lt;/a&gt; from time to time.&lt;/p&gt;
&lt;h2 id=&quot;benefits-of-typescript&quot;&gt;Benefits of Typescript&lt;/h2&gt;
&lt;p&gt;The static vs dynamic typing debate is beyond the scope of this article. Suffice to say that having compile time type checking can help the self-aware programmer to write more correct software. It is also useful when sharing types between the server and client. &lt;/p&gt;
&lt;p&gt;Typescript has &lt;em&gt;‘optional static typing’&lt;/em&gt;, meaning that you can relax the type checking when it feels good to do so. This can be useful when you want to do dynamic type things and when you are integrating with JavaScript libraries. &lt;/p&gt;
&lt;h1 id=&quot;get-started-with-node-and-typescript&quot;&gt;Get Started With Node and Typescript&lt;/h1&gt;
&lt;p&gt;Step 1, &lt;a href=&quot;http://withouttheloop.com/articles/2016-03-24-node-web-ts/install%20node.js&quot;&gt;https://nodejs.org/en/&lt;/a&gt;. Node itself is just an executable, so you don’t really &lt;strong&gt;need&lt;/strong&gt; to install it, but doing so will be easier and will install the node package manager (npm) as well. &lt;/p&gt;
&lt;p&gt;Next, install typescript, via npm:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ npm install -g typescript
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now create your first typescript program (person.ts):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;interface Person {
    name: string;
    age: number;
}

function birthday(someone : Person) : Person {
    return {name: someone.name, age: someone.age+1};
}

console.dir(birthday({name:&amp;quot;Judy&amp;quot;,age:39}));
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and compile using the typescript compiler (tsc):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ tsc person.ts
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The output of the typescript compiler is the javascript file &lt;code&gt;person.js&lt;/code&gt;, which contains:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function birthday(someone) {
    return { name: someone.name, age: someone.age + 1 };
}
console.dir(birthday({ name: &amp;quot;Judy&amp;quot;, age: 39 }));
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Wooh! That’s just the typescript with the type annotations striped out. This makes sense because typescript is a compile time system, not a runtime system.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Typescript is a compile time system, not a runtime system. &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Keeping this in mind will help you as you pickup typescript. &lt;/p&gt;
&lt;p&gt;Now we can run our program with node.js&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ node person.js
{ name: &amp;#39;Judy&amp;#39;, age: 40 }
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now to show what makes typescript useful. Let’s intentionally introduce a type error into our program:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;interface Person {
    name: string;
    age: number;
}

function birthday(someone : Person) : Person {
    return {handle: someone.name, age: someone.age+1};
}

console.dir(birthday({name:&amp;quot;Judy&amp;quot;,age:39}));
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;See the type error? The &lt;code&gt;birthday&lt;/code&gt; function returns a value that is not valid for the type &lt;code&gt;Person&lt;/code&gt;. When we compile:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ tsc person.ts
person.ts(7,13): error TS2322: Type &amp;#39;{ handle: string; age: number; }&amp;#39; 
is not assignable to type &amp;#39;Person&amp;#39;.
  Object literal may only specify known properties, 
  and &amp;#39;handle&amp;#39; does not exist in type &amp;#39;Person&amp;#39;.
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&quot;adding-a-web-framework&quot;&gt;Adding a Web Framework&lt;/h1&gt;
&lt;p&gt;Typescript relies heavily on the JavaScript ecosystem. As mentioned previously typescript does not exist at runtime. So it needs the JavaScript runtime, the JavaScript (or node) standard library, and JavaScript packages. &lt;/p&gt;
&lt;p&gt;For this article we will work with the node web framework &lt;a href=&quot;http://definitelytyped.org/tsd/&quot;&gt;hapi&lt;/a&gt;. Hapi is a javascript framework. To use it in a typescript project we need a type definition file to tell typescript about the types used in hapi. To find Typescript type definitions search the &lt;a href=&quot;http://definitelytyped.org/tsd/&quot;&gt;definitely typed site&lt;/a&gt; which is a repository of typescript type definition files. The easiest way to install a type definition is to use &lt;a href=&quot;https://github.com/Definitelytyped/tsd#install&quot;&gt;tsd&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ npm install tsd -g
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now you can install the type definitions for Hapi:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ tsd install hapi --save
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Unfortunately there is nothing synchonizing typescript type definitions to the libraries they define, and when the two get out of sync it causes frustration. I recommend:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Start by choosing libraries that have TSD type definitions. You can create your own but it is not easy. &lt;/li&gt;
&lt;li&gt;Install the type definition. Inspect its source to discover which version of the JavaScript library the type definition was written for.&lt;/li&gt;
&lt;li&gt;Install that version of the JavaScript library.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For me, TSD installed type definitions for hapi 13.0.0, so that is the version of the Javascript library I want to install:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ npm install hapi@13.0.0 --save
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now create a new typescript program &lt;code&gt;server.ts&lt;/code&gt;. The first line should be:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/// &amp;lt;reference path=&amp;quot;typings/tsd.d.ts&amp;quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;tsd.d.ts&lt;/code&gt; is a file created by TSD that references the type definitions for all included libraries. This comment tells the typescript compiler where to find type definitions. &lt;/p&gt;
&lt;p&gt;Next, add the code for a simple hapi web server:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/// &amp;lt;reference path=&amp;quot;typings/tsd.d.ts&amp;quot; /&amp;gt;

import * as Hapi from &amp;#39;hapi&amp;#39;;

const server = new Hapi.Server();
server.connection({ 
    host: &amp;#39;localhost&amp;#39;, 
    port: 8000 
});

server.route({
    method: &amp;#39;GET&amp;#39;,
    path:&amp;#39;/hello/{name}&amp;#39;, 
    handler: function (request, reply) {

        return reply(&amp;#39;hello &amp;#39; + request.params[&amp;#39;name&amp;#39;]);
    }
});

server.start((err) =&amp;gt; {
    if (err) { throw err; }
    console.log(&amp;#39;Server running at:&amp;#39;, server.info.uri);
});
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Compile and start:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ tsc server.ts
$ node server.js
Server running at: http://localhost:8000
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now navigate your browser (or curl) to &lt;code&gt;http://localhohst:8000/hello/Eugene&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ curl http://localhost:8000/hello/Eugene
hello Eugene
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;automatically-compiling-and-restarting-the-server&quot;&gt;Automatically Compiling and Restarting the Server&lt;/h2&gt;
&lt;p&gt;The development workflow at this point is clunky. When a change is made to the typescript source you need to recompile the application, then restart the hapi server to pickup the changes.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ tsc server.ts
$ node server.js
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This gets old quickly. We can have typescript automatically detect and compile changes by using the -w flag:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ tsc server.ts -w
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Not only is this more convenient, it is also faster. By keeping the process alive typescript is able to implement incremental compilation (only recompile the bits that have changed). &lt;/p&gt;
&lt;p&gt;To automatically restart the server we can use the &lt;code&gt;node-dev&lt;/code&gt; package.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ npm install node-dev -g
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then run the program with &lt;code&gt;node-dev&lt;/code&gt; instead of &lt;code&gt;node&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ node-dev server.js
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;node-dev&lt;/code&gt; detects when a required module is changed and restarts the process. &lt;/p&gt;
&lt;h1 id=&quot;performance&quot;&gt;Performance&lt;/h1&gt;
&lt;p&gt;Node is supposed to be fast right? As written, our simple server is processes about 1,600 reqs/s. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2016-03-24-node-web-ts/single.png&quot; alt=&quot;single threaded&quot;&gt;&lt;/p&gt;
&lt;p&gt;Not bad, but nothing special considering it doesn’t do much. This is because node is single threaded and therefore only capable of utilizing a single CPU core. We can fix this (somewhat) using node’s ‘cluster’ module to start a process per CPU core. The clustered code looks like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/// &amp;lt;reference path=&amp;quot;typings/tsd.d.ts&amp;quot; /&amp;gt;

import * as cluster from &amp;#39;cluster&amp;#39;;
import { cpus } from &amp;#39;os&amp;#39;;
import * as Hapi from &amp;#39;hapi&amp;#39;;

const numCPUs = cpus().length;

if (cluster.isMaster) {
  for (var i = 0; i &amp;lt; numCPUs; i++) {
    cluster.fork();
  }
  cluster.on(&amp;#39;exit&amp;#39;, (worker, code, signal) =&amp;gt; {
    console.log(`worker ${worker.process.pid} died`);
  });
} else {
    const server = new Hapi.Server();
    server.connection({ 
        host: &amp;#39;localhost&amp;#39;, 
        port: 8000 
    });

    server.route({
        method: &amp;#39;GET&amp;#39;,
        path:&amp;#39;/hello/{name}&amp;#39;, 
        handler: (request, reply) =&amp;gt; reply(&amp;#39;hello &amp;#39; + request.params[&amp;#39;name&amp;#39;])
    });

    server.start((err) =&amp;gt; {
        if (err) { throw err; }
        console.log(&amp;#39;Server running at:&amp;#39;, server.info.uri);
    }); 
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This pushes the reqs/s up to 5,700.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2016-03-24-node-web-ts/rps.png&quot; alt=&quot;requests per second&quot;&gt;&lt;/p&gt;
&lt;p&gt;That’s better :)&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Is it time to learn F#?</title>
      <link>http://withouttheloop.com/articles/2016-03-18-time-to-learn-fsharp/</link>
      <pubDate>Fri, 18 Mar 2016 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2016-03-18-time-to-learn-fsharp/</guid>
      <author></author>
      <description>&lt;blockquote&gt;
&lt;p&gt;TL;DR After a marathon production process I have finally released a new screencast, “&lt;a href=&quot;https://app.pluralsight.com/library/courses/fsharp-fundamentals/table-of-contents&quot;&gt;F# Fundamentals&lt;/a&gt;“ for Pluralsight.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://app.pluralsight.com/library/courses/fsharp-fundamentals/table-of-contents&quot;&gt;&lt;img src=&quot;pluralsight.png&quot; alt=&quot;pluralsight&quot; style=&quot;width:300px;margin:auto;&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;2015 was a big year for functional programming (FP), with many high-profile successes.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://code.facebook.com/posts/745068642270222/fighting-spam-with-haskell/&quot;&gt;Facebook implemented its anti-spam system using Haskell&lt;/a&gt;, and its flow and hack compilers using OCaml.&lt;/li&gt;
&lt;li&gt;There were a number of highly subscribed &lt;a href=&quot;https://www.edx.org/course/introduction-functional-programming-delftx-fp101x-0&quot;&gt;FP&lt;/a&gt; &lt;a href=&quot;https://www.coursera.org/course/progfun&quot;&gt;MOOCS&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.janestreet.com/technology/&quot;&gt;Jane Street continued to build a successful trading business on OCaml&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;There was a pronounced shift towards FP style in JavaScript tooling such as Elm, React, RxJS, Immutable.js and Angular2.&lt;/li&gt;
&lt;li&gt;The &lt;a href=&quot;http://www.slideshare.net/deanwampler/why-scala-is-taking-over-the-big-data-world&quot;&gt;big data ecosystem moved towards scala as a de-facto standard&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Developers are discovering that FP helps them to be clearer and more rigorous in their programming. A maturing industry is discovering a set of more capable tools.&lt;/p&gt;
&lt;h1 id=&quot;is-it-time-to-learn-functional-programming-&quot;&gt;Is it time to learn functional programming?&lt;/h1&gt;
&lt;p&gt;Probably.&lt;/p&gt;
&lt;p&gt;Either you will discover a whole new level of programming skill and productivity, or you will learn why it is not for you. Surely either option is better than ignorance?&lt;/p&gt;
&lt;h1 id=&quot;is-it-time-to-learn-f-&quot;&gt;Is it time to learn F#?&lt;/h1&gt;
&lt;p&gt;Yes. If you work with .NET then F# should be one tool in your toolbox. &lt;/p&gt;
&lt;p&gt;The biggest uptake of functional programming has been in the tools that are able to benefit from a larger ecosystem. Scala and Clojure have benefitted from targeting the JVM. This allows them to be used anywhere Java is expected, to run on the JVM and to access the Java standard library. In the .NET world F# is the equivalent. It is a functional programming language that runs on the .NET CLR and has access to the .NET base class library.&lt;/p&gt;
&lt;p&gt;Still not sure? Have a look at this &lt;a href=&quot;http://fsharpforfunandprofit.com/why-use-fsharp/&quot;&gt;excellent article&lt;/a&gt; describing the benefits of F# and functional programming.&lt;/p&gt;
&lt;h1 id=&quot;how-&quot;&gt;How?&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;http://www.tryfsharp.org/&quot;&gt;Try F#&lt;/a&gt; lets you experiment with F# programming in your browser. &lt;a href=&quot;http://fsharpforfunandprofit.com/&quot;&gt;http://fsharpforfunandprofit.com/&lt;/a&gt; has lots of great content.&lt;/p&gt;
&lt;p&gt;Finally, I have recorded a &lt;a href=&quot;https://app.pluralsight.com/library/courses/fsharp-fundamentals/table-of-contents&quot;&gt;six hour screencast (F# Fundamentals)&lt;/a&gt; that takes the student from no knowledge of F# to a intermediate level sufficient for creating console applications, services and web applications.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Implementing Tetris with React and Redux - VII</title>
      <link>http://withouttheloop.com/articles/2016-01-11-tetris7/</link>
      <pubDate>Mon, 11 Jan 2016 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2016-01-11-tetris7/</guid>
      <author></author>
      <description>&lt;p&gt;Previously, we converted the application to Typescript. In this episode we will implement collapsing rows, game ending and scoring.&lt;/p&gt;
&lt;p&gt;To follow along with this article checkout the commit &lt;a href=&quot;https://github.com/liammclennan/tetris/commit/e843d275a52d7ad72862b663638bb84d098f9c07&quot;&gt;e843d2&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ git clone https://github.com/liammclennan/tetris.git
$ git checkout e843d2
$ npm run bootstrap
$ npm run likehell
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&quot;collapsing-rows&quot;&gt;Collapsing Rows&lt;/h1&gt;
&lt;p&gt;In tetris rows collapse when they are full. The first step required for implementing this behaviour is to be able to detect full rows. Start with a test:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;describe(&amp;#39;game with last row full&amp;#39;, ()=&amp;gt; {
    var game = new Models.Game(()=&amp;gt;{});
    game.rubble = _.range(1, game.cols+1).map(col =&amp;gt; new Models.Point(game.rows, col));

    it(&amp;#39;should have one completed row&amp;#39;, ()=&amp;gt; assert.equal(1, game.completedRows().length));
    it(&amp;#39;should have row 15 as completed&amp;#39;, ()=&amp;gt; assert.equal(15, game.completedRows()[0]));
});
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and implement the &lt;code&gt;Game.completedRows()&lt;/code&gt; method. I have used &lt;a href=&quot;http://underscorejs.org/&quot;&gt;underscore&lt;/a&gt; to generate ranges. The method works by finding all the rows for which every column contains rubble.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;completedRows() {
    return _.range(1,this.rows+1).filter(row =&amp;gt;
          _.range(1,this.cols+1).every(col =&amp;gt; this.rubbleHas(row,col))
    );
}
rubbleHas(row,col) {
        return this.rubble.some(point =&amp;gt; point.row === row &amp;amp;&amp;amp; point.col === col);
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Next we need to collapse full rows when they are found. This involves removing all the rubble in the collapsed row, and then shifting all other rubble down. Again, start with a test:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;describe(&amp;#39;collapsing&amp;#39;, ()=&amp;gt; {
    var game = new Models.Game(()=&amp;gt;{});

    var row14 =  [new Models.Point(game.rows-1,1), new Models.Point(game.rows-1, 2)];
    game.rubble = _.range(1, game.cols+1)
      .map(col =&amp;gt; new Models.Point(game.rows, col))
      .concat(row14);

    it(&amp;#39;should move row 14 to row 15 (collapse)&amp;#39;, ()=&amp;gt; {
      assert.equal(22, game.rubble.length);
      game.collapseRow(15);
      assert.equal(2, game.rubble.length, &amp;#39;the full row has been deleted&amp;#39;);
      assert.ok(_.some(game.rubble, point =&amp;gt; point.row === 15 &amp;amp;&amp;amp; point.col === 1), &amp;#39;a point from the 2nd row has moved down&amp;#39;);
      assert.ok(_.some(game.rubble, point =&amp;gt; point.row === 15 &amp;amp;&amp;amp; point.col === 2), &amp;#39;the other point from the 2nd row has moved down&amp;#39;);
    });
});
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And then implement:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;collapseRow(row) {
    this.rubble = this.rubble.filter(point =&amp;gt; point.row !== row);
    this.rubble.filter(point =&amp;gt; point.row &amp;lt; row).forEach(point =&amp;gt; point.row += 1);
}
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&quot;ending-the-game&quot;&gt;Ending the Game&lt;/h1&gt;
&lt;p&gt;The game should end when rubble reaches the top of the game area. The game object therefore has all the information required to know if the game has finished:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;   isGameOver() {
    return this.rubble.some(point =&amp;gt; point.row === 1);
  }
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt; Then at the end of the tick processing (&lt;code&gt;convertToRubble&lt;/code&gt;) we know not to start a new piece if the game has ended:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;convertToRubble() {
    this.rubble = this.rubble.concat(this.fallingPiece.points());
    this.completedRows().forEach(r =&amp;gt; this.collapseRow(r));
    if (!this.isGameOver()) {
      this.startAPiece();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We should also check when processing actions:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function reducer(state = new Model.Game(()=&amp;gt;{}), action) {
  if (state.isGameOver()) return state;

  switch (action.type) {
      case &amp;#39;TICK&amp;#39;:
        const revedState = state.tick();
        if (!revedState.isGameOver()) {
          setTimeout(() =&amp;gt; store.dispatch({ type: &amp;#39;TICK&amp;#39; }),300);
        }
        return revedState;
      case &amp;#39;ROTATE&amp;#39;:
        return state.rotate();
      case &amp;#39;LEFT&amp;#39;:
        return state.left();
      case &amp;#39;RIGHT&amp;#39;:
        return state.right();
      default: return state;
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This effectively stops the TICK loop once the game ends.&lt;/p&gt;
&lt;p&gt;Then we can change &lt;code&gt;GameView&lt;/code&gt; component to change the UI when the game ends:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export var GameView = React.createClass&amp;lt;GameViewProps,any&amp;gt;({
  render: function () {
    return &amp;lt;div className=&amp;quot;border&amp;quot; style={{width: this.props.game.cols*25, height: this.props.game.rows*25}}&amp;gt;
      { this.props.game.isGameOver() ?
        &amp;lt;span&amp;gt;GAME OVER&amp;lt;/span&amp;gt; : &amp;lt;span&amp;gt;
        &amp;lt;PieceView piece={this.props.game.fallingPiece} /&amp;gt;
        &amp;lt;RubbleView rubble={this.props.game.rubble} /&amp;gt;
        &amp;lt;/span&amp;gt;
      }
    &amp;lt;/div&amp;gt;;
  }
});
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;img src=&quot;gameover.png&quot; alt=&quot;Game Over&quot; /&gt;&lt;/p&gt;
&lt;h1 id=&quot;scoring&quot;&gt;Scoring&lt;/h1&gt;
&lt;p&gt;We will use a simplified tetris scoring system that awards points for clearing rows. The more rows cleared the higher the award.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;# Lines&lt;/th&gt;
&lt;th style=&quot;text-align:center&quot;&gt;Points&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;40&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;100&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;300&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td style=&quot;text-align:center&quot;&gt;1200&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;We know when a row collapses, so we can add a method to &lt;code&gt;Game&lt;/code&gt; that calculates the points to award when rows collapse. It can be a simple encoding of the above points table, with the correct indexing to retrieve the right value:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;calculateAward(completedRows) {
  const map = {
    0: 0,
    1: 40,
    2: 100,
    3: 300,
    4: 1200
  };
  return map[completedRows.length];
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A nice property of this implementation is that it is valid for values of completed rows &amp;gt;= 0. Tetris does not allow for more than 4 rows to be completed at the same time.&lt;/p&gt;
&lt;p&gt;We can use &lt;code&gt;calculateAward&lt;/code&gt; in the &lt;code&gt;convertToRubble&lt;/code&gt; method to increment a &lt;code&gt;Game.score&lt;/code&gt; property that tracks the players score.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;convertToRubble() {
  this.rubble = this.rubble.concat(this.fallingPiece.points());
  const completedRows = this.completedRows();
  completedRows.forEach(r =&amp;gt; this.collapseRow(r));
  this.score += this.calculateAward(completedRows);
  if (!this.isGameOver()) {
    this.startAPiece();
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now the player needs to know what their score is, so we modify &lt;code&gt;GameView&lt;/code&gt; to include a &lt;code&gt;ScoreView&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export var GameView = React.createClass&amp;lt;GameViewProps,any&amp;gt;({
  render: function () {
    return &amp;lt;div className=&amp;quot;border&amp;quot; style={{width: this.props.game.cols*25, height: this.props.game.rows*25}}&amp;gt;
      { this.props.game.isGameOver() ?
        &amp;lt;span&amp;gt;GAME OVER&amp;lt;/span&amp;gt; : &amp;lt;span&amp;gt;
        &amp;lt;PieceView piece={this.props.game.fallingPiece} /&amp;gt;
        &amp;lt;RubbleView rubble={this.props.game.rubble} /&amp;gt;
        &amp;lt;ScoreView score={this.props.game.score} /&amp;gt;
        &amp;lt;/span&amp;gt;
      }
    &amp;lt;/div&amp;gt;;
  }
});
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and implement score view to dump the game score in a div:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;interface ScoreViewProps { score:number; }
const ScoreView = React.createClass&amp;lt;ScoreViewProps,any&amp;gt;({
  render: function () {
    return &amp;lt;div className=&amp;quot;score-display&amp;quot;&amp;gt;{this.props.score}&amp;lt;/div&amp;gt;;
  }
});
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;et voilà!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;score.png&quot; alt=&quot;Tetris with score&quot; /&gt;&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Implementing Tetris with React and Redux - VI</title>
      <link>http://withouttheloop.com/articles/2016-01-07-tetris6/</link>
      <pubDate>Thu, 07 Jan 2016 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2016-01-07-tetris6/</guid>
      <author></author>
      <description>&lt;p&gt;Last time I promised you collapsing completed rows and ending the game. That will have to wait. I have something &lt;strong&gt;even more exciting!&lt;/strong&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Converting to typescript&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;To follow along with this article checkout the commit &lt;a href=&quot;https://github.com/liammclennan/tetris/commit/70fa71e6893c73dff57ae29ff006ab51f3896136&quot;&gt;70fa71&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ git clone https://github.com/liammclennan/tetris.git
$ git checkout 70fa71
$ npm run bootstrap
$ npm run likehell
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&quot;typescript&quot;&gt;Typescript&lt;/h1&gt;
&lt;p&gt;Having a type checking compiler eliminates a large set of bugs, and makes a heap of tests redundant. Tests are a debt that must be serviced so we should aim to get maximum value from the fewest tests.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.typescriptlang.org/&quot;&gt;Typescript&lt;/a&gt; adds compile time type checking to JavaScript. Converting our application to typescript requires:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;converting the application code from JavaScript to Typescript&lt;/li&gt;
&lt;li&gt;acquiring &lt;a href=&quot;http://www.typescriptlang.org/Handbook#writing-dts-files&quot;&gt;Typescript type definitions&lt;/a&gt; for all dependencies&lt;/li&gt;
&lt;li&gt;modifying the build process to include the Typescript compiler&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;adding-typescript-to-the-build&quot;&gt;Adding Typescript to the Build&lt;/h1&gt;
&lt;p&gt;Working backwards we can start by acquiring the required Typescript dev tools:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm install typescript tsd --save
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Typescript is the npm package including the typescript compiler. &lt;a href=&quot;http://definitelytyped.org/tsd/&quot;&gt;Tsd&lt;/a&gt; is a tool for acquiring Typescript type definition files for popular JavaScript libraries.&lt;/p&gt;
&lt;p&gt;We can then use tsd to fetch the type definitions we need:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;tsd install react-global mousetrap mocha node underscore --save
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The type definitions are saved into a &lt;em&gt;typings/&lt;/em&gt; directory and listed in a manifest &lt;em&gt;tsd.json&lt;/em&gt;. A Typescript file &lt;em&gt;typings/tsd.d.ts&lt;/em&gt; references all of the type definitions as a shortcut way to import them all. I could not find a tsd definition for Redux so I manually included the type definition at &lt;em&gt;src/redux.d.ts&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Next we prepend another build command in &lt;em&gt;gulpfile.js&lt;/em&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;tsc src/app.tsx test/modelsTests.ts --jsx react --outDir build/es6 -t ES6
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;tsc&lt;/code&gt; is the typescript compiler.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;src/app.tsx&lt;/code&gt; and &lt;code&gt;test/modelsTests.ts&lt;/code&gt; are the entry point files. All other files are found by following dependencies. The &lt;code&gt;.tsx&lt;/code&gt; extension indicates that the file contains &lt;a href=&quot;https://facebook.github.io/jsx/&quot;&gt;jsx&lt;/a&gt; embedded in Typescript.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;--jsx react&lt;/code&gt; tells the compiler that when it finds jsx it should compile it to React JavaScript.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;--outDir build/es6&lt;/code&gt; specifies where the output should be written.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;-t ES6&lt;/code&gt; sets the compiler to target ES6 (ES2015).&lt;/p&gt;
&lt;h1 id=&quot;converting-to-typescript&quot;&gt;Converting to Typescript&lt;/h1&gt;
&lt;p&gt;The easiest way to convert an application from JavaScript to Typescript is to start from the leaves of the dependency tree and work back to the root. That means starting with the modules that have the fewest dependencies. For this Tetris app &lt;em&gt;model.js&lt;/em&gt; is the best choice.&lt;/p&gt;
&lt;p&gt;Firstly we can change the file extension to &lt;em&gt;.ts&lt;/em&gt; and attempt to compile using:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;tsc src/model.js -t ES6
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;which won’t work. The typescript compiler will give messages indicating the things that need to be fixed. For &lt;em&gt;model.js&lt;/em&gt; this is mostly the syntax of classes. Typescript has a shortcut syntax for specifying the properties of classes that looks like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export class Tetromino {
  constructor(public name:string, public rotator: (rotation:string)=&amp;gt;Point[]) {}
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This automatically creates public properties &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;rotator&lt;/code&gt;. &lt;code&gt;name&lt;/code&gt; has the type &lt;code&gt;string&lt;/code&gt;. &lt;code&gt;rotator&lt;/code&gt; has the type &lt;code&gt;(rotation:string)=&amp;gt;Point[]&lt;/code&gt; which means a function from a &lt;code&gt;string&lt;/code&gt; to an array of &lt;code&gt;Point&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;When all the type errors in &lt;em&gt;model.ts&lt;/em&gt; are fixed we move to &lt;em&gt;components.ts&lt;/em&gt;. This file is slightly more complicated because it has dependencies. The first thing to do is add a reference to &lt;em&gt;tsd.d.ts&lt;/em&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/// &amp;lt;reference path=&amp;quot;../typings/tsd.d.ts&amp;quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is a directive to the typescript compiler that tells it where to find type information. From &lt;em&gt;tsd.d.ts&lt;/em&gt; typescript can find type definitions for all of the libraries we are using (except Redux).&lt;/p&gt;
&lt;p&gt;The big change in this file is specifying the &lt;code&gt;props&lt;/code&gt; and &lt;code&gt;state&lt;/code&gt; type parameters for each React component by passing the types to the &lt;code&gt;createClass&lt;/code&gt; function.&lt;/p&gt;
&lt;p&gt;For the &lt;code&gt;GameView&lt;/code&gt; component the type of its props is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;interface GameViewProps {
  game: Model.Game;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;GameView&lt;/code&gt; does not use state (none of our components do) so the component changes to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export var GameView = React.createClass&amp;lt;GameViewProps,any&amp;gt;({
  render: function () {
    return &amp;lt;div className=&amp;quot;border&amp;quot; style={
      {
        width: this.props.game.cols*25,
        height: this.props.game.rows*25
      }}&amp;gt;
      &amp;lt;PieceView piece={this.props.game.fallingPiece} /&amp;gt;
      &amp;lt;RubbleView rubble={this.props.game.rubble} /&amp;gt;
    &amp;lt;/div&amp;gt;;
  }
});
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We now move up the dependency tree to &lt;em&gt;app.tsx&lt;/em&gt; which needs to reference &lt;em&gt;tsd.d.ts&lt;/em&gt; and &lt;em&gt;redux.d.ts&lt;/em&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/// &amp;lt;reference path=&amp;quot;../typings/tsd.d.ts&amp;quot; /&amp;gt;
/// &amp;lt;reference path=&amp;quot;redux.d.ts&amp;quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The file is otherwise much the same.&lt;/p&gt;
&lt;p&gt;The test file &lt;em&gt;modelsTests.ts&lt;/em&gt; also needs a reference to &lt;em&gt;tsd.d.ts&lt;/em&gt;. Then everything should compile properly, the tests should run successfully and the application should run.&lt;/p&gt;
&lt;p&gt;And now we have type safety.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Implementing Tetris with React and Redux - V</title>
      <link>http://withouttheloop.com/articles/2016-01-05-tetris5/</link>
      <pubDate>Tue, 05 Jan 2016 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2016-01-05-tetris5/</guid>
      <author></author>
      <description>&lt;p&gt;In the previous article we refactored the domain model, simplified the React rendering, and added some JavaScript unit tests.&lt;/p&gt;
&lt;p&gt;In this addition we work on collision detection and add event handling for rotation and lateral movement.&lt;/p&gt;
&lt;p&gt;To follow along with this article checkout the commit &lt;a href=&quot;https://github.com/liammclennan/tetris/commit/ce0c318f9d85ff7cf4edd05cc255395da0bd7294&quot;&gt;ce0c31&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ git clone https://github.com/liammclennan/tetris.git
$ git checkout ce0c31
$ npm install
$ npm run away
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&quot;adding-event-handlers&quot;&gt;Adding Event Handlers&lt;/h1&gt;
&lt;p&gt;Normally in a React application the events come out of the DOM, and therefore come via the React eventing system. For tetris the relevant events are not DOM events but keyboard events. To work with keyboard events we will use the &lt;a href=&quot;https://craig.is/killing/mice&quot;&gt;mousetrap&lt;/a&gt; library.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ npm install --save mousetrap
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;When the application starts we register some keyboard listeners for the relevant keys:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import * as Mousetrap from &amp;#39;mousetrap&amp;#39;;

Mousetrap.bind(&amp;#39;space&amp;#39;, ()=&amp;gt; store.dispatch({type:&amp;#39;ROTATE&amp;#39;}));
Mousetrap.bind(&amp;#39;left&amp;#39;, ()=&amp;gt; store.dispatch({type:&amp;#39;LEFT&amp;#39;}));
Mousetrap.bind(&amp;#39;right&amp;#39;, ()=&amp;gt; store.dispatch({type:&amp;#39;RIGHT&amp;#39;}));
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;With that in place the &lt;strong&gt;space&lt;/strong&gt;, &lt;strong&gt;left&lt;/strong&gt;, and &lt;strong&gt;right&lt;/strong&gt; keys will dispatch corresponding actions to Redux. Therefore, we need to update our Redux reducer function to correctly process these new actions.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function reducer(state = new Model.Game(), action) {
  switch (action.type) {
      case &amp;#39;TICK&amp;#39;:
        const revedState = state.tick();
        setTimeout(() =&amp;gt; store.dispatch({ type: &amp;#39;TICK&amp;#39; }),500);
        return revedState;
      case &amp;#39;ROTATE&amp;#39;:
        return state.rotate();
      case &amp;#39;LEFT&amp;#39;:
        return state.left();
      case &amp;#39;RIGHT&amp;#39;:
        return state.right();
      default: return state;
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;TICK&lt;/code&gt; case has also changed slightly. Previously I used &lt;code&gt;setInterval()&lt;/code&gt; to trigger a tick on a time interval. The disadvantage of &lt;code&gt;setInterval()&lt;/code&gt; is that it does not allow the debugger to stop the game. If we stop on a breakpoint to do some debugging &lt;code&gt;setInterval()&lt;/code&gt; carries on triggering ticks every 500ms. The solution is to process a tick and then use &lt;code&gt;setTimeout()&lt;/code&gt; to queue the next tick. This way if execution stops on a breakpoint we won’t get the next tick until we resume execution.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;ROTATE&lt;/code&gt;, &lt;code&gt;LEFT&lt;/code&gt; and &lt;code&gt;RIGHT&lt;/code&gt; actions are handled by delegating to corresponding methods on the game object. Keeping the heavy lifting out of the reducer function makes it easier to understand and makes the application easier to test.&lt;/p&gt;
&lt;h1 id=&quot;implementing-rotation&quot;&gt;Implementing Rotation&lt;/h1&gt;
&lt;p&gt;The &lt;code&gt;Piece&lt;/code&gt; type is aware of its possible rotations (N,E,S,W) and is capable of producing the correct set of points given any of those rotations. Therefore, for the game to rotate the current piece it merely needs to update the piece’s &lt;code&gt;rotation&lt;/code&gt; property. This is done be delegating to the &lt;code&gt;Piece&lt;/code&gt; object, so the &lt;code&gt;Game&lt;/code&gt;‘s &lt;code&gt;rotate()&lt;/code&gt; method is just:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;rotate() {
  this.fallingPiece.rotate();
  return this;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note that rotate must return the game object so that the reducer function can then return it as the updated Redux state.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;rotate()&lt;/code&gt; method of &lt;code&gt;Piece&lt;/code&gt; then does the work of calculating what the ‘next’ rotation is (i.e. if the current rotation is ‘N’ then ‘next’ rotation will be ‘E’).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;rotate() {
    const rotations = Piece.rotations();
    this.rotation = rotations[(rotations.indexOf(this.rotation)+1) % 4];
},
static rotations() {
    return [&amp;#39;N&amp;#39;,&amp;#39;E&amp;#39;,&amp;#39;S&amp;#39;,&amp;#39;W&amp;#39;];
}
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&quot;implementing-lateral-movement&quot;&gt;Implementing Lateral Movement&lt;/h1&gt;
&lt;p&gt;As this is Tetris, the player may move the piece from side to side. Like rotation the &lt;code&gt;Game&lt;/code&gt;‘s &lt;code&gt;left()&lt;/code&gt; and &lt;code&gt;right()&lt;/code&gt; methods simply delegate to &lt;code&gt;left()&lt;/code&gt; and &lt;code&gt;right()&lt;/code&gt; methods on the &lt;code&gt;Piece&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;A &lt;code&gt;Piece&lt;/code&gt; is a &lt;code&gt;Shape&lt;/code&gt; plus a rotation plus an offset. When moving laterally the shape stays the same and the rotation stays the same. Only the offset has to change. A left move requires decreasing the column of the offset by one and a right move requires increasing the column of the offset by one, hence the &lt;code&gt;left()&lt;/code&gt; and &lt;code&gt;right()&lt;/code&gt; methods of &lt;code&gt;Piece&lt;/code&gt; are:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;left() {
  this.offset = new Point(this.offset.row, this.offset.col-1);
}
right() {
  this.offset = new Point(this.offset.row, this.offset.col+1);
}
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&quot;preventing-boundary-violations-and-collisions&quot;&gt;Preventing Boundary Violations and Collisions&lt;/h1&gt;
&lt;p&gt;Our rotation and lateral movement, as implemented, is entirely unconstrained. The player is able to move the pieces outside the boundary of the game, and also to move pieces over the top of rubble. Preventing these violations is non-trivial, especially for rotations. How do you know if a rotation will cause the piece to go out of bounds or to overlap with some rubble? The easier way is to allow the operation to occur, then check for boundary violations and collisions, and if a problem is found apply a compensating action that reverses the original action.&lt;/p&gt;
&lt;p&gt;If a left movement causes the piece to go out of bounds apply a right movement to compensate. If a rotation causes the piece to overlap some rubble apply a rotation in the opposite direction to compensate. Because React separates the calculation of the UI state from the rendering, all of this happens without causing any change to the DOM. The user does not see the action and its compensation. This strategy is implemented in the &lt;code&gt;Game&lt;/code&gt;‘s &lt;code&gt;transactionDo&lt;/code&gt; method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;transactionDo(thing, compensation) {
  thing();
  if (this.fallingPieceIsOutOfBounds() || this.fallingPieceOverlapsRubble()) {
    compensation();
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The argument &lt;code&gt;thing&lt;/code&gt; is the operation we are attempting. &lt;code&gt;compensation&lt;/code&gt; is the compensating action to apply in the event that &lt;code&gt;thing&lt;/code&gt; puts the game into an invalid state. An invalid state is defined as a point out of bounds or a point overlapping rubble. The detection is accomplished with the following two simple methods of the &lt;code&gt;Game&lt;/code&gt; type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;fallingPieceIsOutOfBounds() {
  return this.fallingPiece.minCol() &amp;lt; 1 ||
    this.fallingPiece.maxCol() &amp;gt; this.cols ||
    this.fallingPiece.maxRow() &amp;gt; this.rows;
}
fallingPieceOverlapsRubble() {
  return this.fallingPiece.points().some(p =&amp;gt; this.rubble.some(r =&amp;gt; r.sameAs(p)));
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;rotate&lt;/code&gt;, &lt;code&gt;left&lt;/code&gt; and &lt;code&gt;right&lt;/code&gt; methods on &lt;code&gt;Game&lt;/code&gt; can then use &lt;code&gt;transactionDo&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;rotate() {
  this.transactionDo(
    ()=&amp;gt;this.fallingPiece.rotate(),
    ()=&amp;gt; this.fallingPiece.unRotate());
  return this;
}
left() {
  this.transactionDo(
    ()=&amp;gt;this.fallingPiece.left(),
    ()=&amp;gt; this.fallingPiece.right());
  return this;
}
right() {
  this.transactionDo(
    ()=&amp;gt;this.fallingPiece.right(),
    ()=&amp;gt; this.fallingPiece.left());
  return this;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;unRotate&lt;/code&gt; is simply the inverse of &lt;code&gt;rotate&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;unRotate() {
  this.rotation = Piece.rotations()[(Piece.rotations().indexOf(this.rotation)-1) % 4];
}
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&quot;improving-the-development-workflow&quot;&gt;Improving the Development Workflow&lt;/h1&gt;
&lt;p&gt;Development is more efficient if we can see the changes to our application without having to save changes, run the build, and refresh the browser. We can automate the rebuilding process using a filesystem watcher. For this project we will use &lt;a href=&quot;http://gulpjs.com/&quot;&gt;gulp&lt;/a&gt; to orchestrate this process.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm install --save gulp gulp-shell
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Gulp is configured by writing a build script in a file &lt;strong&gt;gulpfile.js&lt;/strong&gt;. To accomplish our goal this can be as simple as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var gulp = require(&amp;#39;gulp&amp;#39;);
var shell = require(&amp;#39;gulp-shell&amp;#39;);

gulp.task(&amp;#39;buildandtest&amp;#39;, shell.task([
  &amp;#39;browserify -t [ babelify --presets [ react es2015 ] ] app.js -o bundle.js&amp;#39;,
  &amp;#39;node_modules/mocha/bin/mocha --compilers js:babel-register&amp;#39;
]));

gulp.task(&amp;#39;default&amp;#39;, function() {
    gulp.watch([&amp;#39;*.js&amp;#39;, &amp;#39;test/*.js&amp;#39;], [&amp;#39;buildandtest&amp;#39;]);
});
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;default&lt;/code&gt; task establishes a file system watch for files matching the pattern &lt;code&gt;*.js&lt;/code&gt; and &lt;code&gt;test/*.js&lt;/code&gt;. If a change is detected then the &lt;code&gt;buildandtest&lt;/code&gt; task is run.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;buildandtest&lt;/code&gt; uses the shell to build the application (using the same commands that we had in &lt;strong&gt;package.json&lt;/strong&gt;) and then runs the mocha tests.&lt;/p&gt;
&lt;p&gt;With Gulp setup we no longer need to use npm as build tool and can simplify the &lt;code&gt;scripts&lt;/code&gt; section of &lt;strong&gt;package.json&lt;/strong&gt; to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;quot;scripts&amp;quot;: {
    &amp;quot;away&amp;quot;: &amp;quot;node node_modules/gulp/bin/gulp.js&amp;quot;
  },
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I called the script &lt;code&gt;away&lt;/code&gt; so that the command to start the build is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ npm run away
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We now have a mostly playable Tetris.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;screenshot.png&quot; alt=&quot;mostly playable tetris&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The big things missing are collapsing complete rows and ending the game. Hopefully you can see how those features will be implemented.&lt;/p&gt;
&lt;h1 id=&quot;next-time-&quot;&gt;Next Time…&lt;/h1&gt;
&lt;p&gt;The next installment will cover collapsing completed rows and ending the game. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>Implementing Tetris with React and Redux - IV</title>
      <link>http://withouttheloop.com/articles/2016-01-04-tetris4/</link>
      <pubDate>Mon, 04 Jan 2016 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2016-01-04-tetris4/</guid>
      <author></author>
      <description>&lt;p&gt;In the previous article we introduced Redux for managing the user interface state and added some rudimentary animation.&lt;/p&gt;
&lt;p&gt;In this addition we will refactor the application models and introduce some testing.&lt;/p&gt;
&lt;p&gt;To follow along with this article checkout the commit &lt;a href=&quot;https://github.com/liammclennan/tetris/commit/b01c12dd887c3f86e21a3a66a24f727627b1d171&quot;&gt;b01c12d&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ git clone https://github.com/liammclennan/tetris.git
$ npm install
$ git checkout b01c12d
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&quot;fixing-the-model&quot;&gt;Fixing the Model&lt;/h1&gt;
&lt;p&gt;At this point in the implementation it is time to start thinking about the logic of Tetris and how we will implement things like collision detection, boundaries and collapsing rows. This is stuff that I don’t want in my React components because it is application logic that should be a core part of my application.&lt;/p&gt;
&lt;p&gt;I have made a mistake with my domain modelling by representing the different Tetrominos as different types, when in fact they only need to be different configurations of the same type (&lt;code&gt;Shape&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Also, I have come to the realization that a Tetrominos is not a set of points with a standard orientation that can be rotated. It is better to think of a Tetromino as a set of rotations of a shape (I call the rotations N, S, E and W).&lt;/p&gt;
&lt;h2 id=&quot;the-shape-type&quot;&gt;The ‘Shape’ Type&lt;/h2&gt;
&lt;p&gt;A ‘Shape’ is a kind of Tetromino. It has a name and a function that returns the shape’s points given a rotation.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// a tetromino
export class Shape {
  constructor(name, rotator) {
    this.name = name;
    this.rotator = rotator;
  }
  pointsRotated(rotation) {
    return this.rotator(rotation);
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;With the &lt;code&gt;Shape&lt;/code&gt; type we can now fully define all possible rotations of all possible Tetrominos. I put them in a dictionary so that I can easily access the one I want (e.g. &lt;code&gt;shapes[&amp;#39;Z&amp;#39;]&lt;/code&gt;):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// dictionary of shape type to square offsets
export var shapes = {
  &amp;#39;O&amp;#39;: new Shape(&amp;#39;O&amp;#39;, rotation =&amp;gt; [new Point(1,1),new Point(1,2), new Point(2,1),new Point(2,2)]),
  &amp;#39;I&amp;#39;: new Shape(&amp;#39;I&amp;#39;, rotation =&amp;gt; {
    switch (rotation) {
      case &amp;#39;N&amp;#39;: return [new Point(1,1), new Point(2,1),new Point(3,1), new Point(4,1)];
      case &amp;#39;E&amp;#39;: return [new Point(2,1), new Point(2,2),new Point(2,3), new Point(2,4)];
      case &amp;#39;S&amp;#39;: return [new Point(1,1), new Point(2,1),new Point(3,1), new Point(4,1)];
      case &amp;#39;W&amp;#39;: return [new Point(2,1), new Point(2,2),new Point(2,3), new Point(2,4)];
    }
  }),
  &amp;#39;T&amp;#39;: new Shape(&amp;#39;T&amp;#39;, rotation =&amp;gt; {
    switch (rotation) {
      case &amp;#39;N&amp;#39;: return [new Point(1,1), new Point(1,2), new Point(2,2), new Point(1,3)];
      case &amp;#39;E&amp;#39;: return [new Point(1,2), new Point(2,2),new Point(3,2), new Point(2,1)];
      case &amp;#39;S&amp;#39;: return [new Point(1,2), new Point(2,1),new Point(2,2), new Point(2,3)];
      case &amp;#39;W&amp;#39;: return [new Point(1,1), new Point(2,1),new Point(3,1), new Point(2,2)];
    }
  }),
  &amp;#39;L&amp;#39;: new Shape(&amp;#39;L&amp;#39;, rotation =&amp;gt; {
    switch (rotation) {
      case &amp;#39;N&amp;#39;: return [new Point(1,1), new Point(2,1), new Point(1,2), new Point(1,3)];
      case &amp;#39;E&amp;#39;: return [new Point(1,1), new Point(1,2), new Point(2,2), new Point(3,2)];
      case &amp;#39;S&amp;#39;: return [new Point(1,3), new Point(2,1), new Point(2,2), new Point(2,3)];
      case &amp;#39;W&amp;#39;: return [new Point(1,1), new Point(2,1), new Point(3,1), new Point(3,2)];

    }
  }),
  &amp;#39;Z&amp;#39;: new Shape(&amp;#39;Z&amp;#39;, rotation =&amp;gt; {
    switch (rotation) {
      case &amp;#39;N&amp;#39;: return [new Point(1,1), new Point(1,2), new Point(2,2), new Point(2,3)];
      case &amp;#39;E&amp;#39;: return [new Point(1,2), new Point(2,2),new Point(2,1), new Point(3,1)];
      case &amp;#39;S&amp;#39;: return [new Point(1,1), new Point(1,2), new Point(2,2), new Point(2,3)];
      case &amp;#39;W&amp;#39;: return [new Point(1,2), new Point(2,2),new Point(2,1), new Point(3,1)];
    }
  })
};
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;the-piece-type&quot;&gt;The ‘Piece’ Type&lt;/h2&gt;
&lt;p&gt;To be able to work with instances of shapes on the game board we need a type to represent an instance of a shape with an offset and rotation. That type is &lt;code&gt;Piece&lt;/code&gt;. Note that the rotation defaults to ‘N’, and the offset defaults to row 1 column 10 (top centre).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// an instance of a tetromino on the board
export class Piece {
  constructor(shape, offset = new Point(1,10)) {
    this.shape = shape;
    this.offset = offset;
    this.rotation = &amp;#39;N&amp;#39;;
  }
  points() {
    return this.shape.pointsRotated(this.rotation).map((point,ix) =&amp;gt; point.add(this.offset));
  }
  static rotations() {
    return [&amp;#39;N&amp;#39;,&amp;#39;E&amp;#39;,&amp;#39;S&amp;#39;,&amp;#39;W&amp;#39;];
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The set of possible rotations is given by the static function &lt;code&gt;rotations()&lt;/code&gt;. As a static function it is accessed of the type, not an instance of the type, e.g. &lt;code&gt;Piece.rotations()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;points()&lt;/code&gt; function returns the squares (points) that need to be drawn for the piece. This is done by starting with the correct rotation of the point’s shape and then adding the Piece’s offset to each point.&lt;/p&gt;
&lt;h2 id=&quot;the-game-type&quot;&gt;The ‘Game’ Type&lt;/h2&gt;
&lt;p&gt;To coordinate the game of Tetris we introduce a new type &lt;code&gt;Game&lt;/code&gt;. Game keeps track of the currently falling piece (there can be only one) and the &lt;em&gt;rubble&lt;/em&gt; left by all pieces that have fallen previously. Once a piece has finished falling it can no longer be stored as a piece because Tetris allows full rows to collapse, so the &lt;code&gt;Game&lt;/code&gt; converts fallen pieces to rubble which is just a collection of points.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export class Game {
  constructor() {
    this.rows = 15;
    this.cols = 20;
    this.rubble = [];
    this.startAPiece();
  }
  tick() {
    this.fallingPiece.offset = this.fallingPiece.offset.fallOne();
    if (this.fallingPiece.maxRow() &amp;gt;= this.rows) {
      this.convertToRubble();
    }
    return this;
  }
  convertToRubble() {
    this.rubble = this.rubble.concat(this.fallingPiece.points());
    this.startAPiece();
  }
  startAPiece() {
    this.fallingPiece = new Piece(shapes.selectRandom());
  }
  rotate() {
    this.fallingPiece.rotate();
    return this;
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;startAPiece()&lt;/code&gt; is a method that intializes a new falling &lt;code&gt;Piece&lt;/code&gt;. To choose the &lt;code&gt;Shape&lt;/code&gt; for the new piece it uses the &lt;code&gt;selectRandom()&lt;/code&gt; method, which randomly chooses one of the five possible Tetromino shapes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;shapes.selectRandom = function() {
  var index = Math.floor(Math.random()*1000000%5);
  return shapes[Object.keys(shapes)[index]];
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;tick()&lt;/code&gt; is the method that advances the game by one time unit, by moving the falling piece down by one position. This is done by changing the falling piece’s offset. If the falling piece hits the lower boundary (&lt;code&gt;this.fallingPiece.maxRow() &amp;gt;= this.rows&lt;/code&gt;) then the piece is converted to rubble.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;convertToRubble()&lt;/code&gt; adds the points from the current falling piece to the existing collection of rubble. It then delegates to &lt;code&gt;startAPiece()&lt;/code&gt; to create a new falling piece.&lt;/p&gt;
&lt;h1 id=&quot;the-react-components&quot;&gt;The React Components&lt;/h1&gt;
&lt;p&gt;Much of the refactoring in this episode has been to move the application logic into a domain model and away from the React components. The React components can now be very simple, which is good.&lt;/p&gt;
&lt;p&gt;From the outside in we start with &lt;code&gt;GameView&lt;/code&gt;. This is a React component responsible for rendering the entire game.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export var GameView = React.createClass({
  render: function () {
    return &amp;lt;div className=&amp;quot;border&amp;quot; style={{width: this.props.game.cols*25, height: this.props.game.rows*25}}&amp;gt;
      &amp;lt;PieceView piece={this.props.game.fallingPiece} /&amp;gt;
      &amp;lt;RubbleView rubble={this.props.game.rubble} /&amp;gt;
    &amp;lt;/div&amp;gt;;
  }
});
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The game is rendered as a div with 25 pixels for each row and column. Within the &lt;code&gt;GameView&lt;/code&gt; there is a &lt;code&gt;PieceView&lt;/code&gt;, which renders the current (falling) piece, and a &lt;code&gt;RubbleView&lt;/code&gt; which renders the rubble of all pieces that have fallen previously.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;PieceView&lt;/code&gt; has a single &lt;em&gt;prop&lt;/em&gt; called &lt;code&gt;piece&lt;/code&gt;. This is how we pass data into the &lt;code&gt;PieceView&lt;/code&gt;. &lt;code&gt;piece&lt;/code&gt; is expected to be an instance of the &lt;code&gt;Piece&lt;/code&gt; model type.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export var PieceView = React.createClass({
  render: function () {
    return &amp;lt;div&amp;gt;
      {this.props.piece.points().map(sq =&amp;gt; &amp;lt;Square key={count++} row={sq.row} col={sq.col} /&amp;gt;)}
    &amp;lt;/div&amp;gt;;
  }
});
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;PieceView&lt;/code&gt; is very simple. It extracts the points from the piece and converts each one to a &lt;code&gt;Square&lt;/code&gt; element. &lt;code&gt;Square&lt;/code&gt; is a component responsible for rendering a single point.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export var Square = React.createClass({
    render: function() {
            var s = {
            left: (this.props.col-1) * 25 + &amp;#39;px&amp;#39;,
          top: ((this.props.row-1) * 25) + &amp;#39;px&amp;#39;
        };
        return &amp;lt;div className=&amp;quot;square&amp;quot; style={s}&amp;gt;&amp;lt;/div&amp;gt;;
    }
});
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&quot;the-app-component&quot;&gt;The ‘App’ Component&lt;/h1&gt;
&lt;p&gt;App (app.js) has been kept simple by moving a lot of the logic into models. It has not changed much from the previous edition.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import * as React from &amp;#39;react&amp;#39;;
import * as ReactDOM  from &amp;#39;react-dom&amp;#39;;
import * as Components from &amp;#39;./components&amp;#39;;
import * as Model from &amp;#39;./model&amp;#39;;
import {createStore} from &amp;#39;redux&amp;#39;;


function reducer(state = new Model.Game(), action) {
  switch (action.type) {
    case &amp;#39;TICK&amp;#39;:
      return state.tick();
    default: return state;
  }
}

let store = createStore(reducer);
store.subscribe(() =&amp;gt; {
  ReactDOM.render(&amp;lt;Components.GameView game={store.getState()} /&amp;gt;, document.getElementById(&amp;#39;container&amp;#39;));
});
setInterval(() =&amp;gt; store.dispatch({ type: &amp;#39;TICK&amp;#39; }),500);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The result is that we now have pieces falling one after another and stopping at the boundary of the game area.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;screenshot.png&quot; alt=&quot;Tetris screenshot&quot; /&gt;&lt;/p&gt;
&lt;h1 id=&quot;testing&quot;&gt;Testing&lt;/h1&gt;
&lt;p&gt;In JavaScript at least, if you haven’t tested it you don’t know it works. I want to add some unit tests and I want to be able to verify them without a browser, therefore I choose &lt;a href=&quot;https://mochajs.org/&quot;&gt;mocha&lt;/a&gt; as my test runner. &lt;code&gt;babel-register&lt;/code&gt; is an adapter that gives mocha the ability to work with ES2015 via babel.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm install --save mocha babel-register
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Mocha runs in the browser or in node.js and has a hierarchical test format that I like.&lt;/p&gt;
&lt;p&gt;To be able to run my tests via npm, and without a global install of mocha, I add the following script to &lt;code&gt;package.json&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;quot;scripts&amp;quot;: {
  &amp;quot;build&amp;quot;: &amp;quot;browserify -t [ babelify --presets [ react es2015 ] ] app.js -o bundle.js&amp;quot;,
  &amp;quot;test&amp;quot;: &amp;quot;node_modules/mocha/bin/mocha --compilers js:babel-register&amp;quot;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now I can run my tests with:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm run test
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;but first I will need some tests. Within the &lt;code&gt;test&lt;/code&gt; directory (mocha convention) I write my model tests in a file called &lt;code&gt;modelTests.js&lt;/code&gt;. To start I need to import an assertion library and the module I want to test:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var assert = require(&amp;#39;assert&amp;#39;);
var Models = require(&amp;#39;../model&amp;#39;);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The first tests I add are to check that shapes have the points that I expect them to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function pieceHasPoints(piece, points) {
  return points.every(item =&amp;gt; piece.hasPoint(item));
}

describe(&amp;#39;models&amp;#39;, function () {
  describe(&amp;#39;Piece&amp;#39;, ()=&amp;gt; {
    describe(&amp;#39;hasPoint&amp;#39;, ()=&amp;gt; {
      var piece = new Models.Piece(Models.shapes.I, new Models.Point(1,1));
      it(&amp;#39;should have (1,1)&amp;#39;,()=&amp;gt; assert(piece.hasPoint(new Models.Point(1,1))));
      it(&amp;#39;should have (2,1)&amp;#39;,()=&amp;gt; assert(piece.hasPoint(new Models.Point(2,1))));
      it(&amp;#39;should have (3,1)&amp;#39;,()=&amp;gt; assert(piece.hasPoint(new Models.Point(3,1))));
      it(&amp;#39;should have (4,1)&amp;#39;,()=&amp;gt; assert(piece.hasPoint(new Models.Point(4,1))));
      it(&amp;#39;should not have (2,2)&amp;#39;,()=&amp;gt; assert(!piece.hasPoint(new Models.Point(2,2))));
      it(&amp;#39;should not have (1,2)&amp;#39;,()=&amp;gt; assert(!piece.hasPoint(new Models.Point(2,2))));
      it(&amp;#39;should not have (3,2)&amp;#39;,()=&amp;gt; assert(!piece.hasPoint(new Models.Point(2,2))));
      it(&amp;#39;should not have (3,3)&amp;#39;,()=&amp;gt; assert(!piece.hasPoint(new Models.Point(2,2))));
    });
  });
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Next I check that rotation works correctly:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;describe(&amp;#39;rotation&amp;#39;, ()=&amp;gt; {
    describe(&amp;#39;general rotation&amp;#39;, ()=&amp;gt; {
      it(&amp;#39;should rotate clockwise indefinitely&amp;#39;, ()=&amp;gt; {
        var piece = new Models.Piece(Models.shapes.I);
        assert.equal(piece.rotation, &amp;#39;N&amp;#39;)
        piece.rotate();
        assert.equal(piece.rotation, &amp;#39;E&amp;#39;);
        piece.rotate();
        assert.equal(piece.rotation, &amp;#39;S&amp;#39;);
        piece.rotate();
        assert.equal(piece.rotation, &amp;#39;W&amp;#39;);
        piece.rotate();
        assert.equal(piece.rotation, &amp;#39;N&amp;#39;);
        piece.rotate();
        assert.equal(piece.rotation, &amp;#39;E&amp;#39;);
        piece.rotate();
        assert.equal(piece.rotation, &amp;#39;S&amp;#39;);
        piece.rotate();
        assert.equal(piece.rotation, &amp;#39;W&amp;#39;);
        piece.rotate();
        assert.equal(piece.rotation, &amp;#39;N&amp;#39;);
      });
    });

    describe(&amp;#39;rotating an I&amp;#39;, ()=&amp;gt; {
      var piece = new Models.Piece(Models.shapes.I, new Models.Point(1,1));
      it(&amp;#39;should have the expected points to start with&amp;#39;,
        ()=&amp;gt; assert(pieceHasPoints(piece, [new Models.Point(1,1),new Models.Point(2,1),new Models.Point(3,1),new Models.Point(4,1)])));
      it(&amp;#39;should rotate to the correct E position&amp;#39;, ()=&amp;gt; {
        piece.rotate();
        assert(pieceHasPoints(piece, [new Models.Point(2,1),new Models.Point(2,2),new Models.Point(2,3),new Models.Point(2,4)]));
      });
      it(&amp;#39;should rotate to the correct S position&amp;#39;, ()=&amp;gt; {
        piece.rotate();
        assert(pieceHasPoints(piece, [new Models.Point(1,1),new Models.Point(2,1),new Models.Point(3,1),new Models.Point(4,1)]));
      });
      it(&amp;#39;should rotate to the correct W position&amp;#39;, ()=&amp;gt; {
        piece.rotate();
        assert(pieceHasPoints(piece, [new Models.Point(2,1),new Models.Point(2,2),new Models.Point(2,3),new Models.Point(2,4)]));
      });
      it(&amp;#39;should rotate back to N&amp;#39;, ()=&amp;gt; {
        piece.rotate();
        assert(pieceHasPoints(piece, [new Models.Point(1,1),new Models.Point(2,1),new Models.Point(3,1),new Models.Point(4,1)]));
      });
    });
  });
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Running these tests as described produces the output:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; node_modules/mocha/bin/mocha --compilers js:babel-register

  models
    Piece
      hasPoint
        ✓ should have (1,1)
        ✓ should have (2,1)
        ✓ should have (3,1)
        ✓ should have (4,1)
        ✓ should not have (2,2)
        ✓ should not have (1,2)
        ✓ should not have (3,2)
        ✓ should not have (3,3)
    rotation
      general rotation
        ✓ should rotate clockwise indefinitely
      rotating an I
        ✓ should have the expected points to start with
        ✓ should rotate to the correct E position
        ✓ should rotate to the correct S position
        ✓ should rotate to the correct W position
        ✓ should rotate back to N

  14 passing (12ms)
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&quot;next-time-&quot;&gt;Next Time…&lt;/h1&gt;
&lt;p&gt;The next installment of the series will look at handling user input so that we can allow the user to position pieces (move left and right) and trigger rotation. There is work to be done to add collision detection and improve the development workflow. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>Implementing Tetris with React and Redux - III</title>
      <link>http://withouttheloop.com/articles/2015-12-28-tetris3/</link>
      <pubDate>Mon, 28 Dec 2015 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2015-12-28-tetris3/</guid>
      <author></author>
      <description>&lt;p&gt;In the previous article we began implementing tetris with React and Redux and got as far rendering the tetris shapes (called tetrominos).&lt;/p&gt;
&lt;p&gt;In this addition we will add some animation and introduce Redux for managing UI state.&lt;/p&gt;
&lt;p&gt;To follow along with this article checkout the commit &lt;a href=&quot;https://github.com/liammclennan/tetris/commit/9f2c695d4e766d03d9280f086dd5429520cd03e3&quot;&gt;9f2c69&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ git clone https://github.com/liammclennan/tetris.git
$ git checkout 9f2c69
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&quot;introducing-redux&quot;&gt;Introducing Redux&lt;/h1&gt;
&lt;p&gt;React provides two features:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;It generates a UI from a model and maintains the synchronization.&lt;/li&gt;
&lt;li&gt;It provides an eventing system for detecting and handling UI events.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;By itself then, React is not a sufficient basis for a user interface. Facebook filled the gap with Flux. Flux has the right idea (unidirectional data flow) but over-complicates it with actions, dispatchers and stores. It may be a good design for Facebook, but it is not a good generalized solution for web development.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://redux.js.org/&quot;&gt;Redux&lt;/a&gt; is a simpler library that started with the ideas of Flux and then left them all out. It provides management of UI state, and the ways in which that state is modified. Here is how it works.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;React events are translated to &lt;em&gt;actions&lt;/em&gt;. Actions are application level values indicating the users intent, e.g. &lt;strong&gt;add todo item&lt;/strong&gt; or &lt;strong&gt;remove calendar entry&lt;/strong&gt;. Actions often have associated data, so an actual action might be &lt;code&gt;{type:&amp;#39;ADD_TODO_ITEM&amp;#39;, title:&amp;#39;Buy some milk&amp;#39;}&lt;/code&gt;. There are no rules about the format of actions.&lt;/li&gt;
&lt;li&gt;Redux is configured with functions called &lt;em&gt;reducers&lt;/em&gt; that apply actions to the current state, and produce an updated state.&lt;/li&gt;
&lt;li&gt;Redux notifies React that the UI state has changed and the UI should be updated.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To add Redux we install two new npm packages:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm install --save redux react-redux
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then in &lt;code&gt;app.js&lt;/code&gt; we create a redux reducer function that knows how to apply actions to the UI state. This is often a switch statement that branches on the type of the action. If you wanted you could instead put the logic in the action and delegate to it.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function reducer(state = [new Model.O(1,1), new Model.L(1,4)], action) {
  switch (action.type) {
    case &amp;#39;TICK&amp;#39;:
      state.push(new Model.O(action.data*2,action.data*2));
      return state;
    default: return state;
  }
  return state;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The parameters to the function are the existing state and an action. We use the ES2015 default parameter feature to initialize the state to an array containing two tetrominos. Then we switch on the type of the action. If the action is a &lt;em&gt;TICK&lt;/em&gt; then we append a new &lt;em&gt;O&lt;/em&gt; tetromino to the state. The value returned from a reducer is the new state.&lt;/p&gt;
&lt;p&gt;With a fresh reducer function we can now create a redux store to wrap the UI state:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let store = createStore(reducer);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and register with react to re-render when the state changes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;store.subscribe(() =&amp;gt; {
  ReactDOM.render(
  &amp;lt;div&amp;gt;
    {store.getState().map(c =&amp;gt; &amp;lt;Components.ShapeView shape={c} /&amp;gt;)}
  &amp;lt;/div&amp;gt;,
      document.getElementById(&amp;#39;container&amp;#39;)
  );
});
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note that the state is extracted from the store by means of the &lt;code&gt;getState()&lt;/code&gt; method.&lt;/p&gt;
&lt;h1 id=&quot;adding-some-animation&quot;&gt;Adding Some Animation&lt;/h1&gt;
&lt;p&gt;Tetris is a 2-dimensional animated game. We need some way to make the pieces move. I like to work in small increments instead of trying to jump immediately to the final solution, so I will be happy with any sort of regular UI change. The simplest thing I can think of is to generate ticks on a timer, and include an increasing value as data.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var counter = 1;
setInterval(() =&amp;gt; store.dispatch({ type: &amp;#39;TICK&amp;#39;, data: counter++ }),1000);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Remember that &lt;code&gt;store&lt;/code&gt; is our redux wrapper around application state. The &lt;code&gt;dispatch&lt;/code&gt; method is how we publish an action. &lt;/p&gt;
&lt;p&gt;This combined with our reducer means that every second a square tetromino will be added to the board diagonally to the lower right of the previous piece. The result is something like:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;screenshot.png&quot; /&gt;&lt;/p&gt;
&lt;h1 id=&quot;next-time-&quot;&gt;Next Time…&lt;/h1&gt;
&lt;p&gt;The next installment of this series will add falling, rotation and testing.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Implementing Tetris with React and Redux - II</title>
      <link>http://withouttheloop.com/articles/2015-12-27-tetris-2/</link>
      <pubDate>Sun, 27 Dec 2015 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2015-12-27-tetris-2/</guid>
      <author></author>
      <description>&lt;p&gt;In the previous article we began implementing tetris with React and Redux and got as far rendering the tetris shapes (called tetrominos).&lt;/p&gt;
&lt;p&gt;To follow along with this article checkout the commit &lt;a href=&quot;https://github.com/liammclennan/tetris/commit/594a7355c377f62edb44a1cb3f10759d0e0bf804&quot;&gt;594a735&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ git clone https://github.com/liammclennan/tetris.git
$ git checkout 594a735
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&quot;simplifying-the-components&quot;&gt;Simplifying the Components&lt;/h1&gt;
&lt;p&gt;Thinking ahead it becomes apparent that we will need logic related to the shapes, such as how to rotate them and prevent collisions. If we introduce models for the tetrominos then they will be represented twice, once as models and once as React components.&lt;/p&gt;
&lt;p&gt;As we don’t want to repeat ourselves I think it is appropriate to simplify the React components. Instead of having different components for each tetromino all we really need is one component that can render a square. At the same time I will begin to introduce ES2015 modules. My new module, called components, will be in a file called &lt;code&gt;components.js&lt;/code&gt;. Anything that I want to be available outside of the module needs to be prefixed with the &lt;code&gt;export&lt;/code&gt; keyword. Instead of loading React using the commonjs &lt;code&gt;require&lt;/code&gt; function we will switch to using the &lt;code&gt;import&lt;/code&gt; keyword from ES2015. The new components module, and the new &lt;code&gt;ShapeView&lt;/code&gt; component looks like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import * as React from &amp;#39;react&amp;#39;;
import * as ReactDOM from &amp;#39;react-dom&amp;#39;;

export var ShapeView = React.createClass({
  render: function () {
    return &amp;lt;div&amp;gt;
      {this.props.shape.squares().map(sq =&amp;gt; &amp;lt;Square row={sq.row} col={sq.col} /&amp;gt;)}
    &amp;lt;/div&amp;gt;;
  }
});
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;import * as React from &amp;#39;react&amp;#39;&lt;/code&gt; statement means that we are importing the &lt;code&gt;react&lt;/code&gt; module and assigning all of its exports to the identifier &lt;code&gt;React&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The refactored &lt;code&gt;ShapeView&lt;/code&gt; component expects a model called &lt;code&gt;shape&lt;/code&gt; having a method &lt;code&gt;squares()&lt;/code&gt; that returns a collection of points that defines the shape. Thus the component can be reused for any shape that can describes its points.&lt;/p&gt;
&lt;h1 id=&quot;introducing-models&quot;&gt;Introducing Models&lt;/h1&gt;
&lt;p&gt;Having recognised that we need models to encapsulate the Tetris logic I will create another module, called &lt;code&gt;models&lt;/code&gt;. The file models.js contains classes that model some tetrominos (O and L) and a class that models the Squares from which the other shapes are composed.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export class Sqr {
  constructor(row,col) {
    this.row = row;
    this.col = col;
  }
}

export class O {
  constructor(row,col) {
    this.row = row;
    this.col = col;
  }
  squares() {
    return [new Sqr(this.row,this.col), new Sqr(this.row, this.col+1), new Sqr(this.row+1,this.col), new Sqr(this.row+1,this.col+1)];
  }
}

export class L {
  constructor(row,col) {
    this.row = row;
    this.col = col;
  }
  squares() {
    return [new Sqr(this.row,this.col), new Sqr(this.row+1, this.col), new Sqr(this.row+2,this.col), new Sqr(this.row+3,this.col)];
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As required by the &lt;code&gt;ShapeView&lt;/code&gt; component the &lt;code&gt;O&lt;/code&gt; and &lt;code&gt;L&lt;/code&gt; classes both have a &lt;code&gt;squares()&lt;/code&gt; method returning an array of &lt;code&gt;Sqr&lt;/code&gt;.  &lt;/p&gt;
&lt;h1 id=&quot;putting-it-together&quot;&gt;Putting it Together&lt;/h1&gt;
&lt;p&gt;Now we can simplify out &lt;code&gt;app.js&lt;/code&gt;. Firstly, import the required modules so that they are available within &lt;code&gt;app.js&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var React = require(&amp;#39;react&amp;#39;);
var ReactDOM = require(&amp;#39;react-dom&amp;#39;);
var Components = require(&amp;#39;./components&amp;#39;);
var Model = require(&amp;#39;./model&amp;#39;);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note that I have not yet switched this file to use the ES2015 style imports.&lt;/p&gt;
&lt;p&gt;Next, I create an object to act as the model for React to render:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var data = [new Model.O(1,1), new Model.L(1,4)];
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For now, the model is an array of tetrominos, one &lt;code&gt;O&lt;/code&gt; and one &lt;code&gt;L&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The rendering is now simpler. All we need to do is loop over the total set of squares and render each.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ReactDOM.render(
&amp;lt;div&amp;gt;
  {data.map(c =&amp;gt; &amp;lt;Components.ShapeView shape={c} /&amp;gt;)}
&amp;lt;/div&amp;gt;,
    document.getElementById(&amp;#39;container&amp;#39;)
);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In the next article we will start animating the tetrominos and introduce &lt;code&gt;Redux&lt;/code&gt; as a tool for managing state.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Implementing Tetris with React and Redux - I</title>
      <link>http://withouttheloop.com/articles/2015-12-22-tetris1/</link>
      <pubDate>Tue, 22 Dec 2015 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2015-12-22-tetris1/</guid>
      <author></author>
      <description>&lt;p&gt;&lt;img src=&quot;tetris.jpg&quot; alt=&quot;tetris&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I cannot think of a game more classic than tetris. When I was a kid it was the staple diet of gameboy wielding preteens. Therefore, I decided to reimplement tetris using javascript, &lt;a href=&quot;https://facebook.github.io/react/&quot;&gt;React&lt;/a&gt; and &lt;a href=&quot;http://redux.js.org/&quot;&gt;Redux&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&quot;the-cast&quot;&gt;The Cast&lt;/h1&gt;
&lt;h3 id=&quot;javascript-es2015-&quot;&gt;JavaScript (ES2015)&lt;/h3&gt;
&lt;p&gt;At first I started with TypeScript, but I gave up getting it to work with all the other tooling (type definitions, webpack, React etc) and switched to ES2015. ES2015 is not widely supported so I must compile it to ES5. Since I’m using React (with JSX) I’m obliged to have a compile step anyway.&lt;/p&gt;
&lt;h3 id=&quot;react&quot;&gt;React&lt;/h3&gt;
&lt;p&gt;React is a UI library that knows how to keep a web UI in sync with a model object, and how to dispatch events.&lt;/p&gt;
&lt;h3 id=&quot;redux&quot;&gt;Redux&lt;/h3&gt;
&lt;p&gt;Redux is a simple library that puts some structure around UI state and manages the mutation of that state.&lt;/p&gt;
&lt;h3 id=&quot;babel&quot;&gt;Babel&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://babeljs.io/&quot;&gt;Babel&lt;/a&gt; is the defacto standard tool for ES2015 -&amp;gt; ES5 compilations.&lt;/p&gt;
&lt;h3 id=&quot;browserify&quot;&gt;Browserify&lt;/h3&gt;
&lt;p&gt;One of the ES2015 features is modules, but to take advantage of ES2015 modules, to include other modules from NPM and to improve the network efficiency of the application &lt;a href=&quot;http://browserify.org/&quot;&gt;Broswerify&lt;/a&gt; converts the modules into something that works in the browser and smooshes everything into a single file.&lt;/p&gt;
&lt;h3 id=&quot;mocha&quot;&gt;Mocha&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://mochajs.org/&quot;&gt;Mocha&lt;/a&gt; is a node-based JavaScript testing tool. It provides a library for logically organising tests and a runner for running the tests and reporting the results.&lt;/p&gt;
&lt;h3 id=&quot;gulp&quot;&gt;Gulp&lt;/h3&gt;
&lt;p&gt;I use &lt;a href=&quot;http://gulpjs.com/&quot;&gt;gulp&lt;/a&gt; for my build script. It coordinates all the other tools and provides file system watching.&lt;/p&gt;
&lt;h3 id=&quot;what-i-hate-about-all-this&quot;&gt;What I Hate About All This&lt;/h3&gt;
&lt;p&gt;The number of fiddly little tools required to work with JavaScript at the moment annoys me. Each in isolation I understand their purpose but considering the ecosystem as a whole it is obviously an appalling waste of time having to deal with all this bits. I’m sure it will settle down with time. Can’t wait.&lt;/p&gt;
&lt;p&gt;The most pernicious issue is not the quantity of tools required, but the tight coupling between them. Browserify requires a plugin (babelify) to connect it to babel. Mocha requires a plugin (babel-register) to connect it to babel. If I wasn’t so lazy as to have gulp execute shell scripts then I would require gulp plugins specific to mocha, browserify and possible babel.&lt;/p&gt;
&lt;h1 id=&quot;step-1-basic-tooling&quot;&gt;Step 1 - Basic tooling&lt;/h1&gt;
&lt;p&gt;You may, if you wish, follow along with my &lt;a href=&quot;https://github.com/liammclennan/tetris&quot;&gt;git commits&lt;/a&gt;. This step is commit &lt;a href=&quot;https://github.com/liammclennan/tetris/commit/dffea31bfee670f4644eaf8d0586a81f576fd548&quot;&gt;dffea31bfee670f4644eaf8d0586a81f576fd548&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To get to this state:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ git clone https://github.com/liammclennan/tetris.git
$ git checkout dffea31bfee670f4644eaf8d0586a81f576fd548
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;My application starts with a simple, empty, web page:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;style.css&amp;quot;&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;div id=&amp;quot;container&amp;quot;&amp;gt;
    &amp;lt;!-- This element&amp;#39;s contents will be replaced with your component. --&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;script src=&amp;quot;bundle.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note that the webpage includes just two files: style.css and bundle.js. The entire application, including all of my javascript and all required libraries, is bundled into bundle.js by browserify. I know you are wondering how, so let’s inspect package.json:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &amp;quot;name&amp;quot;: &amp;quot;tetris&amp;quot;,
  &amp;quot;version&amp;quot;: &amp;quot;1.0.0&amp;quot;,
  &amp;quot;description&amp;quot;: &amp;quot;&amp;quot;,
  &amp;quot;main&amp;quot;: &amp;quot;index.js&amp;quot;,
  &amp;quot;scripts&amp;quot;: {
    &amp;quot;build&amp;quot;: &amp;quot;browserify -t [ babelify --presets [ react ] ] app.js -o bundle.js&amp;quot;,
    &amp;quot;test&amp;quot;: &amp;quot;echo \&amp;quot;Error: no test specified\&amp;quot; &amp;amp;&amp;amp; exit 1&amp;quot;
  },
  &amp;quot;author&amp;quot;: &amp;quot;&amp;quot;,
  &amp;quot;license&amp;quot;: &amp;quot;ISC&amp;quot;,
  &amp;quot;dependencies&amp;quot;: {
    &amp;quot;babel-preset-react&amp;quot;: &amp;quot;^6.3.13&amp;quot;,
    &amp;quot;babelify&amp;quot;: &amp;quot;^7.2.0&amp;quot;,
    &amp;quot;react&amp;quot;: &amp;quot;^0.14.3&amp;quot;,
    &amp;quot;react-dom&amp;quot;: &amp;quot;^0.14.3&amp;quot;
  },
  &amp;quot;devDependencies&amp;quot;: {
    &amp;quot;babel-preset-es2015&amp;quot;: &amp;quot;^6.3.13&amp;quot;,
    &amp;quot;babelify&amp;quot;: &amp;quot;^7.2.0&amp;quot;
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Package.json is the metadata file for my NPM package. It includes a list of dependencies and the optional ability to execute some scripts. I have defined a &lt;code&gt;build&lt;/code&gt; script as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;browserify -t [ babelify --presets [ react ] ] app.js -o bundle.js
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This &lt;a href=&quot;https://github.com/substack/node-browserify#usage&quot;&gt;tells browserify&lt;/a&gt; to &lt;em&gt;transform&lt;/em&gt; the input via babelify, and when delegating to babel to use the &lt;em&gt;react&lt;/em&gt; preset. &lt;code&gt;app.js&lt;/code&gt; is the root of my application. Browserify will start their and spider through all the included modules. &lt;code&gt;-o bundle.js&lt;/code&gt; sets the output file. To execute this build script:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm run build
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&quot;step-2-a-little-bit-of-tetris&quot;&gt;Step 2 - A Little Bit of Tetris&lt;/h1&gt;
&lt;p&gt;The game tetris involves the placement of &lt;a href=&quot;https://en.wikipedia.org/wiki/Tetromino&quot;&gt;tetrominos&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A tetromino is a geometric shape composed of four squares, connected orthogonally.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;How many tetrominos can you think of? Well there are 5 (I, O, Z, T, L).&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;tetrominos.png&quot; alt=&quot;Tetrominos&quot; style=&quot;width:200px&quot;/&gt;&lt;/p&gt;
&lt;p&gt;React uses components to organise UI elements. The fundamental requirement for a component is that it must have a &lt;code&gt;render&lt;/code&gt; method that defines how a model object is converted into UI. To assemble Tetrominos we can start by defining a component for a single square (in app.js):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var Square = React.createClass({
    render: function() {
            var s = {
            left: (this.props.col-1) * 25 + &amp;#39;px&amp;#39;,
          top: (this.props.row-1) * 25 + &amp;#39;px&amp;#39;
        };
        return &amp;lt;div className=&amp;quot;square&amp;quot; style={s}&amp;gt;&amp;lt;/div&amp;gt;;
    }
});
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This component converts a simple model of the form &lt;code&gt;{col,row}&lt;/code&gt; into a div with the class &lt;code&gt;square&lt;/code&gt; positioned absolutely according to the &lt;code&gt;row&lt;/code&gt; and &lt;code&gt;col&lt;/code&gt; values. With this low-level component we can assemble higher level components for the different tetrominos:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var OShape = React.createClass({
    render: function () {
      return &amp;lt;div&amp;gt;
        &amp;lt;Square row={this.props.row} col={this.props.col} /&amp;gt;
        &amp;lt;Square row={this.props.row} col={this.props.col+1} /&amp;gt;
      &amp;lt;Square row={this.props.row+1} col={this.props.col} /&amp;gt;
          &amp;lt;Square row={this.props.row+1} col={this.props.col+1} /&amp;gt;
    &amp;lt;/div&amp;gt;;
  }
});

var LShape = React.createClass({
    render: function () {
      return &amp;lt;div&amp;gt;
        &amp;lt;Square row={this.props.row} col={this.props.col} /&amp;gt;
          &amp;lt;Square row={this.props.row+1} col={this.props.col} /&amp;gt;
      &amp;lt;Square row={this.props.row+2} col={this.props.col} /&amp;gt;
          &amp;lt;Square row={this.props.row+3} col={this.props.col} /&amp;gt;
    &amp;lt;/div&amp;gt;;
  }
});

var SShape = React.createClass({
    render: function () {
      return &amp;lt;div&amp;gt;
        &amp;lt;Square row={this.props.row} col={this.props.col+1} /&amp;gt;
          &amp;lt;Square row={this.props.row} col={this.props.col+2} /&amp;gt;
      &amp;lt;Square row={this.props.row+1} col={this.props.col} /&amp;gt;
          &amp;lt;Square row={this.props.row+1} col={this.props.col+1} /&amp;gt;
    &amp;lt;/div&amp;gt;;
  }
});
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We can then use React to render some tetrominos into the HTML page we defined earlier:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ReactDOM.render(
&amp;lt;div&amp;gt;
    &amp;lt;OShape row={1} col={1} /&amp;gt;
  &amp;lt;LShape row={1} col={4} /&amp;gt;
  &amp;lt;SShape row={1} col={6} /&amp;gt;
&amp;lt;/div&amp;gt;,
    document.getElementById(&amp;#39;container&amp;#39;)
);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And with that we have the start of the rendering portion of our tetris game! We have done some ES2015 development with modern tooling, and a little bit of React. Redux will enter the picture in a future post.&lt;/p&gt;
&lt;p&gt;If you are following along you can build this using:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm install
npm run build
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then open &lt;code&gt;index.html&lt;/code&gt; in your browser.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>SqlDoc</title>
      <link>http://withouttheloop.com/articles/2015-12-01-sqldoc/</link>
      <pubDate>Tue, 01 Dec 2015 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2015-12-01-sqldoc/</guid>
      <author></author>
      <description>&lt;p&gt;&lt;img src=&quot;doc.png&quot; alt=&quot;Great scott!&quot; align=&quot;left&quot; style=&quot;width: 300px;margin-right: 20px;margin-bottom: 20px;&quot; /&gt; One year ago I built an application data storage library, called &lt;a href=&quot;https://github.com/liammclennan/SqlDoc&quot;&gt;PostgresDoc&lt;/a&gt;. The intent was, and is, to support document db semantics on top of relational databases. I have since renamed the project to &lt;strong&gt;SqlDoc&lt;/strong&gt; to acknowledge that it now works with Postgresql and Sql Server.&lt;/p&gt;
&lt;p&gt;The strengths of SqlDoc compared to a dedicated document db are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;works with your existing database server&lt;/li&gt;
&lt;li&gt;proper, multi-document transactions&lt;/li&gt;
&lt;li&gt;supports joins&lt;/li&gt;
&lt;li&gt;supports a hybrid document / relational model&lt;/li&gt;
&lt;li&gt;easy to project to flat views for reporting and ETL&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The strengths of SqlDoc compared to a relational database are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;simple programming model&lt;/li&gt;
&lt;li&gt;No object / relational mapping&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;new-api&quot;&gt;New API&lt;/h1&gt;
&lt;p&gt;I heard that people like the &lt;code&gt;IDocumentSession&lt;/code&gt; API from RavenDB so I’ve &lt;a href=&quot;https://github.com/liammclennan/SqlDoc/blob/master/TestsCs/DocumentSessionAPITests.cs&quot;&gt;added it to SqlDoc&lt;/a&gt;. This will make life easier for people who want to do data access via a component provided from an IoC container.&lt;/p&gt;
&lt;h2 id=&quot;creating-a-session&quot;&gt;Creating a session&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;var _documentSession =
  new DocumentSession&amp;lt;Guid&amp;gt;(SqlConnection.From(connectionString));
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;adding-a-document&quot;&gt;Adding a document&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;var _aDocument = new PersonCs
{
    _id = Guid.NewGuid(),
    Name = &amp;quot;Docsesh&amp;quot;,
    Age = 90,
    FavouriteThings = new[] { &amp;quot;Golf&amp;quot;, &amp;quot;Statue of liberty&amp;quot; }
};
_documentSession.Store(_aDocument._id, _aDocument);
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;updating-a-document&quot;&gt;Updating a document&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;_aDocument.Age += 1;
_documentSession.Update(_aDocument._id, _aDocument);
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;deleting-a-document&quot;&gt;Deleting a document&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;_documentSession.Delete(_aDocument._id, _aDocument);
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;persisting-the-unit-of-work&quot;&gt;Persisting the unit of work&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;_documentSession.SaveChanges();
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;load-by-id&quot;&gt;Load by id&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;var fresh = _documentSession.Load&amp;lt;PersonCs&amp;gt;(id);
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;load-by-query&quot;&gt;Load by query&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;var result = _documentSession.Query&amp;lt;PersonCs&amp;gt;(
&amp;quot;select data from PersonCs where Data.value(&amp;#39;(/FsPickler/value/instance/idkBackingField)[1]&amp;#39;, &amp;#39;uniqueidentifier&amp;#39;) = @id&amp;quot;,
new Dictionary&amp;lt;string, object&amp;gt; { { &amp;quot;id&amp;quot;, _aDocument._id } });
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&quot;why-you-don-t-need-to-put-idocumentsession-in-an-ioc-container&quot;&gt;Why you don’t need to put IDocumentSession in an IoC container&lt;/h1&gt;
&lt;p&gt;Rather than making your application code take a dependency on IDocumentSession consider instead having your application code returns its results, and then do your data access. That way there is a neat separation between pure application code responsible for logic and calculation and external integration code that does integration with external things like file systems and databases.&lt;/p&gt;
&lt;p&gt;Here is the traditional way:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class MyApp
{
  public MyApp(IDocumentSession documentSession) {}

  public void DoThing() {
    documentSession.Store(new Thing());
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To test that we need to mock documentSession.&lt;/p&gt;
&lt;p&gt;The alternative is to keep the persistence plumbing out of your application:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class MyApp
{
  public static Operation DoThing() {
    var thing = new Thing();
    return Operation.Insert(thing.Id, thing);
  }
}

// consumer
UnitOfWork.Commit(connection, new Queue&amp;lt;Operation&amp;gt;(MyApp.DoThing()));
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This separates the calculation and the logical result of adding a &lt;code&gt;new Thing()&lt;/code&gt; from the mechanism of doing so. To test &lt;code&gt;DoThing()&lt;/code&gt; just call it and inspect the result. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>Cycle.js Starter</title>
      <link>http://withouttheloop.com/articles/2015-11-08-Cycle-Starter/</link>
      <pubDate>Sun, 08 Nov 2015 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2015-11-08-Cycle-Starter/</guid>
      <author></author>
      <description>&lt;p&gt;Just getting a &lt;a href=&quot;http://cycle.js.org/&quot;&gt;cycle.js&lt;/a&gt; app building can take some time. &lt;a href=&quot;https://github.com/liammclennan/cycle-starter&quot;&gt;This repo&lt;/a&gt; is meant to provide a working starting point for a cycle.js app using Babel to compile ES2015 to ES5, webpack to bundle the modules into a script and gulp to orchestrate the build process.&lt;/p&gt;
&lt;p&gt;The build produces a single bundled script in browser/bundle.js.&lt;/p&gt;
&lt;h1 id=&quot;get-started&quot;&gt;Get Started&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;git clone https://github.com/liammclennan/cycle-starter.git
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Install gulp:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm install -g gulp
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Install dependencies:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm install
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Build:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;gulp
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then open &lt;code&gt;index.html&lt;/code&gt; in your browser.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Nokia Ringtone Composer Emulator</title>
      <link>http://withouttheloop.com/articles/2015-10-28-nokia-composer/</link>
      <pubDate>Wed, 28 Oct 2015 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2015-10-28-nokia-composer/</guid>
      <author></author>
      <description>&lt;p&gt;I’ve been working on a Pluralsight F# course for some time. The sample project I chose is to build a web-based emulator of the classic Nokia 3310 composer application that allowed Nokia owners to program their own ringtones. I have previously written about &lt;a href=&quot;http://withouttheloop.com/articles/2014-10-29-fsharp-signal-generator/&quot;&gt;building the tone generator&lt;/a&gt; and &lt;a href=&quot;http://withouttheloop.com/articles/2014-10-30-building-a-parser-with-fparsec/&quot;&gt;parsing the ringtone syntax with FParsec&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The final step was to wrap the composer application in a simple web page, and so&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;my &lt;a href=&quot;http://nokiacomposer.azurewebsites.net/&quot;&gt;Nokia Composer Emulator&lt;/a&gt; is now online!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id=&quot;using-fsharpx-to-make-it-easier-to-work-with-choices&quot;&gt;Using FSharpX to make it easier to work with Choices&lt;/h1&gt;
&lt;p&gt;The composer module returns a &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ee353439.aspx&quot;&gt;&lt;code&gt;Choice&amp;lt;MemoryStream,string&amp;gt;&lt;/code&gt;&lt;/a&gt; that represents either a wave file or a string error message. &lt;code&gt;Choice&lt;/code&gt; is a type with two possible forms, a choice value is either a &lt;code&gt;Choice1Of2 someMemoryStream&lt;/code&gt; or &lt;code&gt;Choice2Of2 &amp;quot;error message&amp;quot;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To work with a choice we pattern match:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    match aChoiceValue with
        | Choice1Of2 stream -&amp;gt; doSomethingWith stream
        | Choice2Of2 error -&amp;gt; printfn &amp;quot;Error: %s&amp;quot; error
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I got sick of constantly pattern matching the choice, doing some calculation and repacking a choice, so I looked to &lt;a href=&quot;http://fsprojects.github.io/FSharpx.Extras/reference/fsharpx-functional-choice.html&quot;&gt;FSharpx&lt;/a&gt; for some help. For my scenario I want do something with the successful value if there is one and pass straight through if there has been an error. FSharpX provides &lt;a href=&quot;https://github.com/fsprojects/FSharpx.Extras/blob/master/src/FSharpx.Extras/ComputationExpressions/Monad.fs#L751-751&quot;&gt;&lt;code&gt;Choice.map&lt;/code&gt;&lt;/a&gt; for this purpose.&lt;/p&gt;
&lt;p&gt;Code goes from&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let assembleToPackedStream (score:string) =
    match parse score with
        | Choice1Of2 tokens -&amp;gt; Choice1Of2 &amp;lt;| pack(assemble tokens)
        | Choice2Of2 error -&amp;gt; Choice2Of2 error
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;to&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let assembleToPackedStream (score:string) =
    Choice.map (fun tokens -&amp;gt; pack(assemble tokens)) (parse score)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If, when processing the success value, I wanted to be able to produce an error I could have used &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/ee353439.aspx&quot;&gt;&lt;code&gt;bind&lt;/code&gt;&lt;/a&gt; instead of &lt;code&gt;map&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let assembleToPackedStream (score:string) =
    Choice.bind (fun tokens -&amp;gt;
                    if thereIsAnError then
                        Choice2Of2 &amp;quot;error message goes here&amp;quot;
                    else
                        Choice1Of2 (pack(assemble tokens)))
        (parse score)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;More commonly people use the &lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt; infix operator for the bind operation.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let assembleToPackedStream (score:string) =
    (parse score) &amp;gt;&amp;gt;= (fun tokens -&amp;gt;
                        if thereIsAnError then
                            Choice2Of2 &amp;quot;error message goes here&amp;quot;
                        else
                            Choice1Of2 (pack(assemble tokens)))
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&quot;f-web-application&quot;&gt;F# Web Application&lt;/h1&gt;
&lt;p&gt;For the web application I use the excellent &lt;a href=&quot;http://bloggemdano.blogspot.com.au/2013/12/a-new-f-aspnet-mvc-5-and-web-api-2.html&quot;&gt;asp.net mvc 5 and web api 2 F# project template&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The action I added to handle the composition post converts an error result to an exception. If the composition was created successfully then the &lt;code&gt;Content-Dispostion&lt;/code&gt; header is set and the wave file returned.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[&amp;lt;HttpPost&amp;gt;]
   member this.Produce(score:string) =
       match Assembler.assembleToPackedStream score with
           | Choice1Of2 ms -&amp;gt;
               this.Response.AppendHeader(
                   &amp;quot;Content-Disposition&amp;quot;,
                   (ContentDisposition(FileName = &amp;quot;sickringtone.wav&amp;quot;, Inline = false)).ToString())
               ms.Position &amp;lt;- 0L
               this.File(ms, &amp;quot;audio/x-wav&amp;quot;)
           | Choice2Of2 err -&amp;gt; failwith err
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In the past I have also used the &lt;a href=&quot;http://bloggemdano.blogspot.com.au/2013/12/a-few-other-template-additions-and.html&quot;&gt;nancy F# templates&lt;/a&gt; which are good.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>The Future of The Web</title>
      <link>http://withouttheloop.com/articles/2015-10-08-future-of-web/</link>
      <pubDate>Thu, 08 Oct 2015 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2015-10-08-future-of-web/</guid>
      <author></author>
      <description>&lt;p&gt;I confess to a nostalgia for the ol’ days of web development, when applications ran on the server, where they belong. To ensure that I am on the right side of history I acknowledge that JavaScript UIs are now defacto standard and therefore turn my attention to making them nicer to build. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;getofflawn.jpg&quot; alt=&quot;Get off my lawn&quot;/&gt;&lt;/p&gt;
&lt;h1 id=&quot;where-are-we-now-&quot;&gt;Where are we now?&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;g.png&quot; alt=&quot;web tech graph&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The image above visualizes the shift to richer user interfaces, and the added technology burden that we have accepted in exchange. I propose that we have given to much ground on complexity, and done so unnecessarily. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;g2.png&quot; alt=&quot;web tech + humility&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The way forward requires a liberal dose of &lt;em&gt;humility&lt;/em&gt;. We must acknowledge our human limitations and compensate by aggresively pursuing simple solutions. If you don’t believe me &lt;a href=&quot;https://www.cs.utexas.edu/~EWD/transcriptions/EWD03xx/EWD340.html&quot;&gt;listen to Dijkstra&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img style=&quot;width:200px&quot; src=&quot;dijkstra.jpg&quot; alt=&quot;Dijkstra&quot; align=&quot;right&quot;/&gt; “We shall do a much better programming job, provided that we approach the task with a full appreciation of its tremendous difficulty, provided that we stick to modest and elegant programming languages, provided that we respect the intrinsic limitations of the human mind and approach the task as Very Humble Programmers.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id=&quot;the-humble-programmer&quot;&gt;The Humble Programmer&lt;/h1&gt;
&lt;p&gt;The humble programmer recognizes that &lt;a href=&quot;http://www.infoq.com/presentations/Simple-Made-Easy&quot;&gt;simple is more important than easy&lt;/a&gt;, and more important than feeding our egos.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;hitler.jpg&quot; alt=&quot;The humble programmer is not pleased&quot; /&gt;&lt;br/&gt;
&lt;em&gt;The Humble Programmer is not pleased&lt;/em&gt;&lt;/p&gt;
&lt;h1 id=&quot;poor-richard-s-web-architecture-of-the-future&quot;&gt;Poor Richard’s Web Architecture of the Future&lt;/h1&gt;
&lt;p&gt;From the tar pit of web development tools a concensus is slowly emerging of what a simple web application design of the future might be. This design, sometimes called MVI, consists of three components: a model, a view and intents.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;mvi.png&quot; alt=&quot;MVI&quot; /&gt;&lt;/p&gt;
&lt;h2 id=&quot;the-model&quot;&gt;The Model&lt;/h2&gt;
&lt;p&gt;The model is a single data structure containing the entire user interface state for the application. This must include &lt;strong&gt;everything&lt;/strong&gt; required to describe the user interface, including things like highlighted controls, and scroll position. &lt;/p&gt;
&lt;h2 id=&quot;the-view&quot;&gt;The View&lt;/h2&gt;
&lt;p&gt;Given an exhaustive model as described above the &lt;em&gt;view&lt;/em&gt; can be reduced to a simple function, from the model to a user interface. &lt;/p&gt;
&lt;h2 id=&quot;intents&quot;&gt;Intents&lt;/h2&gt;
&lt;p&gt;Intents, sometimes called actions, are simple values that represent things that the user wants to do. Typically, intents are generated by events, e.g. a button click event may produce a ‘user wants to add an item to a list’ intent. Intents are then processed as updates to the model. When the model changes the view is regenerated. &lt;/p&gt;
&lt;h1 id=&quot;mvi-from-first-principles&quot;&gt;MVI from First Principles&lt;/h1&gt;
&lt;p&gt;A good way to understand something is to build one, so let us create an MVI application from scratch. &lt;/p&gt;
&lt;p&gt;The application state is a random number (between 0 and 10). The view renders that number in a heading. Clicking on the heading indicates that the user intends to see the square of the number. The ‘square’ intent is processed by squaring the number in the application state. Because the application state has changed the view is re-rendered.&lt;/p&gt;
&lt;iframe width=&quot;100%&quot; height=&quot;300&quot; src=&quot;//jsfiddle.net/b6gosd2d/embedded/result,js&quot; allowfullscreen=&quot;allowfullscreen&quot; frameborder=&quot;0&quot;&gt;&lt;/iframe&gt;

&lt;h1 id=&quot;more-info&quot;&gt;More Info&lt;/h1&gt;
&lt;p&gt;The &lt;a href=&quot;https://github.com/evancz/elm-architecture-tutorial/&quot;&gt;Elm Architecture Tutorial&lt;/a&gt; is a good read, describing many of the same ideas mentioned here. &lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://cycle.js.org/&quot;&gt;Cycle.js&lt;/a&gt; is another implementation worth exploring. To my knowledge it is the source of the MVI terminology. &lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/rackt/redux&quot;&gt;Redux&lt;/a&gt; is a “state container for JavaScript apps”, meaning it holds the state object and controls the application of intents/actions to it. &lt;a href=&quot;http://facebook.github.io/react/&quot;&gt;React&lt;/a&gt; provides an implementation of the view component. Redux is designed to work with React and together they complete the MVI design. &lt;/p&gt;
&lt;h1 id=&quot;dijkstra-s-final-thoughts&quot;&gt;Dijkstra’s Final Thoughts&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;“The competent programmer is fully aware of the strictly limited size of his own skull; therefore he approaches the programming task in full humility”&lt;/p&gt;
&lt;/blockquote&gt;
</description>
    </item>
    <item>
      <title>Product Review - Kogan Fortis Magnetic Indoor Bicycle Trainer</title>
      <link>http://withouttheloop.com/articles/2015-09-14-kogan-fortis-bicycle-trainer/</link>
      <pubDate>Mon, 14 Sep 2015 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2015-09-14-kogan-fortis-bicycle-trainer/</guid>
      <author></author>
      <description>&lt;p&gt;I’m reviewing the &lt;a href=&quot;https://www.kogan.com/au/buy/fortis-magnetic-indoor-bicycle-trainer/&quot;&gt;fortis magnetic indoor bicycle trainer&lt;/a&gt; because no one else has. I have only used mine twice so I can’t comment on longevity and it is my first turbo trainer so I don’t know how it compares to others. Here is what I do know.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;tt.jpg&quot; alt=&quot;Fortis magnetic indoor bicycle trainer&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Assembly is straightforward - simply mount the resistance thingo on the frame, and swap the rear quick release skewer on your bike for the supplied one that fits the frame mounts. I’m not sure if this skewer is suitable for regular riding, and I’m not game to find out at 70km/h down a hill, so I swap my regular skewer back in before hitting the road. It is simple to mount the bike but important that the surface be perfectly level. A tightening bolt is then used to secure the roller against your bike’s back wheel. Resistance is controlled via a handlebar mounted dial.&lt;/p&gt;
&lt;h1 id=&quot;the-good&quot;&gt;The good&lt;/h1&gt;
&lt;p&gt;The device seems reasonably sturdy and works as advertised. I get exercise. Assembly was simple.&lt;/p&gt;
&lt;h1 id=&quot;the-less-good&quot;&gt;The less good&lt;/h1&gt;
&lt;p&gt;There are 6 resistance levels and none of them are very difficult. I think a good cyclist may struggle to struggle. The resistance has a lot of inertia, so it is difficult at first but becomes easier with momentum. It feels like you are spinning up a flywheel. Very much the opposite of actual cycling.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Learning Cycle.js</title>
      <link>http://withouttheloop.com/articles/2015-09-03-learning-cyclejs/</link>
      <pubDate>Thu, 03 Sep 2015 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2015-09-03-learning-cyclejs/</guid>
      <author></author>
      <description>&lt;p&gt;&lt;img src=&quot;cyclejs_logo.svg&quot; alt=&quot;Cycle.js logo&quot; style=&quot;width:250px;&quot; align=&quot;right&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://cycle.js.org/&quot;&gt;Cycle.js&lt;/a&gt; is clearly React inspired, but it attempts to fix some areas where React is deficient, or weird. It also advocates (forces?) a functional style, composing immutable state via observables.&lt;/p&gt;
&lt;p&gt;Even with a React background the learning curve is steep. I started to see how it is possible to reason about Cycle.js applications when I saw &lt;a href=&quot;https://meet.lync.com/readify-net/liam.mclennan/LW6W5FMZ&quot;&gt;the refactoring to the Intent-Model-View pattern&lt;/a&gt;. See &lt;a href=&quot;http://jsbin.com/vikaga/1/edit?js,output&quot;&gt;jsbin&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This post includes graphics and code samples from the &lt;a href=&quot;http://cycle.js.org/&quot;&gt;Cycle.js&lt;/a&gt; website.&lt;/p&gt;
&lt;h1 id=&quot;intent&quot;&gt;Intent&lt;/h1&gt;
&lt;p&gt;Intent is typically a function from sources of input (drivers) (DOM, HTTP, etc) to a set of observables, named according to the user’s intent (e.g. &lt;code&gt;changeHeight$&lt;/code&gt;, &lt;code&gt;receiveUserDetails$&lt;/code&gt;).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function intent(DOM) {
  return {
    changeWeight$: DOM.get(&amp;#39;#weight&amp;#39;, &amp;#39;input&amp;#39;)
      .map(ev =&amp;gt; ev.target.value),
    changeHeight$: DOM.get(&amp;#39;#height&amp;#39;, &amp;#39;input&amp;#39;)
      .map(ev =&amp;gt; ev.target.value)
  };
}
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&quot;model&quot;&gt;Model&lt;/h1&gt;
&lt;p&gt;Model is a function from intents (produced by the &lt;code&gt;Intent&lt;/code&gt; function) to a &lt;code&gt;state$&lt;/code&gt; observable. The latest value of the &lt;code&gt;state$&lt;/code&gt; observable is the current state of the component. &lt;code&gt;state$&lt;/code&gt; is observed by the view, so changes to &lt;code&gt;state$&lt;/code&gt; cause changes to the view. Earlier examples had the state spread across multiple observables (e.g. one for the DOM, one for each possible HTTP request). Consolidating state into a single observable takes some work but makes the component easier to reason about and the view easier to implement.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function model(actions) {
  return Cycle.Rx.Observable.combineLatest(
    actions.changeWeight$.startWith(70),
    actions.changeHeight$.startWith(170),
    (weight, height) =&amp;gt;
      ({weight, height, bmi: calculateBMI(weight, height)})
  );
}
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&quot;view&quot;&gt;View&lt;/h1&gt;
&lt;p&gt;View is a function from the model observable (&lt;code&gt;state$&lt;/code&gt;) to a vdom observable. This is equivalent to React’s &lt;code&gt;Render&lt;/code&gt; function.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function view(state$) {
  return state$.map(({weight, height, bmi}) =&amp;gt;
    h(&amp;#39;div&amp;#39;, [
      renderWeightSlider(weight),
      renderHeightSlider(height),
      h(&amp;#39;h2&amp;#39;, &amp;#39;BMI is &amp;#39; + bmi)
    ])
  );
}
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&quot;main-&quot;&gt;main()&lt;/h1&gt;
&lt;svg  style=&quot;width:100px;&quot; viewBox=&quot;0 0 209 507&quot; version=&quot;1.1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot; xmlns:sketch=&quot;http://www.bohemiancoding.com/sketch/ns&quot;&gt;
    &lt;!-- Generator: Sketch 3.3.2 (12043) - http://www.bohemiancoding.com/sketch --&gt;
    &lt;title&gt;Group&lt;/title&gt;
    &lt;desc&gt;Created with Sketch.&lt;/desc&gt;
    &lt;defs&gt;&lt;/defs&gt;
    &lt;g id=&quot;human-computer&quot; stroke=&quot;none&quot; stroke-width=&quot;1&quot; fill=&quot;none&quot; fill-rule=&quot;evenodd&quot; sketch:type=&quot;MSPage&quot;&gt;
        &lt;g id=&quot;Group&quot; sketch:type=&quot;MSLayerGroup&quot; transform=&quot;translate(-45.000000, -15.000000)&quot;&gt;
            &lt;circle id=&quot;Oval-1&quot; stroke=&quot;#9AC572&quot; stroke-width=&quot;10&quot; fill=&quot;#A5FF51&quot; sketch:type=&quot;MSShapeGroup&quot; cx=&quot;146&quot; cy=&quot;419&quot; r=&quot;38&quot;&gt;&lt;/circle&gt;
            &lt;circle id=&quot;Oval-2&quot; stroke=&quot;#B9B9B9&quot; stroke-width=&quot;10&quot; fill=&quot;#DDDDDD&quot; sketch:type=&quot;MSShapeGroup&quot; cx=&quot;146&quot; cy=&quot;140&quot; r=&quot;38&quot;&gt;&lt;/circle&gt;
            &lt;text id=&quot;Human&quot; sketch:type=&quot;MSTextLayer&quot; font-family=&quot;Source Sans Pro&quot; font-size=&quot;50&quot; font-weight=&quot;normal&quot; sketch:alignment=&quot;middle&quot; fill=&quot;#7DA25A&quot;&gt;
                &lt;tspan x=&quot;68.4&quot; y=&quot;521&quot;&gt;Human&lt;/tspan&gt;
            &lt;/text&gt;
            &lt;text id=&quot;Computer&quot; sketch:type=&quot;MSTextLayer&quot; font-family=&quot;Source Sans Pro&quot; font-size=&quot;50&quot; font-weight=&quot;normal&quot; sketch:alignment=&quot;middle&quot; fill=&quot;#747474&quot;&gt;
                &lt;tspan x=&quot;43.7&quot; y=&quot;49&quot;&gt;Computer&lt;/tspan&gt;
            &lt;/text&gt;
            &lt;g id=&quot;Path-15-+-Path-2&quot; transform=&quot;translate(98.500000, 282.000000) scale(1, -1) translate(-98.500000, -282.000000) translate(75.000000, 183.000000)&quot; stroke=&quot;#979797&quot; sketch:type=&quot;MSShapeGroup&quot;&gt;
                &lt;path d=&quot;M37.3775229,1.50509088 L16.9737944,18.4291738 L37.3775229,34.2764494&quot; id=&quot;Path-15&quot; stroke-width=&quot;7&quot; transform=&quot;translate(27.175659, 17.890770) rotate(125.000000) translate(-27.175659, -17.890770) &quot;&gt;&lt;/path&gt;
                &lt;path d=&quot;M26.9129005,197.154998 C26.9129005,197.154998 -34.8157014,98.8736491 31,12.3678484&quot; id=&quot;Path-2&quot; stroke-width=&quot;9&quot;&gt;&lt;/path&gt;
            &lt;/g&gt;
            &lt;g id=&quot;Path-15-+-Path-3&quot; transform=&quot;translate(194.500000, 279.000000) scale(-1, 1) translate(-194.500000, -279.000000) translate(171.000000, 180.000000)&quot; stroke=&quot;#9BC672&quot; sketch:type=&quot;MSShapeGroup&quot;&gt;
                &lt;path d=&quot;M37.3775229,1.50509088 L16.9737944,18.4291738 L37.3775229,34.2764494&quot; id=&quot;Path-15&quot; stroke-width=&quot;7&quot; transform=&quot;translate(27.175659, 17.890770) rotate(125.000000) translate(-27.175659, -17.890770) &quot;&gt;&lt;/path&gt;
                &lt;path d=&quot;M26.9129005,197.154998 C26.9129005,197.154998 -34.8157014,98.8736491 31,12.3678484&quot; id=&quot;Path-2&quot; stroke-width=&quot;9&quot;&gt;&lt;/path&gt;
            &lt;/g&gt;
        &lt;/g&gt;
    &lt;/g&gt;
&lt;/svg&gt;

&lt;p&gt;A cycle.js application includes a function that represents the computer side of the human-computer interaction, often called &lt;code&gt;main&lt;/code&gt;. It is a function from input drivers (http responses, DOM events) to output drivers (http requests, vdom structure). The &lt;a href=&quot;http://jsbin.com/yizisa/6/edit?js,output&quot;&gt;Get Random User&lt;/a&gt; example shows working with two drivers (HTTP and DOM).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function main({DOM}) {
  return {DOM: view(model(intent(DOM)))};
}
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&quot;cycle-run-&quot;&gt;Cycle.run()&lt;/h1&gt;
&lt;p&gt;An application is started by calling &lt;code&gt;Cycle.run()&lt;/code&gt; specifying the &lt;code&gt;main&lt;/code&gt; function and the required drivers. E.g.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Cycle.run(main, {
  DOM: makeDOMDriver(&amp;#39;#app&amp;#39;),
  HTTP: makeHTTPDriver()
});
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>Ten Lessons From a Large IoT Project</title>
      <link>http://withouttheloop.com/articles/2015-09-02-iot-lessons/</link>
      <pubDate>Wed, 02 Sep 2015 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2015-09-02-iot-lessons/</guid>
      <author></author>
      <description>&lt;p&gt;&lt;img src=&quot;wc.jpg&quot;/&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Lesson 1&lt;/strong&gt;: Big data tools don’t solve the intractable problems of distributed system. They leak complexity to the consumer.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Lesson 2&lt;/strong&gt;: Peak performance often relies on even distribution across partitions. Hashing keys can help. Try SHA256.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Lesson 3&lt;/strong&gt;: To prevent DOS attacks public cloud components like Event Hub throw exceptions if you exceed quotas. The client must take responsibility for throttling.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Lesson 4&lt;/strong&gt;: &lt;a href=&quot;https://azure.microsoft.com/en-us/documentation/articles/web-sites-create-web-jobs/&quot;&gt;Azure web jobs are brilliant&lt;/a&gt;. They provide a way to run a console application as a reliable service that can be scaled horizontally. Web jobs are simple and they work.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Lesson 5&lt;/strong&gt;: &lt;a href=&quot;https://engineering.linkedin.com/distributed-systems/log-what-every-software-engineer-should-know-about-real-time-datas-unifying&quot;&gt;Distributed logs are a useful data structure for distributed systems&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Lesson 6&lt;/strong&gt;: To understand what is happening in a system you need centralised logging with a correlation scheme.  &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Lesson 7&lt;/strong&gt;: As metrics get larger we lose the ability to reason about them. 50/500/5000/50000 requests/s are very different. Those differences matter.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Lesson 8&lt;/strong&gt;: Very large datasets (PB) drastically reduce data storage options.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Lesson 9&lt;/strong&gt;: Consistency in the absence of transactions is hard. You will have to think about it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Lesson 10&lt;/strong&gt;: All actions must be idempotent. Work in batches. If an error occurs during a batch the idempotency allows the batch to be replayed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Lesson 11&lt;/strong&gt;: Tuning batch size substantially affects performance. Large batches and low error rates are the sweet spot. Higher error rates require smaller batches.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Processing HBASE data with Rx</title>
      <link>http://withouttheloop.com/articles/2015-07-27-processing-hbase-data/</link>
      <pubDate>Mon, 27 Jul 2015 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2015-07-27-processing-hbase-data/</guid>
      <author></author>
      <description>&lt;p&gt;&lt;a href=&quot;http://hbase.apache.org/&quot;&gt;HBase&lt;/a&gt; is good at many things but adhoc querying is not one of them. You can query by key, or you can scan over a range of keys. Sometimes it is handy to be able to monitor a table and process rows as they are added. This kind of processing over a stream is what &lt;a href=&quot;http://reactivex.io/&quot;&gt;Reactive Extensions (Rx)&lt;/a&gt; is good at, so why not combine hbase querying with Rx Observables?&lt;/p&gt;
&lt;p&gt;I’ll be using the Microsoft Hbase client and an Azure HBase cluster. What I want is to convert an Hbase table into an Rx observable, so that I can filter, transform, group and fold. Step 1 is to fetch my observable:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var hotRows = HBaseToObservable.Build(new Uri(&amp;quot;https://redacted.azurehdinsight.net&amp;quot;), &amp;quot;????&amp;quot;, &amp;quot;??????&amp;quot;,
&amp;quot;tablename&amp;quot;,&amp;quot;start_key&amp;quot;)
.Select(r =&amp;gt; new {
key = Encoding.UTF8.GetString(r.key),
data = r.values.ToDictionary(
  v =&amp;gt; Encoding.UTF8.GetString(v.column),
  v=&amp;gt; Encoding.UTF8.GetString(v.data))});
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;hotRows&lt;/code&gt; is now an observable reading forward over the hbase table &lt;code&gt;tablename&lt;/code&gt; from the key &lt;code&gt;start_key&lt;/code&gt;. As new records are appended to the table they will be pushed through the observable.&lt;/p&gt;
&lt;h2 id=&quot;why-do-we-want-an-observable-view-of-an-hbase-table-&quot;&gt;Why do we want an observable view of an hbase table?&lt;/h2&gt;
&lt;p&gt;This is most useful for a table storing data such as timeseries data, where we want a live, forward-only stream. With an observable we can do things like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;hotRows
  .Where(r =&amp;gt; r.data[&amp;quot;some_column&amp;quot;] == &amp;quot;whatever&amp;quot;)
  .GroupBy(r =&amp;gt; r.data[&amp;quot;colour&amp;quot;])
  .Select(r =&amp;gt; r.data[&amp;quot;radius&amp;quot;] * Math.PI);
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;how-is-it-implemented-&quot;&gt;How is it implemented?&lt;/h2&gt;
&lt;p&gt;In short, it creates an observable, and an hbase table scanner, and pushes rows to the observable. Once it reaches the end of the table it polls every three seconds for new rows.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class HBaseToObservable
{
    public static IObservable&amp;lt;CellSet.Row&amp;gt; Build(
        Uri server,
        string username,
        string password,
        string tableName,
        string startKey
        )
    {
        var creds = new ClusterCredentials(server, username, password);
        var client = new HBaseClient(creds);
        var rowsOut = new ReplaySubject&amp;lt;CellSet.Row&amp;gt;();

        Task.Run(()=&amp;gt;{
            GetRows(rowsOut,client,tableName,startKey);
        });
        return rowsOut;
    }

    private static void GetRows(ReplaySubject&amp;lt;CellSet.Row&amp;gt; rowsOut,
        HBaseClient client,
        string tableName,
        string startKey) {
        CellSet next = null;
        string lastKey = &amp;quot;&amp;quot;;

        var scannerInfo = client.CreateScanner(tableName, new Scanner()
        {
            batch = 100,
            startRow = Encoding.UTF8.GetBytes(startKey),
            endRow = BitConverter.GetBytes(int.MaxValue)
        });
        while ((next = client.ScannerGetNext(scannerInfo)) != null)
            {
                foreach (var row in next.rows) {
                    lastKey = Encoding.UTF8.GetString(row.key);
                    rowsOut.OnNext(row);
                }
            }
        Task.Delay(TimeSpan.FromSeconds(3))
            .ContinueWith((t)=&amp;gt;GetRows(rowsOut,client,tableName,lastKey));
    }
}
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>Dealing With Unreliable TPL Tasks</title>
      <link>http://withouttheloop.com/articles/2015-07-22-unreliable-tasks/</link>
      <pubDate>Wed, 22 Jul 2015 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2015-07-22-unreliable-tasks/</guid>
      <author></author>
      <description>&lt;p&gt;Suppose you have a collection of .net TPL tasks and the knowledge that some of them may fail (throw an exception) and some may take an unacceptably long period of time to resolve. In the case of the errored tasks you wish to collect information to assist diagnosis. In the case of the long running tasks you wish to ignore them and allow the program to carry on so that throughput is maintained.&lt;/p&gt;
&lt;p&gt;This is not a simple problem when using the .net TPL (Task&lt;T&gt;, async, await, etc), which seems to be designed with an all or nothing mentality. Consider the following motely crew of tasks:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Task&amp;lt;int?&amp;gt;[] calcTasks = new [] {
    Task.Run(() =&amp;gt; {
        Thread.Sleep(200);
        var div = 0;
        return new Nullable&amp;lt;int&amp;gt;(5/div);
    }),
    Task.Run(() =&amp;gt; {
        Thread.Sleep(100);
        return new Nullable&amp;lt;int&amp;gt;(42);
    }),
    Task.Run(() =&amp;gt; {
        Thread.Sleep(1500);
        return new Nullable&amp;lt;int&amp;gt;(99);
    })
};
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;All three are asynchronous operations including a time delay. The first task attempts to divide by zero and will therefore throw a &lt;code&gt;DivideByZero&lt;/code&gt; exception. The last task sleeps for 1.5s, which exceeds the acceptable timeout for my use case. Only the second task will succeed, ultimately producing the value &lt;code&gt;42&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;What is needed now is a function to process a collection of tasks, in the context of a particular timeout duration, and return a collection of results. Each result should describe the fate of one task. The class I use to represent the result of a Task that may error or timeout is &lt;code&gt;AsyncTimedResult&amp;lt;TResult&amp;gt;&lt;/code&gt; described below:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public enum AsyncResultStates
{
    Unknown, TimedOut, Resolved, Faulted
}

public class AsyncTimedResult&amp;lt;TResult&amp;gt;
{
    public TResult Result { get; private set; }
    public Exception Error { get; private set; }
    public AsyncResultStates State { get; private set; }
    public string Message { get; private set; }

    protected AsyncTimedResult()
    {
        Message = &amp;quot;&amp;quot;;
        State = AsyncResultStates.Unknown;
    }

    ...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To process a collection of unreliable tasks I use a function called &lt;code&gt;ExtractResults&lt;/code&gt;, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;AsyncTimedResult&amp;lt;int?&amp;gt;[] results = await
    UnreliableTasks.ExtractResults(calcTasks, TimeSpan.FromSeconds(1));
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I can then categorize the results by their state:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var succeeded = results.Where(UnreliableTasks.IsResolved);
var faulted = results.Where(UnreliableTasks.IsFaulted);
var timedout = results.Where(UnreliableTasks.IsTimedOut);
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;how-does-it-work-&quot;&gt;How Does it Work?&lt;/h2&gt;
&lt;p&gt;The TPL doesn’t include any support for adding timeouts to tasks. We simulate timeouts with a bit of a hack. For each task that we wish to evaluate against a timeout, we create a new task that will resolve at the timeout limit, then we race the two tasks using &lt;code&gt;Task.WhenAny()&lt;/code&gt; which results in the first task to resolve. If the timeout task resolves first then we know that our task timed out.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var taskICareAbout = Task.Run(() =&amp;gt; {
    Thread.Sleep(200);
    var div = 0;
    return new Nullable&amp;lt;int&amp;gt;(5/div);
});
var timerTask = Task.Delay(TimeSpan.FromMilliseconds(100))
  .ContinueWith(t =&amp;gt; default(int?));
var first = await Task.WhenAny&amp;lt;int?&amp;gt;(taskICareAbout, timerTask);
if (first == taskICareAbout) {
  // my task completed first
} else {
  // timer task completed first
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;timerTask&lt;/code&gt; has a continuation just to convert it to the same type as our other task. For &lt;code&gt;ExtractResults&lt;/code&gt; I also need to process the results and categorize them by state. The full implementation is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static async Task&amp;lt;AsyncTimedResult&amp;lt;T&amp;gt;[]&amp;gt; ExtractResults&amp;lt;T&amp;gt;(IEnumerable&amp;lt;Task&amp;lt;T&amp;gt;&amp;gt; tasks, TimeSpan timeout)
{
    var tasksWithTimeouts = tasks.Select(t =&amp;gt;
        Task.WhenAny&amp;lt;T&amp;gt;(Task.Delay(timeout).ContinueWith(t2 =&amp;gt; default(T)), t));
    var everything = Task.WhenAll(tasksWithTimeouts)
        .ContinueWith(t =&amp;gt; t.Result.Select(ti =&amp;gt;
        {
            if (ti.IsFaulted || ti.Exception != null)
            {
                return AsyncTimedResult&amp;lt;T&amp;gt;.Reject(ti.Exception);
            }
            if (ti.Result == null || ti.Result.Equals(default(T)))
            {
                return AsyncTimedResult&amp;lt;T&amp;gt;.TimeOut();
            }

            return AsyncTimedResult&amp;lt;T&amp;gt;.Resolve(ti.Result);
        }));
    var results = await everything;
    return results.ToArray();
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;all-together&quot;&gt;All Together&lt;/h2&gt;
&lt;p&gt;Here is a complete console app demonstrating the method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace TasksC
{
    class Program
    {
        static void Main(string[] args)
        {
            Do().Wait();
        }

        private static async Task Do()
        {
            Task&amp;lt;int?&amp;gt;[] calcTasks = new[] {
                Task.Run(() =&amp;gt; {
                    Thread.Sleep(200);
                    var div = 0;
                    return new Nullable&amp;lt;int&amp;gt;(5/div);
                }),
                Task.Run(() =&amp;gt; {
                    Thread.Sleep(100);
                    return new Nullable&amp;lt;int&amp;gt;(42);
                }),
                Task.Run(() =&amp;gt; {
                    Thread.Sleep(1500);
                    return new Nullable&amp;lt;int&amp;gt;(99);
                })
            };

            var results = await UnreliableTasks.ExtractResults(calcTasks, TimeSpan.FromSeconds(1));
            var succeeded = results.Where(UnreliableTasks.IsResolved);
            var faulted = results.Where(UnreliableTasks.IsFaulted);
            var timedout = results.Where(UnreliableTasks.IsTimedOut);

            Console.WriteLine(string.Join(&amp;quot;,&amp;quot;, succeeded.Select(n =&amp;gt; n.Result)));
            Console.WriteLine(&amp;quot;\nErrors:\n&amp;quot;);
            Console.WriteLine(string.Join(&amp;quot;,&amp;quot;, faulted
                .Select(n =&amp;gt; n.Error.InnerException.Message).ToArray()));
            Console.WriteLine(&amp;quot;\nTimeouts:\n&amp;quot;);
            Console.WriteLine(timedout.Count());
            Console.ReadLine();
        }
    }

    public class UnreliableTasks
    {
        public static async Task&amp;lt;AsyncTimedResult&amp;lt;T&amp;gt;[]&amp;gt; ExtractResults&amp;lt;T&amp;gt;(IEnumerable&amp;lt;Task&amp;lt;T&amp;gt;&amp;gt; tasks, TimeSpan timeout)
        {
            var tasksWithTimeouts = tasks.Select(t =&amp;gt;
                Task.WhenAny&amp;lt;T&amp;gt;(Task.Delay(timeout).ContinueWith(t2 =&amp;gt; default(T)), t));
            var everything = Task.WhenAll(tasksWithTimeouts)
                .ContinueWith(t =&amp;gt; t.Result.Select(ti =&amp;gt;
                {
                    if (ti.IsFaulted || ti.Exception != null)
                    {
                        return AsyncTimedResult&amp;lt;T&amp;gt;.Reject(ti.Exception);
                    }
                    if (ti.Result == null || ti.Result.Equals(default(T)))
                    {
                        return AsyncTimedResult&amp;lt;T&amp;gt;.TimeOut();
                    }

                    return AsyncTimedResult&amp;lt;T&amp;gt;.Resolve(ti.Result);
                }));
            var results = await everything;
            return results.ToArray();
        }

        public enum AsyncResultStates
        {
            Unknown, TimedOut, Resolved, Faulted
        }

        public static bool IsResolved&amp;lt;T&amp;gt;(AsyncTimedResult&amp;lt;T&amp;gt; result)
        {
            return result.State == AsyncResultStates.Resolved;
        }

        public static bool IsFaulted&amp;lt;T&amp;gt;(AsyncTimedResult&amp;lt;T&amp;gt; result)
        {
            return result.State == AsyncResultStates.Faulted;
        }

        public static bool IsTimedOut&amp;lt;T&amp;gt;(AsyncTimedResult&amp;lt;T&amp;gt; result)
        {
            return result.State == AsyncResultStates.TimedOut;
        }

        public class AsyncTimedResult&amp;lt;TResult&amp;gt;
        {
            public TResult Result { get; private set; }
            public Exception Error { get; private set; }
            public AsyncResultStates State { get; private set; }
            public string Message { get; private set; }

            protected AsyncTimedResult()
            {
                Message = &amp;quot;&amp;quot;;
                State = AsyncResultStates.Unknown;
            }

            public static AsyncTimedResult&amp;lt;TResult&amp;gt; Resolve(TResult result)
            {
                return new AsyncTimedResult&amp;lt;TResult&amp;gt;() { Result = result, State = AsyncResultStates.Resolved };
            }

            public static AsyncTimedResult&amp;lt;TResult&amp;gt; Reject(Exception ex)
            {
                return new AsyncTimedResult&amp;lt;TResult&amp;gt;() { Error = ex, State = AsyncResultStates.Faulted };
            }

            public static AsyncTimedResult&amp;lt;TResult&amp;gt; TimeOut()
            {
                return new AsyncTimedResult&amp;lt;TResult&amp;gt;() { State = AsyncResultStates.TimedOut };
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>Deploying custom services as Azure Webjobs</title>
      <link>http://withouttheloop.com/articles/2015-06-23-deploying-custom-services-as-azure-webjobs/</link>
      <pubDate>Tue, 23 Jun 2015 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2015-06-23-deploying-custom-services-as-azure-webjobs/</guid>
      <author></author>
      <description>&lt;p&gt;Azure has this thing called &lt;a href=&quot;http://www.hanselman.com/blog/IntroducingWindowsAzureWebJobs.aspx&quot;&gt;webjobs&lt;/a&gt;. It is a curious way of deploying continous or scheduled services as sub-processes of an Azure website. This may be a desirable option because:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;it’s a PaaS thing. You don’t have to manage a server.&lt;/li&gt;
&lt;li&gt;you get configurable scale - including autoscaling&lt;/li&gt;
&lt;li&gt;you can run many logical services within a single management unit (Azure Website)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I did not enjoy my time with the MSDN documentation for Azure Webjobs. They document the manual process for working with Webjobs, either the Visual Studio Azure tooling or through the Azure portal. Manual deployment processes, involving clicking lots of buttons with a mouse, a not going to be workable on my team, so I need a way to automate deployment. Also, the documentation only shows how to write services that are coupled to Azure. I want to be able to run my service locally. &lt;/p&gt;
&lt;h2 id=&quot;step-1-use-a-console-app-for-your-service&quot;&gt;Step 1: Use a console app for your service&lt;/h2&gt;
&lt;p&gt;The holy grail of .net services has been wrapping console apps for a long time, often using something like Topshelf. The goal is to get the reliability of a service for deployment but the ease of development and testing of a console app. &lt;/p&gt;
&lt;p&gt;To create a console app for deployment as an Azure Webjob:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;create a normal, regular, vanilla, wonderful console application.&lt;/li&gt;
&lt;li&gt;create a web project&lt;/li&gt;
&lt;li&gt;in the web projects context menu choose Add -&amp;gt; Existing project as Azure webjob and select your console application&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;step-2-packaging-for-deployment&quot;&gt;Step 2: Packaging for deployment&lt;/h2&gt;
&lt;p&gt;The secret to Azure Webjob deployment is to include your executable in the web project at:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;App_Data\jobs\{job type}\{job name}&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That is the one bit of information to really need to know and it is conspicuously absent from the documentation. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;shake.gif&quot;/&gt;&lt;/p&gt;
&lt;p&gt;There are a number of different ways to accomplish this goal. One is to use a post-build step like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;copy &amp;quot;$(SolutionDir)mywebjob\bin\$(ConfigurationName)\*.*&amp;quot; &amp;quot;$(ProjectDir)App_Data\jobs\continuous\mywebjob&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;which you can add via the &lt;code&gt;Build Events&lt;/code&gt; tab of the web project’s properties page. &lt;/p&gt;
&lt;p&gt;Because we are using Teamcity to build and package our web project as a nuget package for deployment via Octopus Deploy we can use a nuspec file instead. &lt;/p&gt;
&lt;p&gt;A simple nuspec file looks something like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;
&amp;lt;package &amp;gt;
  &amp;lt;metadata&amp;gt;
    &amp;lt;id&amp;gt;MyProjectName&amp;lt;/id&amp;gt;
      &amp;lt;version&amp;gt;0.0.0.0&amp;lt;/version&amp;gt;
      &amp;lt;authors&amp;gt;NA&amp;lt;/authors&amp;gt;
    &amp;lt;owners&amp;gt;NA&amp;lt;/owners&amp;gt;
    &amp;lt;requireLicenseAcceptance&amp;gt;false&amp;lt;/requireLicenseAcceptance&amp;gt;
    &amp;lt;description&amp;gt;NA&amp;lt;/description&amp;gt;
    &amp;lt;copyright&amp;gt;Copyright 2015&amp;lt;/copyright&amp;gt;
  &amp;lt;/metadata&amp;gt;
    &amp;lt;files&amp;gt;
        &amp;lt;file src=&amp;quot;..\MyWebJob\bin\release\**&amp;quot; target=&amp;quot;App_Data\jobs\continuous\MyWebJob&amp;quot;/&amp;gt;
    &amp;lt;/files&amp;gt;
&amp;lt;/package&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Using Octopack in Teamcity to produce a nupkg package from this nuspec file will fail because the &lt;code&gt;files&lt;/code&gt; element will override the default behaviour of Octopack and only include the listed files. To instruct Octopack to include all the normal project files, as well as the webjob files listed in the nuspec file, add the following element to the web project’s csproj file (in the &lt;code&gt;&amp;lt;PropertyGroup&amp;gt;&lt;/code&gt; element):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;OctoPackEnforceAddingFiles&amp;gt;True&amp;lt;/OctoPackEnforceAddingFiles&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This seems to be an undocumented feature, but it works. &lt;/p&gt;
&lt;h2 id=&quot;step-3-deploy&quot;&gt;Step 3: Deploy&lt;/h2&gt;
&lt;p&gt;Deploy the website to Azure Websites using your favourite method (my family likes to use Octopus Deploy 3 every day). Check in the Azure portal and you will hopefully have a Webjob listed in your Web App. If not, you can connect the Visual Studio Azure tooling to your Azure subscription and use the Service Explorer (App Service node) to see if the files have been deployed as expected. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>Event Sourcing with Couchdb</title>
      <link>http://withouttheloop.com/articles/2015-05-09-event-sourcing-with-couchdb/</link>
      <pubDate>Sat, 09 May 2015 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2015-05-09-event-sourcing-with-couchdb/</guid>
      <author></author>
      <description>&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;
&lt;p&gt;CouchDB, with its indexed views, has some promising properties for an “event sourcing”* system.&lt;/p&gt;
&lt;p&gt;Because views are a function of the documents in the database, and they are indexed, it seems like we can have the best of both worlds, where the authoritative data store is the historical events that have occurred, but at the same time we have an indexed projection of the events that is guaranteed to be up to date (prior to a read).&lt;/p&gt;
&lt;h2 id=&quot;disclaimer&quot;&gt;Disclaimer&lt;/h2&gt;
&lt;p&gt;I have never built an event sourced system. I expect I am doing everything wrong. I’m interested in hearing reasoned commentary. I am less interested in hearing dogma.&lt;/p&gt;
&lt;h2 id=&quot;read-side&quot;&gt;Read Side&lt;/h2&gt;
&lt;p&gt;The following is my current list of ‘person’ entities.&lt;/p&gt;
&lt;table id=&quot;documents&quot; class=&quot;listing&quot; cellspacing=&quot;0&quot;&gt;
        &lt;caption&gt;Documents&lt;/caption&gt;
        &lt;thead&gt;
          &lt;tr&gt;
            &lt;th class=&quot;key&quot;&gt;
              &lt;label class=&quot;&quot; id=&quot;grouplevel&quot;&gt;
                Grouping: &lt;select&gt;
                  &lt;option value=&quot;0&quot;&gt;none&lt;/option&gt;
                  &lt;option value=&quot;1&quot;&gt;level 1&lt;/option&gt;
                  &lt;option value=&quot;2&quot;&gt;level 2&lt;/option&gt;
                  &lt;option value=&quot;3&quot;&gt;level 3&lt;/option&gt;
                  &lt;option value=&quot;4&quot;&gt;level 4&lt;/option&gt;
                  &lt;option value=&quot;5&quot;&gt;level 5&lt;/option&gt;
                  &lt;option value=&quot;6&quot;&gt;level 6&lt;/option&gt;
                  &lt;option value=&quot;7&quot;&gt;level 7&lt;/option&gt;
                  &lt;option value=&quot;8&quot;&gt;level 8&lt;/option&gt;
                  &lt;option value=&quot;9&quot;&gt;level 9&lt;/option&gt;
                  &lt;option value=&quot;100&quot; selected=&quot;&quot;&gt;exact&lt;/option&gt;
                &lt;/select&gt;
              &lt;/label&gt;
              &lt;span&gt;Key&lt;/span&gt;
            &lt;/th&gt;
            &lt;th class=&quot;value&quot;&gt;
              &lt;label id=&quot;reduce&quot;&gt;&lt;input autocomplete=&quot;off&quot; checked=&quot;&quot; type=&quot;checkbox&quot;&gt;&amp;nbsp;Reduce&lt;/label&gt;
              Value
            &lt;/th&gt;
          &lt;/tr&gt;
        &lt;/thead&gt;
        &lt;tbody class=&quot;content&quot;&gt;&lt;tr&gt;&lt;td class=&quot;key&quot;&gt;&lt;strong&gt;[“abigailmclennan”]&lt;/strong&gt;&lt;/td&gt;&lt;td class=&quot;value&quot;&gt;&lt;div&gt;&lt;code class=&quot;object&quot;&gt;{&lt;code class=&quot;key&quot;&gt;_id&lt;/code&gt;: &lt;code class=&quot;string&quot;&gt;“abigailmclennan”&lt;/code&gt;, &lt;code class=&quot;key&quot;&gt;name&lt;/code&gt;: &lt;code class=&quot;string&quot;&gt;“Abigail”&lt;/code&gt;, &lt;code class=&quot;key&quot;&gt;age&lt;/code&gt;: &lt;code class=&quot;number&quot;&gt;1&lt;/code&gt;}&lt;/code&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;odd&quot;&gt;&lt;td class=&quot;key&quot;&gt;&lt;strong&gt;[“foobarlalala”]&lt;/strong&gt;&lt;/td&gt;&lt;td class=&quot;value&quot;&gt;&lt;div&gt;&lt;code class=&quot;object&quot;&gt;{&lt;code class=&quot;key&quot;&gt;_id&lt;/code&gt;: &lt;code class=&quot;string&quot;&gt;“foobarlalala”&lt;/code&gt;, &lt;code class=&quot;key&quot;&gt;name&lt;/code&gt;: &lt;code class=&quot;string&quot;&gt;“Noah”&lt;/code&gt;, &lt;code class=&quot;key&quot;&gt;age&lt;/code&gt;: &lt;code class=&quot;number&quot;&gt;2&lt;/code&gt;}&lt;/code&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;
        &lt;tbody class=&quot;footer&quot;&gt;
          &lt;tr class=&quot;odd&quot;&gt;
            &lt;td colspan=&quot;4&quot;&gt;
              &lt;div id=&quot;paging&quot;&gt;
                &lt;a class=&quot;prev&quot;&gt;← Previous Page&lt;/a&gt; |
                &lt;label&gt;Rows per page: &lt;select id=&quot;perpage&quot;&gt;
                  &lt;option selected=&quot;&quot;&gt;10&lt;/option&gt;
                  &lt;option&gt;25&lt;/option&gt;
                  &lt;option&gt;50&lt;/option&gt;
                  &lt;option&gt;100&lt;/option&gt;
                &lt;/select&gt;&lt;/label&gt; |
                &lt;a class=&quot;next&quot;&gt;Next Page →&lt;/a&gt;
              &lt;/div&gt;
              &lt;span&gt;Showing 1-2 of unknown rows&lt;/span&gt;
            &lt;/td&gt;
          &lt;/tr&gt;
        &lt;/tbody&gt;
      &lt;/table&gt;

&lt;h2 id=&quot;write-side&quot;&gt;Write Side&lt;/h2&gt;
&lt;p&gt;But they are not stored in my database, instead the database stores the &lt;em&gt;events&lt;/em&gt; that caused those entities to have the values they do.&lt;/p&gt;
&lt;p&gt;In this example I have two different kinds of events:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;BirthEvent - indicating that a person was born&lt;/li&gt;
&lt;li&gt;BirthdayEvent - indicating that a person had a birthday&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;From these events the ‘person’ entities are calculated. To make this work in couchdb I have used the following rules:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;each event has a ‘mapId’ property that is the identifier of the related entity&lt;/li&gt;
&lt;li&gt;each type of entity has a map/reduce view. The map function produces each event with its mapId as the key. The reduce function is then passed the set of events that determine the value of an entity. The reduce function processes the events and returns the current state of the entity.&lt;/li&gt;
&lt;li&gt;each event has a &lt;strong&gt;timestamp&lt;/strong&gt; property. To hydrate state from events we need to know the order in which the events occurred.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In my database I have two &lt;strong&gt;BirthEvents&lt;/strong&gt;, and three &lt;strong&gt;BirthdayEvents&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The process is something like this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;flow.png&quot; alt=&quot;flow&quot;/&gt;&lt;/p&gt;
&lt;h2 id=&quot;couchdb-view-code&quot;&gt;CouchDB View Code&lt;/h2&gt;
&lt;p&gt;The map function simply keys the entities by their mapId:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-{javascript}&quot;&gt;function(doc) {  
  if (doc.mapId) {
    emit([doc.mapId], doc);
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This means that the &lt;strong&gt;values&lt;/strong&gt; object within the reduce function is the set of events that produce a single person entity.&lt;/p&gt;
&lt;p&gt;The reduce function then orders the events, by &lt;strong&gt;timestamp&lt;/strong&gt;, and processes them to calculate the current state of the entity:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-{javascript}&quot;&gt;function(keys, values) {
  values.sort(function (f,s) {
    if (f.timestamp &amp;gt; s.timestamp) return 1;
    if (f.timestamp == s.timestamp) return 0;
    return -1;
  });
  var acc = values.reduce(function (p,c,i) {
    if (c.type==&amp;#39;BirthEvent&amp;#39;) {
      return {
        _id:c.mapId,
        name:c.name,
        age:0
      };
    }
    if (c.type == &amp;#39;BirthdayEvent&amp;#39;) {
      p.age +=1;
      return p;
    }
    return c;
  },{});
  return acc;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;result&quot;&gt;Result&lt;/h2&gt;
&lt;p&gt;There are some concerns remaining.&lt;/p&gt;
&lt;p&gt;Each event must somehow map to the entity it produces. A more complicated scheme could be used (to allow an event to affect the state of &amp;gt; 1 entity) but I’m still not sure if this is ideal.&lt;/p&gt;
&lt;p&gt;The reduce function may (or may not) have performance problems. I have not found a way to store the sorted events in the index, so they are re-sorted when the reduce function runs.&lt;/p&gt;
&lt;p&gt;The reduce function is a function from a set of events to the entity those events produce. This could become complicated.&lt;/p&gt;
&lt;p&gt;Entity state is a function of the events that produce the entity, meaning that all entity data must be derivable from the events. I’m not sure if this is good or bad.&lt;/p&gt;
&lt;h2 id=&quot;similar-systems&quot;&gt;Similar Systems&lt;/h2&gt;
&lt;p&gt;One could do the same thing with Sql Server materialized views (except the processing code would have to be written in T-SQL) or with a streaming system (Kafka/Samza/Storm/etc).&lt;/p&gt;
&lt;p&gt;&lt;span&gt;*&lt;/span&gt; not certain what this is.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>RedisMQ</title>
      <link>http://withouttheloop.com/articles/2015-04-29-redismq/</link>
      <pubDate>Wed, 29 Apr 2015 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2015-04-29-redismq/</guid>
      <author></author>
      <description>&lt;p&gt;Many people use Redis for a simple message broker. &lt;a href=&quot;https://gist.github.com/liammclennan/5adf41090507ad6b0b0c&quot;&gt;RedisMQ&lt;/a&gt; is a trivial layer on &lt;a href=&quot;http://redis.io/&quot;&gt;Redis&lt;/a&gt; and &lt;a href=&quot;https://github.com/StackExchange/StackExchange.Redis&quot;&gt;StackExchange.Redis&lt;/a&gt; that probably does not work. It provides two simple messaging patterns:&lt;/p&gt;
&lt;h2 id=&quot;publish-subscribe&quot;&gt;Publish / subscribe&lt;/h2&gt;
&lt;p&gt;A publisher publishes messages. 0, 1 or more consumers subscribe to the messages.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var redis = ConnectionMultiplexer.Connect(&amp;quot;192.168.85.128&amp;quot;);
redis.BroadcastSubscribe&amp;lt;string&amp;gt;(&amp;quot;this-is-the-channel&amp;quot;, message =&amp;gt;
    // do something with the message);
redis.BroadcastPublish(&amp;quot;this-is-the-channel&amp;quot;, &amp;quot;42&amp;quot;);
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;competing-consumer&quot;&gt;Competing consumer&lt;/h2&gt;
&lt;p&gt;A publisher publishes messages to a queue. Messages stay in the queue until someone reads them. Many subscribers may read from the same queue. Each message is processed by just one consumer.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var redis = ConnectionMultiplexer.Connect(&amp;quot;192.168.85.128&amp;quot;);
redis.CompetingConsumerSubscribe&amp;lt;int&amp;gt;(&amp;quot;numbers&amp;quot;, message =&amp;gt;
    // do something with the message);
redis.CompetingConsumerPublish(&amp;quot;numbers&amp;quot;, 1);
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;speed&quot;&gt;Speed&lt;/h2&gt;
&lt;p&gt;RedisMQ is not optimised for performance. It is optimized for being simple for me to write. However, the following gives a rough indication of performance.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Strategy&lt;/th&gt;
&lt;th&gt;# messages&lt;/th&gt;
&lt;th&gt;Time (s)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Broadcast to 2 consumers&lt;/td&gt;
&lt;td&gt;100,000&lt;/td&gt;
&lt;td&gt;21.3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Competing consumer with 1 subscriber&lt;/td&gt;
&lt;td&gt;100,000&lt;/td&gt;
&lt;td&gt;37.7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Competing consumer with 2 subscribers&lt;/td&gt;
&lt;td&gt;100,000&lt;/td&gt;
&lt;td&gt;23.7&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;dependencies&quot;&gt;Dependencies&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;PM&amp;gt; Install-Package StackExchange.Redis
PM&amp;gt; Install-Package Newtonsoft.Json
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>Mars Rover Problem</title>
      <link>http://withouttheloop.com/articles/2015-04-17-mars-rover/</link>
      <pubDate>Fri, 17 Apr 2015 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2015-04-17-mars-rover/</guid>
      <author></author>
      <description>&lt;p&gt;&lt;img src=&quot;curiosity.jpg&quot; style=&quot;width:710px;&quot; alt=&quot;curiosity rover&quot;/&gt;&lt;/p&gt;

&lt;p&gt;Mars Rovers is a simple programming problem with just enough complexity to be interesting and to provide sufficient challenge to experiment with some different strategies. The problem, as stolen from &lt;a href=&quot;https://code.google.com/p/marsrovertechchallenge/&quot;&gt;here&lt;/a&gt;, is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;A squad of robotic rovers are to be landed by NASA on a plateau on Mars.

This plateau, which is curiously rectangular, must be navigated by the rovers so that their on board cameras can get a complete view of the surrounding terrain to send back to Earth.

A rover&amp;#39;s position is represented by a combination of an x and y co-ordinates and a letter representing one of the four cardinal compass points. The plateau is divided up into a grid to simplify navigation. An example position might be 0, 0, N, which means the rover is in the bottom left corner and facing North.

In order to control a rover, NASA sends a simple string of letters. The possible letters are &amp;#39;L&amp;#39;, &amp;#39;R&amp;#39; and &amp;#39;M&amp;#39;. &amp;#39;L&amp;#39; and &amp;#39;R&amp;#39; makes the rover spin 90 degrees left or right respectively, without moving from its current spot.

&amp;#39;M&amp;#39; means move forward one grid point, and maintain the same heading.

Assume that the square directly North from (x, y) is (x, y+1).

Input:

The first line of input is the upper-right coordinates of the plateau, the lower-left coordinates are assumed to be 0,0.

The rest of the input is information pertaining to the rovers that have been deployed. Each rover has two lines of input. The first line gives the rover&amp;#39;s position, and the second line is a series of instructions telling the rover how to explore the plateau.

The position is made up of two integers and a letter separated by spaces, corresponding to the x and y co-ordinates and the rover&amp;#39;s orientation.

Each rover will be finished sequentially, which means that the second rover won&amp;#39;t start to move until the first one has finished moving.

Output:

The output for each rover should be its final co-ordinates and heading.

Test Input:

5 5
1 2 N
LMLMLMLMM
3 3 E
MMRMMRMRRM

Expected Output:

1 3 N
5 1 E
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The problem requires two things: a parser from the input to some useful data structure, and something to process that data structure. Immediately we are confronted by a fundamental difference between OO (at least as I see it done) and functional style.&lt;/p&gt;
&lt;h2 id=&quot;the-oo-programmer&quot;&gt;The OO Programmer&lt;/h2&gt;
&lt;p&gt;The OO programmer sees a &lt;code&gt;MarsRoverController&lt;/code&gt; or similar abstraction for coordinating this problem. The &lt;code&gt;MarsRover&lt;/code&gt; becomes a class having a &lt;code&gt;position&lt;/code&gt; and a &lt;code&gt;direction&lt;/code&gt;. The coordinating object depends on both the parser and the &lt;code&gt;MarsRover&lt;/code&gt;. It firstly asks the parser to parse the input, then asks the &lt;code&gt;MarsRover&lt;/code&gt; to process the movements. An even uglier implementation would have the &lt;code&gt;MarsRover&lt;/code&gt; doing the coordination responsibility.&lt;/p&gt;
&lt;h2 id=&quot;the-functional-programmer&quot;&gt;The Functional Programmer&lt;/h2&gt;
&lt;p&gt;To the functional programmer these are all just functions. A function to do the parsing and a function to process the data structure. In my implementation the functions are &lt;code&gt;parseInitialization&lt;/code&gt; and &lt;code&gt;play&lt;/code&gt;. My REPL usage looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; parseInitialization testInput |&amp;gt; play;;
val it : Rover list = [{x = 1;
                        y = 3;
                        direction = N;}; {x = 5;
                                          y = 1;
                                          direction = E;}]
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;implementing-the-action-state-change&quot;&gt;Implementing the Action State Change&lt;/h2&gt;
&lt;p&gt;Somewhere we have to process actions. The possible actions are turn left, turn right, or move forward. Processing one of this actions changes the state of the rover.&lt;/p&gt;
&lt;p&gt;Let us first focus on the turning actions. There are different ways to implement this. My first attempt was a simple enumeration of the possibilities:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let turn direction action =
    if action = M then failwith &amp;quot;M is not a turn action&amp;quot;
    match (direction,action) with
        | (N,L) -&amp;gt; W
        | (N,R) -&amp;gt; E
        | (E,L) -&amp;gt; N
        | (E,R) -&amp;gt; S
        | (S,L) -&amp;gt; E
        | (S,R) -&amp;gt; W
        | (W,L) -&amp;gt; S
        | (W,R) -&amp;gt; N
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I like the simplicity of this approach. The required guard to check for a move action was a strong indication that I had modelled the types incorrectly. If it feels wrong, it probably is.&lt;/p&gt;
&lt;p&gt;As an experiment I then tried an implementation that understood the directions as angle measurements. This has the advantage that it could be extended to more realistic systems, but it is more complicated:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let turnAlt direction action =
    let directionAngles = [(N,0);(E,90);(S,180);(W,270)]
    let angle = (List.find (fun (d,a) -&amp;gt; d = direction) directionAngles) |&amp;gt; snd
    let angleToDirection angle =
        List.find (fun (d,a) -&amp;gt; a = angle) directionAngles |&amp;gt; fst
    let turnedAngle =
        match action with
        | L -&amp;gt; angle - 90
        | R -&amp;gt; angle + 90
        | M -&amp;gt; failwith &amp;quot;M is not a turn action&amp;quot;
    angleToDirection   (if turnedAngle &amp;lt; 0 then
                            turnedAngle + 360
                        elif turnedAngle = 360 then
                            0
                        else
                            turnedAngle)
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;parsing&quot;&gt;Parsing&lt;/h2&gt;
&lt;p&gt;To keep things simple I started with simple string splitting to parse the input. For the record, it looks like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let parseDirection = function
    | &amp;quot;N&amp;quot; -&amp;gt; N
    | &amp;quot;E&amp;quot; -&amp;gt; E
    | &amp;quot;S&amp;quot; -&amp;gt; S
    | &amp;quot;W&amp;quot; -&amp;gt; W
    | d -&amp;gt; failwith (&amp;quot;Unknown direction &amp;quot; + d)

let parseRover (line:string) =
    let lineParts = line.Split(&amp;#39; &amp;#39;)
    {x = lineParts.[0] |&amp;gt; int; y = lineParts.[1] |&amp;gt; int; direction = parseDirection lineParts.[2]}

let parseActions (line:string) =
    [
        for c in line do
            yield match c with
                    | &amp;#39;L&amp;#39; -&amp;gt; L
                    | &amp;#39;R&amp;#39; -&amp;gt; R
                    | &amp;#39;M&amp;#39; -&amp;gt; M
                    | other -&amp;gt; failwith (&amp;quot;Unknown action &amp;quot; + (string other))
    ]

let parseInstructions lines : Instruction list =
    [
        for i in [0..(Array.length lines)/2 - 1] do
            let roverLine = lines.[2*i]
            let actionLine = lines.[2*i+1]
            yield {rover= parseRover roverLine; actions = parseActions actionLine}
    ]

let parseInitialization (input:string) =
    let lines = input.Split(&amp;#39;\n&amp;#39;)
    let topRightLine = lines.[0]
    {
        upperRightX = lines.[0].Split(&amp;#39; &amp;#39;).[0] |&amp;gt; int; upperRightY = lines.[0].Split(&amp;#39; &amp;#39;).[1] |&amp;gt; int;
        instructions = parseInstructions lines.[1..]
    }
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;parsing-with-fparsec&quot;&gt;Parsing with Fparsec&lt;/h2&gt;
&lt;p&gt;Then, for fun, I deleted my implementation and replaced it with &lt;a href=&quot;http://www.quanttec.com/fparsec/&quot;&gt;fparsec&lt;/a&gt; parser combinators.&lt;/p&gt;
&lt;p&gt;Firstly, we need to parse the first line, giving the top right coordinates, to a point:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type Point = {x:int; y:int}
let ptopright = sepBy pint32 (pchar &amp;#39; &amp;#39;) |&amp;gt;&amp;gt; (fun [x;y] -&amp;gt; {x=x;y=y})
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;usage:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; run ptopright &amp;quot;5 6&amp;quot;
val it : ParserResult&amp;lt;Point,unit&amp;gt; = Success: {x = 5;
 y = 6;}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Next, we need to parse a direction. This is an example of parsing alternatives:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type Direction = N | E | S | W
let pdirection = (charReturn &amp;#39;N&amp;#39; N) &amp;lt;|&amp;gt; (charReturn &amp;#39;E&amp;#39; E) &amp;lt;|&amp;gt; (charReturn &amp;#39;S&amp;#39; S) &amp;lt;|&amp;gt; (charReturn &amp;#39;W&amp;#39; W)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now we can parse the second line of input, the rover’s state. Here we run 5 parsers (x, space, y, space, direction) and pipe the results into a function that produces the type we want (&lt;code&gt;Rover&lt;/code&gt;):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type Rover = {location:Point; direction:Direction}
// 1 2 N
let proverstate =
    pipe3
        (pint32 .&amp;gt;&amp;gt; (pchar &amp;#39; &amp;#39;))
        (pint32 .&amp;gt;&amp;gt; (pchar &amp;#39; &amp;#39;))
        pdirection
        (fun x y direction -&amp;gt; {location = {x=x;y=y}; direction = direction})
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Next - a way to parse actions - turn left, turn right or move forward:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type Turn = L | R
type Action =
    | Turn of  Turn
    | M
let pturn = (charReturn &amp;#39;L&amp;#39; (Turn L)) &amp;lt;|&amp;gt; (charReturn &amp;#39;R&amp;#39; (Turn R))
let paction = pturn &amp;lt;|&amp;gt; (charReturn &amp;#39;M&amp;#39; M)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Actions never occur by themself. We want to parse a sequence of them, so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// LMMLMRM
let pactions = many (pturn &amp;lt;|&amp;gt; (charReturn &amp;#39;M&amp;#39; M))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We want to parse pairs of rover + actions so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type Instruction = {rover:Rover; actions:Action list}

// 1 2 N
// LMLMLMLMM
let pinstruction =
  pipe2
    (proverstate .&amp;gt;&amp;gt; newline)
    pactions
    (fun state actions -&amp;gt; {rover=state; actions=actions})
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Finally, we connect all of our parsers together:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let pinit =
    pipe2
        (ptopright .&amp;gt;&amp;gt; newline)
        (many pinstruction)
        (fun topright instructions -&amp;gt;
            {upperRight = topright; instructions = instructions})
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;the-completed-mars-rover-solution&quot;&gt;The Completed Mars Rover Solution&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;#r @&amp;quot;FParsec.1.0.1\lib\net40-client\FParsecCS.dll&amp;quot;
#r @&amp;quot;FParsec.1.0.1\lib\net40-client\FParsec.dll&amp;quot;

open FParsec

type Direction = N | E | S | W
type Point = {x:int; y:int}
type Rover = {location:Point; direction:Direction}
type Turn = L | R
type Action =
    | Turn of  Turn
    | M
type Instruction = {rover:Rover; actions:Action list}
type Initialization = { upperRight: Point; instructions: Instruction list}

let pdirection = (charReturn &amp;#39;N&amp;#39; N) &amp;lt;|&amp;gt; (charReturn &amp;#39;E&amp;#39; E) &amp;lt;|&amp;gt; (charReturn &amp;#39;S&amp;#39; S) &amp;lt;|&amp;gt; (charReturn &amp;#39;W&amp;#39; W)
let ptopright = sepBy pint32 (pchar &amp;#39; &amp;#39;) |&amp;gt;&amp;gt; (fun [x;y] -&amp;gt; {x=x;y=y})

// 1 2 N
let proverstate =
    pipe3
        (pint32 .&amp;gt;&amp;gt; (pchar &amp;#39; &amp;#39;))
        (pint32 .&amp;gt;&amp;gt; (pchar &amp;#39; &amp;#39;))
        pdirection
        (fun x y direction -&amp;gt; {location = {x=x;y=y}; direction = direction})

let pturn = (charReturn &amp;#39;L&amp;#39; (Turn L)) &amp;lt;|&amp;gt; (charReturn &amp;#39;R&amp;#39; (Turn R))
let pactions = (many (pturn &amp;lt;|&amp;gt; (charReturn &amp;#39;M&amp;#39; M))) .&amp;gt;&amp;gt; (skipChar &amp;#39;\n&amp;#39; &amp;lt;|&amp;gt; preturn ())

// 1 2 N
// LMLMLMLMM
let pinstruction =
    pipe2
        (proverstate .&amp;gt;&amp;gt; newline)
        pactions
        (fun state actions -&amp;gt; {rover=state; actions=actions})

let pinit =
    pipe2
        (ptopright .&amp;gt;&amp;gt; newline)
        (many pinstruction)
        (fun topright instructions -&amp;gt;
            {upperRight = topright; instructions = instructions})

let testInput = &amp;quot;5 5
1 2 N
LMLMLMLMM
3 3 E
MMRMMRMRRM&amp;quot;

let extectedOutput = &amp;quot;1 3 N
5 1 E&amp;quot;

let play (init:Initialization) =
    let playInstruction (instruction:Instruction) =
        let turn direction action =
            match (direction,action) with
                | (N,L) -&amp;gt; W
                | (N,R) -&amp;gt; E
                | (E,L) -&amp;gt; N
                | (E,R) -&amp;gt; S
                | (S,L) -&amp;gt; E
                | (S,R) -&amp;gt; W
                | (W,L) -&amp;gt; S
                | (W,R) -&amp;gt; N

        let applyAction (rover:Rover) = function
                | Turn t -&amp;gt; {rover with direction = turn rover.direction t}
                | M -&amp;gt;
                    let moved =
                        { rover with location = match rover.direction with
                                                | N -&amp;gt; {rover.location with y = rover.location.y+1}
                                                | E -&amp;gt; {rover.location with x = rover.location.x+1}
                                                | S -&amp;gt; {rover.location with y = rover.location.y-1}
                                                | W -&amp;gt; {rover.location with x = rover.location.x-1}
                        }
                    if moved.location.x &amp;lt; 0
                        || moved.location.y &amp;lt; 0
                        || moved.location.x &amp;gt; init.upperRight.x
                        || moved.location.y &amp;gt; init.upperRight.y then
                        rover
                    else
                        moved
        List.fold applyAction instruction.rover instruction.actions
    List.map playInstruction init.instructions

match run pinit testInput with
    | Success(result, _, _)   -&amp;gt; play result
    | Failure(errorMsg, _, _) -&amp;gt; printfn &amp;quot;Failed to parse: %s&amp;quot; errorMsg; []
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>PostgresDoc Support For Sql Server</title>
      <link>http://withouttheloop.com/articles/2015-02-13-postgresdoc-sql-server/</link>
      <pubDate>Fri, 13 Feb 2015 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2015-02-13-postgresdoc-sql-server/</guid>
      <author></author>
      <description>&lt;blockquote&gt;
&lt;p&gt;Using sql server as a document database, with transactions, joins, unit of work and other good stuff&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/liammclennan/PostgresDoc&quot;&gt;PostgresDoc&lt;/a&gt; is now the most ironically named ORM! Also, it doesn’t support objects, relations or mapping, but it does now support Sql Server - at least the recent versions.&lt;/p&gt;
&lt;p&gt;Historically, PostgresDoc has been a data access library providing serialization/deserialization, transactions, and a unit of work on top of the Postgresql json data type and associated indexes. &lt;a href=&quot;https://github.com/liammclennan/PostgresDoc/wiki/SQL-Server-Support&quot;&gt;Recently I got around to implementing the same thing on top of Sql Server’s XML data type and its indexes&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;here-is-the-doco&quot;&gt;Here is the Doco&lt;/h2&gt;
&lt;p&gt;PostgresDoc now supports SQL Server. SQL Server does not have the required JSON support, so the SQL Server version serializes to xml instead. The serializer supports .net classes, records and discriminated unions.&lt;/p&gt;
&lt;p&gt;Create your store like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let storeSql = SqlStore &amp;quot;your connection string&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and create tables like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CREATE TABLE [dbo].[card](
  [Id] [uniqueidentifier] NOT NULL,
  [Data] [xml] NOT NULL,
 CONSTRAINT [PK_card] PRIMARY KEY CLUSTERED
(
  [Id] ASC
)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Inserting, updating and deleting work the same as for Postresql. Querying requires the use of Sql Server’s XML querying capabilities.&lt;/p&gt;
&lt;h2 id=&quot;querying&quot;&gt;Querying&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;[
        &amp;quot;sourceUrl&amp;quot;, box url
        &amp;quot;userId&amp;quot;, box userId
]
|&amp;gt; query&amp;lt;Deck&amp;gt; store &amp;quot;select [Data] from [deck]
where Data.value(&amp;#39;(/Deck/userId)[1]&amp;#39;, &amp;#39;uniqueidentifier&amp;#39;) = @userId
and Data.value(&amp;#39;(/Deck/sourceUrl)[1]&amp;#39;, &amp;#39;nvarchar(512)&amp;#39;) = @sourceUrl&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;There are &lt;a href=&quot;http://www.brokenwire.net/bw/Programming/125/querying-xml-fields-using-t-sql&quot;&gt;many more options available for querying sql server xml&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;indexing&quot;&gt;Indexing&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://www.simple-talk.com/sql/database-administration/getting-started-with-xml-indexes/&quot;&gt;Sql server xml indexes traditionally index everything&lt;/a&gt;, which is convenient, bulky and slow.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.simple-talk.com/sql/learn-sql-server/precision-indexing--basics-of-selective-xml-indexes-in-sql-server-2012/&quot;&gt;Since 2012 Sql Server also has selective indexing&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Fermat</title>
      <link>http://withouttheloop.com/articles/2015-01-20-fermat/</link>
      <pubDate>Tue, 20 Jan 2015 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2015-01-20-fermat/</guid>
      <author></author>
      <description>&lt;p&gt;&lt;a href=&quot;https://github.com/liammclennan/fermat&quot;&gt;https://github.com/liammclennan/fermat&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Fermat is a simple library for organising web states and generating urls. Tell it the possible states of your web ui, and how those states map to urls and it will give you a url generation function. &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var fermat = require(&amp;#39;../lib/fermat&amp;#39;)({
    &amp;#39;Inbox&amp;#39;: &amp;#39;/inbox&amp;#39;,
    &amp;#39;Tag&amp;#39;: &amp;#39;/tag/:tag&amp;#39;,
    &amp;#39;Calendar&amp;#39;: &amp;#39;/calendar/:month/:day&amp;#39;
});

fermat(&amp;#39;Calendar&amp;#39;, {
  month: &amp;#39;march&amp;#39;,
  day: &amp;#39;14&amp;#39;
});

// /calendar/march/14
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It works with require.js, node, browserify and &lt;a href=&quot;https://github.com/liammclennan/smodules&quot;&gt;smodules&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;run-tests&quot;&gt;Run Tests&lt;/h2&gt;
&lt;p&gt;First you need mocha.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm install -g mocha
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ npm test
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and you should see something happy like&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; fermat@1.0.0 test c:\work\fermat
&amp;gt; mocha

Fermat
    some states
      V should generate url without route components
      V should generate a url with a route component
      V should generate a url with multiple route components


3 passing (17ms)
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>F# Project Loading</title>
      <link>http://withouttheloop.com/articles/2015-01-16-fsharp-project-loading/</link>
      <pubDate>Fri, 16 Jan 2015 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2015-01-16-fsharp-project-loading/</guid>
      <author></author>
      <description>&lt;p&gt;Everytime I create a new F# project (typically using the MVC 5 F# Templates) things go great until I close Visual Studio. When I try to reopen the solution I inevitably get:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The project ?? could not be opened because opening it would cause a folder to be rendered multiple times in the solution explorer. One such problematic item is ??&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It’s natural to think that the indicated file is causing the problem, but if you remove it then the problem just shifts to the next file. &lt;/p&gt;
&lt;p&gt;The error occurs when files within the project are not grouped by their directory. A project containing:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;Compile Include=&amp;quot;Home\HomeController.fs&amp;quot; /&amp;gt;    
&amp;lt;Content Include=&amp;quot;Scripts\react.js&amp;quot; /&amp;gt;
&amp;lt;None Include=&amp;quot;Home\Index.cshtml&amp;quot; /&amp;gt;
&amp;lt;Content Include=&amp;quot;Scripts\react.d.ts&amp;quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;cannot be reopened. To fix, group the files by their directory.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;Compile Include=&amp;quot;Home\HomeController.fs&amp;quot; /&amp;gt;    
&amp;lt;None Include=&amp;quot;Home\Index.cshtml&amp;quot; /&amp;gt;
&amp;lt;Content Include=&amp;quot;Scripts\react.js&amp;quot; /&amp;gt;
&amp;lt;Content Include=&amp;quot;Scripts\react.d.ts&amp;quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That’s it. Hope this helps someone. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>Spaced Repetition Wiki</title>
      <link>http://withouttheloop.com/articles/2015-01-10-spaced-repetition-wiki/</link>
      <pubDate>Sat, 10 Jan 2015 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2015-01-10-spaced-repetition-wiki/</guid>
      <author></author>
      <description>&lt;h2 id=&quot;on-the-wiki&quot;&gt;On the Wiki&lt;/h2&gt;
&lt;p&gt;A wiki is a collection of user-editable web pages. The wiki was ‘invented’ by Ward Cunningham, so it must be good. I like to use wikis to document things, or record mind maps for areas that I am learning. I have a wiki for vim, a wiki for haskell, a wiki for linux and so on. &lt;/p&gt;
&lt;p&gt;Both github and bitbucket offer free wikis, and bitbucket wikis can be private. &lt;/p&gt;
&lt;h2 id=&quot;on-spaced-repetition&quot;&gt;On Spaced Repetition&lt;/h2&gt;
&lt;p&gt;As we are repeatedly exposed to a datum the time before we forget it gets longer. The most efficient way then to commit something to memory is to be reminded of it immediately prior to the moment you would otherwise have forgotten it. You know this intuitively if you have ever studied for an exam and then realised three weeks later that you no longer retain any of the information. &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Spaced repetition is a learning technique that incorporates increasing intervals of time between subsequent review of previously learned material in order to exploit the psychological spacing effect – Wikipedia&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Most of the things I learn I am happy to forget. It sounds strange but I know my memory is limited and &lt;a href=&quot;http://www.paulgraham.com/know.html&quot;&gt;I believe that we tacitly retain helpful conditioning even when specific facts are forgotten&lt;/a&gt;. To be nerdy about it you could say that short-term memory trains our machine learning system. The memories fade but the prediction function remains. I like spaced repetition for those important data that I want to retain medium to long term. &lt;/p&gt;
&lt;h2 id=&quot;combining-the-wiki-and-spaced-repetition&quot;&gt;Combining the Wiki and Spaced Repetition&lt;/h2&gt;
&lt;p&gt;My struggle with spaced repetition has always been around the maintenance of the question decks. This problem has not existed for me with wikis, so I decided it might work well to embed spaced repetition questions in my wikis. The microformat I chose for this job is:&lt;/p&gt;
&lt;p&gt;Q&amp;gt;&amp;gt;&amp;gt; This is the question? &amp;lt;&amp;lt;&amp;lt;&lt;/p&gt;
&lt;p&gt;A&amp;gt;&amp;gt;&amp;gt; This is the answer. &amp;lt;&amp;lt;&amp;lt;&lt;/p&gt;
&lt;p&gt;Any content at all (including HTML) is allowed between the delimiting tokens. Both this blog article and the &lt;a href=&quot;https://raw.githubusercontent.com/liammclennan/SpacedRepetition/master/README.md&quot;&gt;readme file for the project I created&lt;/a&gt; are valid examples of the format. The &lt;a href=&quot;https://github.com/liammclennan/SpacedRepetition&quot;&gt;aforementioned project&lt;/a&gt; is a terminal program, written in F#, that clones public git repositories, selects the set of markdown files, extracts the spaced repetition content that conforms to the specified microformat, and writes the data to a csv file that I can then import into &lt;a href=&quot;https://raw.githubusercontent.com/liammclennan/SpacedRepetition/master/README.md&quot;&gt;anki&lt;/a&gt; (my spaced repetition client of choice). &lt;/p&gt;
&lt;p&gt;Much of the program came together very nicely and provided some great demonstration of the joy of F#. The part I am least happy with, and the part I think most likely to contain bugs, is the &lt;a href=&quot;https://github.com/liammclennan/SpacedRepetition/blob/master/SpacedRepetition/Parser.fs&quot;&gt;parser&lt;/a&gt;. I’m still learning parsers and parser combinators and this is the first one I’ve done that required backtracking. Regardless, it seems to work. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;glove.jpg&quot; alt=&quot;hand in glove&quot;/&gt;&lt;/p&gt;
&lt;h2 id=&quot;what-s-next-&quot;&gt;What’s Next?&lt;/h2&gt;
&lt;p&gt;I plan to start some postgrad coursework soon and give this system a real workout. I may spin up a web front-end that does spaced repetition from public git repositories. The problems with existing spaced repetition clients are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;proprietary formats&lt;/li&gt;
&lt;li&gt;closed systems&lt;/li&gt;
&lt;li&gt;non-web based&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;all of which I can easily fix with a simple web app. Currently the system is restricted to public git repositories as the data store but I could easily extend it to private git repositories or other data sources. I specifically chose git because it is an open standard. For this reason I abandoned the github and bitbucket APIs. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>Object-Orientation is Just Grouping Partially Applied Functions</title>
      <link>http://withouttheloop.com/articles/2014-11-11-oo-partial-application/</link>
      <pubDate>Tue, 11 Nov 2014 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2014-11-11-oo-partial-application/</guid>
      <author></author>
      <description>&lt;p&gt;I’ve been wondering if perhaps there is not much to this object orientation business. Could it be that an ‘object’ is nothing more than a collection of partially applied functions?&lt;/p&gt;
&lt;h2 id=&quot;an-example-of-object-orientation&quot;&gt;An Example of Object-Orientation&lt;/h2&gt;
&lt;p&gt;Here is a simple object oriented class, representing a person with a couple of operations.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;void Main()
{
    var vlad = new Person(&amp;quot;Vladimir&amp;quot;, 62);
    var tony = new Person(&amp;quot;Tony&amp;quot;, 57);

    tony.Greet().Dump();
    vlad.OlderThan(tony).Dump();
}

public class Person {
    public string _name;
    public int _age;

    public Person(string name, int age) {
        _name = name;
        _age = age;
    }

    public string Greet() {
        return String.Format(&amp;quot;Hello, my name is {0}&amp;quot;, _name);
    }

    public bool OlderThan(Person other) {
        return _age &amp;gt; other._age;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The data is a person’s name and age. The operations are Greeting and comparing the ages of two instances.&lt;/p&gt;
&lt;p&gt;The output of the above Linqpad script is:&lt;/p&gt;
&lt;blockquote&gt;Hello, my name is Tony &lt;/blockquote&gt;
&lt;blockquote&gt;True&lt;/blockquote&gt;

&lt;h2 id=&quot;an-example-with-functions&quot;&gt;An Example With Functions&lt;/h2&gt;
&lt;p&gt;An equivalent functional implementation is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type Person = {name:string;age:int}

let greet p = p.name |&amp;gt; sprintf &amp;quot;Hello my name is %s&amp;quot;
let olderThan p1 p2 = p1.age &amp;gt; p2.age

let vlad = {name= &amp;quot;Vladimir&amp;quot;; age= 62}
let tony = {name= &amp;quot;Tony&amp;quot;; age= 59}

greet vlad
olderThan vlad tony
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;output&lt;/p&gt;
&lt;blockquote&gt;
val it : string = “Hello my name is Vladimir”
val it : bool = true
&lt;/blockquote&gt;

&lt;h2 id=&quot;objects-are-just-partially-applied-functions&quot;&gt;Objects Are Just Partially Applied Functions&lt;/h2&gt;
&lt;p&gt;If I didn’t care about sensible solutions I might implement a functional program that is more directly equivalent to the object-oriented code.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type PersonOO = { greet: string; olderThan: string -&amp;gt; int -&amp;gt; bool}

let greet&amp;#39; name age = name |&amp;gt; sprintf &amp;quot;Hello my name is %s&amp;quot; 
let olderThan&amp;#39; name age name&amp;#39; age&amp;#39; = age &amp;gt; age&amp;#39;

let constructPerson name age = { greet = greet&amp;#39; name age; olderThan = olderThan&amp;#39; name age}

let vlad&amp;#39; = constructPerson &amp;quot;Vladimir&amp;quot; 62
let tony&amp;#39; = constructPerson &amp;quot;Tony&amp;quot; 59

vlad&amp;#39; 
vlad&amp;#39;.olderThan &amp;quot;Tony&amp;quot; 59
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;output&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;val tony&amp;#39; : PersonOO = {greet = &amp;quot;Hello my name is Tony&amp;quot;; olderThan = &amp;lt;fun:tony&amp;#39;@9&amp;gt;;}
val it : bool = true
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;When you look at it this way it is easier to see the problem. In the signature of &lt;code&gt;greet&amp;#39;&lt;/code&gt; the age argument is redundant. In the signature of &lt;code&gt;olderThan&amp;#39;&lt;/code&gt; only the age arguments are used.  &lt;/p&gt;
&lt;h2 id=&quot;some-problems-with-objects&quot;&gt;Some Problems With Objects&lt;/h2&gt;
&lt;p&gt;Both of the previous examples do the same thing. The trouble with the object version is that both methods are coupled to the name and age fields, even though they don’t need to be. The other side of the same coin is a cohesion problem. &lt;/p&gt;
&lt;p&gt;So both implementations are pretty much equivalent, but to me the functions are simpler and more obvious.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Parsing Nokia Composer Ringtones With FParsec</title>
      <link>http://withouttheloop.com/articles/2014-10-30-building-a-parser-with-fparsec/</link>
      <pubDate>Thu, 30 Oct 2014 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2014-10-30-building-a-parser-with-fparsec/</guid>
      <author></author>
      <description>&lt;p&gt;&lt;img src=&quot;3310.jpg&quot; alt=&quot;Nokia 3310&quot;  style=&quot;width: 200px&quot;/&gt; &lt;/p&gt;
&lt;p&gt;The classic Nokia 3310, and similar Nokia phones featured a capability to define custom ringtones using a tool called ‘Composer’.&lt;/p&gt;
&lt;p&gt;Parser uses a text based format to define the sequence of tones that makes up the ringtone. A tone is typically specified in the form:&lt;/p&gt;
&lt;blockquote&gt;8e2&lt;/blockquote&gt;

&lt;p&gt;Where the &lt;code&gt;8&lt;/code&gt; indicates that the tone should last for eighth of a bar (half of a beat), the &lt;code&gt;e&lt;/code&gt; is the musical note describing the pitch of the tone and the &lt;code&gt;2&lt;/code&gt; indicates the octave that note comes from (valid options are 1, 2 and 3). &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;composer.gif&quot; alt=&quot;Composer&quot; style=&quot;width:300px;&quot;  /&gt;&lt;/p&gt;
&lt;p&gt;I want to be able to read the string that defines a composer tune and interpret it in a precise way that can be used for computations (like playing the tune). The full syntax, as a regular expression, is something like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(\d+\.?#?[abcdefg][123])|(\d+\.?\-) 
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A tune is specified by a sequence of tokens, separated by spaces. Each token is either a tone or a rest. A rest is specified by a duration and an optional extension followed by a hyphen (e.g. &lt;code&gt;4.-&lt;/code&gt;). A tone is specified by a duration and an optional extension followed by a note (which may be preceded by a # to indicate sharp), followed by an octave (e.g. &lt;code&gt;16.#f3&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;The Nokia Composer syntax is simple enough that I could parse it with string functions or regular expressions, but I thought it might be fun to do it properly with a &lt;a href=&quot;http://en.wikipedia.org/wiki/Parser_combinator&quot;&gt;parser combinator&lt;/a&gt; library. A parser is a function that accepts a string and returns some structure. A parser combinator is a higher-order function that combines several parsers into a single parser. F# has an excellent parser combinator library called &lt;a href=&quot;http://www.quanttec.com/fparsec/&quot;&gt;FParsec&lt;/a&gt;. In FParsec a parser that reads a float looks like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pfloat &amp;quot;3.14&amp;quot;
// =&amp;gt; Success(3.14,...)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A combinator that parses two floats separated by a space&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;quot;3.14 2.71828&amp;quot; |&amp;gt; pfloat .&amp;gt;&amp;gt; pstring &amp;quot; &amp;quot; &amp;gt;&amp;gt;. pfloat 
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The strategy with parser combinators is to build parsers for the smallest units of syntax, then combine them into larger and larger pieces until you have a parser for the entire thing. &lt;/p&gt;
&lt;p&gt;If you don’t have the good fortune to be using F# don’t worry, there is a &lt;a href=&quot;https://github.com/sprache/Sprache&quot;&gt;parser combinator library for C#&lt;/a&gt; too. &lt;/p&gt;
&lt;h2 id=&quot;parsing-the-nokia-composer-syntax&quot;&gt;Parsing the Nokia Composer Syntax&lt;/h2&gt;
&lt;h3 id=&quot;parsing-the-duration&quot;&gt;Parsing the Duration&lt;/h3&gt;
&lt;p&gt;Before we can parse we need types to parse too. The types that will represent the duration of the tone or rest are:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type NoteLength = Half | Quarter | Eighth | Sixteenth | Thirtyseconth 
type Length = { duration: NoteLength; extended: bool }
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A length type has a duration and an extended bool. Durations followed by a &lt;code&gt;.&lt;/code&gt; are extended by half. The parser for the duration part is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let pnotelength = 
    (stringReturn &amp;quot;2&amp;quot; Half) &amp;lt;|&amp;gt; 
    (stringReturn &amp;quot;4&amp;quot; Quarter) &amp;lt;|&amp;gt; 
    (stringReturn &amp;quot;8&amp;quot; Eighth) &amp;lt;|&amp;gt; 
    (stringReturn &amp;quot;16&amp;quot; Sixteenth) &amp;lt;|&amp;gt; 
    (stringReturn &amp;quot;32&amp;quot; Thirtyseconth)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This simply codifies that the duration can be 2,4,8,16 or 32. The extended parser is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let extendedParser = (stringReturn &amp;quot;.&amp;quot; true) &amp;lt;|&amp;gt; (stringReturn &amp;quot;&amp;quot; false)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;These two parsers are combined into a single duration parser that produces a &lt;code&gt;Length&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let plength = pipe2 
                pnotelength            
                extendedParser 
                (fun t e -&amp;gt; {duration = t; extended = e})
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;parsing-the-pitch&quot;&gt;Parsing the Pitch&lt;/h3&gt;
&lt;p&gt;The syntax that describes the pitch is&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(#?[acdfg])|([be])
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That is a,c,d,f and g may be preceded by a &lt;code&gt;#&lt;/code&gt; to indicate a sharp (a semitone higher) while b and e may not. &lt;/p&gt;
&lt;p&gt;The parser for the optional &lt;code&gt;#&lt;/code&gt; symbol is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let psharp = (stringReturn &amp;quot;#&amp;quot; true) &amp;lt;|&amp;gt; (stringReturn &amp;quot;&amp;quot; false)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;i.e. parse a &lt;code&gt;#&lt;/code&gt; as &lt;code&gt;true&lt;/code&gt; or its absense as &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;&amp;lt;|&amp;gt;&lt;/code&gt; combinator combines two combinators by giving the result of the first one, unless it fails having consumed no input, in which case it gives the result of the second. The restriction that the second parser is only tried if the first does not consume any input is very important and described in detail in &lt;a href=&quot;http://www.quanttec.com/fparsec/users-guide/parsing-alternatives.html&quot;&gt;the FParsec documentation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Next we have a parser for notes that may be sharps. The target type for this parser is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type Note = A | ASharp | B | C | CSharp | D | DSharp | E | F | FSharp | G | GSharp
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and the parser:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let psharpnote = pipe2 
                    psharp 
                    (anyOf &amp;quot;acdfg&amp;quot;) 
                    (fun isSharp note -&amp;gt; match (isSharp, note) with
                        | (false, &amp;#39;a&amp;#39;) -&amp;gt; A
                        | (true, &amp;#39;a&amp;#39;) -&amp;gt; ASharp                    
                        | (false, &amp;#39;c&amp;#39;) -&amp;gt; C
                        | (true, &amp;#39;c&amp;#39;) -&amp;gt; CSharp
                        | (false, &amp;#39;d&amp;#39;) -&amp;gt; D
                        | (true, &amp;#39;d&amp;#39;) -&amp;gt; DSharp
                        | (false, &amp;#39;f&amp;#39;) -&amp;gt; F
                        | (true, &amp;#39;f&amp;#39;) -&amp;gt; FSharp
                        | (false, &amp;#39;g&amp;#39;) -&amp;gt; G
                        | (true, &amp;#39;g&amp;#39;) -&amp;gt; GSharp
                        | (_,unknown) -&amp;gt; 
                            sprintf &amp;quot;Unknown note %c&amp;quot; unknown 
                            |&amp;gt; failwith)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;pipe2&lt;/code&gt; sequences parsers, meaning that &lt;code&gt;psharpnote&lt;/code&gt; is a parser that first parses an optional &lt;code&gt;#&lt;/code&gt; (via &lt;code&gt;psharp&lt;/code&gt;) and then parses one of the characters a,c,d,f or g. The results are then mapped to the &lt;code&gt;Note&lt;/code&gt; type. The above parser cannot produce B or E results, since these are not sharpable notes. A further parser is required:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let pnotsharpablenote = anyOf &amp;quot;be&amp;quot; |&amp;gt;&amp;gt; (function 
                        | &amp;#39;b&amp;#39; -&amp;gt; B
                        | &amp;#39;e&amp;#39; -&amp;gt; E
                        | unknown -&amp;gt; 
                            sprintf &amp;quot;Unknown note %c&amp;quot; unknown 
                            |&amp;gt; failwith)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note that both &lt;code&gt;psharpnote&lt;/code&gt; and &lt;code&gt;pnotsharpablenote&lt;/code&gt; include a pattern match that throws an exception. The compiler requires the pattern match to be exhaustive, however by inspection we can see that the ‘unknown’ case can never actually occur. This is a case where the type system is not sufficiently powerful to capture the fact that the value can only be a ‘b’ or ‘e’ character.&lt;/p&gt;
&lt;p&gt;The last remaining hurdle for our &lt;code&gt;Note&lt;/code&gt; parser is to deal with the alternatives:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let pnote = pnotsharpablenote &amp;lt;|&amp;gt; psharpnote
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now we have one parser, &lt;code&gt;pnote&lt;/code&gt; that can parse any possible note. &lt;/p&gt;
&lt;p&gt;Finally, we need to parse the octave to the following type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type Octave = One | Two | Three
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This can be done with a simple character parser:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let poctave = anyOf &amp;quot;123&amp;quot; |&amp;gt;&amp;gt; (function
                | &amp;#39;1&amp;#39; -&amp;gt; One
                | &amp;#39;2&amp;#39; -&amp;gt; Two
                | &amp;#39;3&amp;#39; -&amp;gt; Three
                | unknown -&amp;gt; sprintf &amp;quot;Unknown octave %c&amp;quot; unknown |&amp;gt; failwith)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;|&amp;gt;&amp;gt;&lt;/code&gt; combinator sends the parsed value of its first argument to its second argument, allowing us to map the char 1,2 or 3 to values of type &lt;code&gt;Octave&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;putting-things-together&quot;&gt;Putting Things Together&lt;/h3&gt;
&lt;p&gt;If &lt;code&gt;Sound&lt;/code&gt; is defined as a rest or a Tone:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type ToneRecord = { note: Note; octave: Octave }
type Sound = Rest | Tone of ToneRecord
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then we can parse a &lt;code&gt;Tone&lt;/code&gt; like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let ptone = pipe2 pnote poctave (fun n o -&amp;gt; Tone {note = n; octave = o})
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and a rest:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let prest = stringReturn &amp;quot;-&amp;quot; Rest
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Finally, a &lt;code&gt;Token&lt;/code&gt; is a duration + (tone || rest):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type Token = { length: Length; sound: Sound }
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and is parsed thus:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let ptoken = pipe2 
                plength 
                (prest &amp;lt;|&amp;gt; ptone) 
                (fun l t -&amp;gt; {length = l; sound = t})
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That is everything required to parse a Nokia composer token, which defines a rest or a note. &lt;/p&gt;
&lt;h3 id=&quot;parsing-tunes&quot;&gt;Parsing Tunes&lt;/h3&gt;
&lt;p&gt;Parsing a tune is a simple matter of applying the &lt;code&gt;ptoken&lt;/code&gt; parser repeatedly until the end of the string. Naturally, there is a combinator for that. &lt;code&gt;sepBy&lt;/code&gt; takes two parsers: the first to parse items and a second to parse the separators between items. For the space separated Nokia Composer syntax we can use:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let pscore = sepBy ptoken (pstring &amp;quot; &amp;quot;)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;With this parser we can now parse ‘I Don’t Wanna Miss a Thing’ by Aerosmith:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pscore &amp;quot;2- 16a1 16- 16a1 16- 8a1 16- 4a2 16g2 16- 2g2 16- 4- 8- 16g2 16- 16g2 16- 16g2 8g2 16- 4c2 16#a1 16- 4a2 8g2 4f2 4g2 8d2 8f2 16- 16f2 16- 16c2 8c2 16- 4a2 8g2 16f2 16- 8f2 16- 16c2 16- 4g2 4f2&amp;quot;
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>Implementing an F# Signal Generator</title>
      <link>http://withouttheloop.com/articles/2014-10-29-fsharp-signal-generator/</link>
      <pubDate>Wed, 29 Oct 2014 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2014-10-29-fsharp-signal-generator/</guid>
      <author></author>
      <description>&lt;p&gt;&lt;img src=&quot;sg.jpg&quot; alt=&quot;signal generator&quot; align=&quot;right&quot; style=&quot;width:400px&quot;/&gt;&lt;/p&gt;
&lt;p&gt;As part of a larger project I have been working on a signal generator. A signal generator is a device (in this case an F# program) that is often used to generate waves at a particular frequency that can be interpreted as sound (by applying to a speaker as a voltage). &lt;/p&gt;
&lt;p&gt;For my project I want to generate pitches and then convert the signal to PCM audio data, wrapped in the windows WAVE file format. PCM format means that the signal is represented as a series of positive or negative values within a certain range. The number of samples per second is called the sample rate (44,100 for CD audio). The range of the values is governed by the bit depth, again I will stick with the CD audio standard 16 bit audio, giving me a range of -32768 to 32767.&lt;/p&gt;
&lt;h2 id=&quot;generating-signals&quot;&gt;Generating Signals&lt;/h2&gt;
&lt;p&gt;The simplest and purest representation of a particular frequency is given by a sine wave. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;sine.gif&quot; alt=&quot;A sine wave&quot;/&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This graph was generated using FSharp.Charting and the following fsx file&lt;/em&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#load &amp;quot;../packages/FSharp.Charting.0.90.7/FSharp.Charting.fsx&amp;quot;
open FSharp.Charting
let c = seq { for x in [1.0..0.1..20.0] do yield (x, sin x) } |&amp;gt; Chart.Line
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note that the wave has a range from -1 to 1 and a recurring regular frequency. But what is that regular frequency? The F# &lt;code&gt;sin&lt;/code&gt; function operates on an angle given in radians. Experimenting in the F# repl (fsi) we can find that &lt;code&gt;sin&lt;/code&gt; of PI radians is 0&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; sin System.Math.PI;;
val it : float = 1.224606354e-16
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Interesting. What about the &lt;code&gt;sin&lt;/code&gt; of 2 PI radians?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; sin (2. * System.Math.PI);;
val it : float = -2.449212708e-16
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Those accustomed to working with floating point numbers will recognise that anything x 10^-16 is floating points version of 0. So sin (n * PI) is 0. This tells us, or at least suggests, that the graph crosses the x axis every PI change in x. Now let’s look at mid-points between x intercepts:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; sin (1.5 * System.Math.PI);;
val it : float = -1.0
&amp;gt; sin (2.5 * System.Math.PI);;
val it : float = 1.0
&amp;gt; sin (3.5 * System.Math.PI);;
val it : float = -1.0
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Half way between PI and 2 x PI the y value is -1. Half way between 2 x PI and 3 x PI the y value is 1. Half way between 3 x PI and 4 x PI the y value is back to -1, so we see that the graph repeats every 2 x PI. &lt;/p&gt;
&lt;p&gt;Now we can start generating PCM data. First we need to list the samples we want to create:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let requiredSamples = seq { 1.0..(seconds * sampleRate) }
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We need &lt;code&gt;sampleRate&lt;/code&gt; samples for every second. Next we plot those points using the &lt;code&gt;sin&lt;/code&gt; function, and scale them by the expected range for 16 bit audio.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let samples = Seq.map 
                (fun x -&amp;gt; x |&amp;gt; sin |&amp;gt; (*) 32767 |&amp;gt; int16) 
                requiredSamples
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now we have PCM audio samples that we can pack and send to an audio player for listening pleasure.&lt;/p&gt;
&lt;h2 id=&quot;packing-pcm-data-into-a-wave-file&quot;&gt;Packing PCM data into a WAVE File&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&quot;https://ccrma.stanford.edu/courses/422/projects/WaveFormat/&quot;&gt;WAVE file format&lt;/a&gt; is a binary format defined as part of Microsoft’s RIFF specification. The details of the format are not very interesting. It has some headers that describe the format in use, and details of the audio data, such as sample rate, bit depth and number of channels. To encode 16 bit mono samples at 44,100the following is sufficient:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let pack (d:int16[]) = 
    let stream = new MemoryStream();
    let writer = new BinaryWriter(stream, System.Text.Encoding.ASCII);
    let dataLength = Array.length d * 2

    // RIFF
    writer.Write(System.Text.Encoding.ASCII.GetBytes(&amp;quot;RIFF&amp;quot;))
    writer.Write(Array.length d)
    writer.Write(System.Text.Encoding.ASCII.GetBytes(&amp;quot;WAVE&amp;quot;))

    // fmt
    writer.Write(System.Text.Encoding.ASCII.GetBytes(&amp;quot;fmt &amp;quot;))
    writer.Write(16)
    writer.Write(1s)        // PCM
    writer.Write(1s)        // mono
    writer.Write(44100)     // sample rate
    writer.Write(44100 * 16 / 8)     // byte rate
    writer.Write(2s)        // bytes per sample
    writer.Write(16s)       // bits per sample

    // data
    writer.Write(System.Text.Encoding.ASCII.GetBytes(&amp;quot;data&amp;quot;))
    writer.Write(dataLength)
    let data:byte[] = Array.zeroCreate dataLength
    System.Buffer.BlockCopy(d, 0, data, 0, data.Length)
    writer.Write(data)
    stream
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;tuning&quot;&gt;Tuning&lt;/h2&gt;
&lt;p&gt;So far we have a signal generator that generates audio data following a sine wave, but we have no control of the pitch (frequency) of the sound. We know that the wave repeats every 2 x PI, and we know that we have 44,100 samples per second. What we need is a way to expand and contract the wave horizontally to hit target frequencies. The graph transformation that controls horizontal stretch is achieved by multiplying the argument by a factor prior to applying the original function. ie&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let square x = x * x
let squareStretched x = (2 * x) * (2 * x)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The frequence of the wave is&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;freq = 44100 / period
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and the period is 2 x PI. To add a horizontal stretching factor we multiply by some factor.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;freq = 44100 / 2 x PI x factor
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;solving for the factor&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;factor = 44100 / 2 * PI * freq
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now we can update our signal generating function to be tuneable using the inverse of factor&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let frequency = 440.
let samples = Seq.map 
                (fun x -&amp;gt; x 
                |&amp;gt; (*) (2. * System.Math.PI * frequency / 44100.)
                |&amp;gt; sin 
                |&amp;gt; (*) 32767 
                |&amp;gt; int16) 
                requiredSamples
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now we can tune our data to frequencies. Above I have used 440Hz (concert A). To pack into a WAVE and save to a file&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let write (ms:MemoryStream) =
    use fs = new FileStream(Path.Combine(__SOURCE_DIRECTORY__,&amp;quot;test.wav&amp;quot;), FileMode.Create)
    ms.WriteTo(fs)

samples |&amp;gt; pack |&amp;gt; write
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;admiring-the-results&quot;&gt;Admiring the Results&lt;/h2&gt;
&lt;p&gt;What is the result of all that effort? &lt;a href=&quot;/articles/2014-10-29-fsharp-signal-generator/test.wav&quot;&gt;A few seconds of concert pitch&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Ad-hoc Polymorphism in F# (how to survive without Type Classes)</title>
      <link>http://withouttheloop.com/articles/2014-10-21-fsharp-adhoc-polymorphism/</link>
      <pubDate>Tue, 21 Oct 2014 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2014-10-21-fsharp-adhoc-polymorphism/</guid>
      <author></author>
      <description>&lt;p&gt;A recurring source of confusion for me when reading about and writing F# has been ad-hoc polymorphism, and it seems that I am not the only one:&lt;/p&gt;
&lt;p&gt;&lt;blockquote&gt;
“F# does not have support for type-classes, or for multi-methods, or anything in between and while you can do certain tricks to achieve such an effect, like passing around a global virtual table, truth is F#’s ad-hoc polymorphic capabilities really suck.”
&lt;/blockquote&gt;
&lt;a href=&quot;http://martinsprogrammingblog.blogspot.com.au/2012/10/the-future-of-net-lies-in-mono-future.html&quot;&gt;Martin Trojer&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Ad_hoc_polymorphism&quot;&gt;Ad-hoc polymorphism&lt;/a&gt; is the programming language feature that allows a function to work with arguments of varying types. The example given by wikipedia is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1 + 2 = 3
3.14 + 0.0015 = 3.1415
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The first line shows the addition of two integers. The second line shows the addition of two floating point numbers. For this to work the &lt;code&gt;(+)&lt;/code&gt; operator must be a function that can operate on both integers and floats. This is an example of ad-hoc polymorphism. F#’s predecessor OCaml has almost no support for ad-hoc polymorphism, so the previous &lt;code&gt;(+)&lt;/code&gt; example does not work in OCaml. &lt;code&gt;+, -, / and *&lt;/code&gt; only work for integers and you need &lt;code&gt;+., -., /. and *.&lt;/code&gt;     for floating point operations. &lt;/p&gt;
&lt;h2 id=&quot;where-f-becomes-difficult&quot;&gt;Where F# Becomes Difficult&lt;/h2&gt;
&lt;p&gt;Consider the following example (borrowed from &lt;a href=&quot;http://blog.lab49.com/archives/2895&quot;&gt;http://blog.lab49.com/archives/2895&lt;/a&gt;):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// this does not work :( 
// (expression was expected to have type 
// float but here has type int)
let twice x = x + x

twice 2.0 |&amp;gt; Console.WriteLine
twice 2 |&amp;gt; Console.WriteLine
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This code fails because the x parameter of the twice function is inferred to be of type &lt;code&gt;float&lt;/code&gt;, because that is the type of the argument the first time that it is called. Type inference lets us get away with not explicitly specifying a type, but it still has to assign a single type. In this case it chooses float, so when the function is applied to an integer we get a compilation error. &lt;/p&gt;
&lt;p&gt;In F# the twice function above can fixed by means of the &lt;code&gt;inline&lt;/code&gt; modifier. &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// this version works!
let inline twice x = x + x

twice 2.0 |&amp;gt; Console.WriteLine
twice 2 |&amp;gt; Console.WriteLine
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Each call to the inline function is replaced by inline code with its own type inference, thus the compiler effectively converts the above to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(fun (x:float) -&amp;gt; x + x)(2.0) |&amp;gt; Console.WriteLine
(fun (x:int) -&amp;gt; x + x)(2) |&amp;gt; Console.WriteLine
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is rather nice because we get the explicit type correctness of having no runtime type coercion, but without having to manually provide implementations for each type. In this way it is superior even to &lt;a href=&quot;http://www.haskell.org/tutorial/classes.html&quot;&gt;Haskell’s lauded type class feature&lt;/a&gt;. &lt;/p&gt;
&lt;h2 id=&quot;a-more-realistic-example&quot;&gt;A More Realistic Example&lt;/h2&gt;
&lt;p&gt;Imagine you want to define a function &lt;code&gt;show&lt;/code&gt; that converts a value of type &lt;code&gt;A&lt;/code&gt; or &lt;code&gt;B&lt;/code&gt; to a string representation. My first attempt was:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type A = { thing: int }
type B = { label: string }

let show (a:A) =
    sprintf &amp;quot;%A&amp;quot; a

let show (b:B) =
    sprintf &amp;quot;%A&amp;quot; b

{ thing = 98 } |&amp;gt; show |&amp;gt; Console.WriteLine
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is not allowed. F# does not allow you to overload the &lt;code&gt;show&lt;/code&gt; function in this way.&lt;/p&gt;
&lt;h2 id=&quot;how-about-using-an-interface-&quot;&gt;How About Using an Interface?&lt;/h2&gt;
&lt;p&gt;Often the requirement for ad-hoc polymorphism can be achieved by using interfaces. F# programmers often talk about using a ‘dictionary of operations’ which is essentially the same thing.&lt;/p&gt;
&lt;p&gt;The example above becomes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type IShow =
    abstract member show : unit -&amp;gt; string

type A =
    { thing: int }
    interface IShow with
        member this.show() = sprintf &amp;quot;%A&amp;quot; this
type B =
    { label: string }
    interface IShow with
        member this.show() = sprintf &amp;quot;%A&amp;quot; this

let show (x:IShow) =
    x.show()

{ thing = 98 } |&amp;gt; show |&amp;gt; Console.WriteLine
{ label = &amp;quot;Car&amp;quot; } |&amp;gt; show |&amp;gt; Console.WriteLine
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is OK, but a little clumsy. There are also some restrictions on implementing interfaces that may occassionally make this solution infeasible. &lt;/p&gt;
&lt;p&gt;F# allows type coercion to an interface for function arguments so we avoid having to explicitly upcast values to IShow (&lt;code&gt;({ thing =98 } :&amp;gt; IShow).show()&lt;/code&gt;). &lt;/p&gt;
&lt;h2 id=&quot;solution-using-static-member-overloading&quot;&gt;Solution Using Static Member Overloading&lt;/h2&gt;
&lt;p&gt;My favourite solution, at least so far, is to use static member overloading. This takes advantage of the fact that while top-level functions cannot be overloaded functions on types can.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type A = { thing: int }
type B = { label: string }

type ThingThatShows =
    static member show(x:A) = sprintf &amp;quot;%A&amp;quot; x
    static member show(x:B) = sprintf &amp;quot;%A&amp;quot; x

{ thing = 98 } |&amp;gt; ThingThatShows.show |&amp;gt; Console.WriteLine
{ label = &amp;quot;Car&amp;quot; } |&amp;gt; ThingThatShows.show |&amp;gt; Console.WriteLine
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This nice part about this is that I am able to define two versions of &lt;code&gt;ThingThatShows.show&lt;/code&gt;, one for type &lt;code&gt;A&lt;/code&gt; and one for type &lt;code&gt;B&lt;/code&gt;. The correct function is then applied based upon the type of the argument.&lt;/p&gt;
&lt;h2 id=&quot;solution-using-statically-resolved-type-constraints&quot;&gt;Solution Using Statically Resolved Type Constraints&lt;/h2&gt;
&lt;p&gt;F# has a somewhat unusual feature - statically resolved generic types - and these can be used in combination with member constraints and inline functions to implement ad-hoc polymorphism. &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type A = { thing: int }
    with static member show a = sprintf &amp;quot;%A&amp;quot; a
type B = { label: string }
    with static member show b = sprintf &amp;quot;%A&amp;quot; b

let inline show (x:^t) =
    (^t: (static member show: ^t -&amp;gt; string) (x))

{ thing = 98 } |&amp;gt; show |&amp;gt; Console.WriteLine
{ label = &amp;quot;Car&amp;quot; } |&amp;gt; show |&amp;gt; Console.WriteLine
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is a lot like the solution using interfaces except:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I did not have to define an interface.&lt;/li&gt;
&lt;li&gt;I did not have to explicitly implement the interface members.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;what-does-this-look-like-in-fancy-pants-haskell-&quot;&gt;What Does This Look Like in Fancy-pants Haskell?&lt;/h2&gt;
&lt;p&gt;Haskell does not have this ad-hoc polymorphism problem. It is obvious in Haskell that Type Classes are the correct solution to this challenge. The example repeated above when converted to a Type Class based Haskell solution is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- define a type class for types
-- that can be shown
class Showable a where
    shw :: a -&amp;gt; String

data A = A String
data B = B Int

-- add the types A and B 
-- to the Showable type class

instance Showable A where
    shw (A s) = s

instance Showable B where
    shw (B i) = show i

putStrLn (shw (A &amp;quot;Car&amp;quot;))
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>HTTP Basic Authentication Support in Wurl</title>
      <link>http://withouttheloop.com/articles/2014-10-08-wurl-http-basic-auth/</link>
      <pubDate>Wed, 08 Oct 2014 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2014-10-08-wurl-http-basic-auth/</guid>
      <author></author>
      <description>&lt;p&gt;&lt;a href=&quot;http://wurl.io&quot;&gt;Wurl&lt;/a&gt; (web curl) is a browser-based HTTP test client that I &lt;a href=&quot;http://withouttheloop.com/articles/2014-03-11-wurl/&quot;&gt;slapped together earlier this year (2014)&lt;/a&gt;, partly because it is a useful tool and partly because it gives me a play project to experiment with React, Typescript and F#. &lt;/p&gt;
&lt;h2 id=&quot;how-it-works&quot;&gt;How it works&lt;/h2&gt;
&lt;p&gt;Wurl describes http requests using the jquery &lt;a href=&quot;http://api.jquery.com/jquery.ajax/&quot;&gt;$.ajax syntax&lt;/a&gt;. I chose this because most developers are familiar with it and because it is capable of describing a wide variety of request options.&lt;/p&gt;
&lt;p&gt;Wurl first attempts to make the request by directly evaluating the request using jquery from the browser. Try &lt;a href=&quot;http://wurl.io/request?url=https%3A%2F%2Fapi.github.com&quot;&gt;this fun example&lt;/a&gt; of querying the github API. Often this strategy will fail due to &lt;a href=&quot;http://en.wikipedia.org/wiki/Cross-origin_resource_sharing&quot;&gt;cross-origin resource sharing&lt;/a&gt; (CORS) restrictions. Wurl is smart enough to detect CORS errors and fallback to making the request via a proxy, which is not subject to CORS restrictions. &lt;/p&gt;
&lt;p&gt;Unfortunately the proxy is not jquery and does not use jquery (it uses &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.net.http.httpclient%28v=vs.118%29.aspx&quot;&gt;HttpClient&lt;/a&gt;) so the query must be parsed and translated. Therefore queries that go via the CORS proxy do not implement the full set of $.ajax features. &lt;/p&gt;
&lt;h2 id=&quot;http-basic-authentication&quot;&gt;HTTP basic authentication&lt;/h2&gt;
&lt;p&gt;Recently I added support for the Authorization header. The options that are honoured now are: url, type (http verb), headers (Authorization only). This means that basic authentication can be used from Wurl for all services, regardless of CORS support.  &lt;/p&gt;
&lt;iframe src=&quot;http://wurl.io/template/d3ba57f1-ebd4-44a6-ad8c-729881cd495f&quot; style=&quot;width: 100%;height:400px;&quot; frameborder=&quot;0&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;Here is an &lt;a href=&quot;http://wurl.io/template/d3ba57f1-ebd4-44a6-ad8c-729881cd495f&quot;&gt;example showing a request to the github API that uses basic authentication&lt;/a&gt;. It fails, but only because I have removed my password. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>DbUp (database migration) Support For Postgresql</title>
      <link>http://withouttheloop.com/articles/2014-10-07-dbup-meet-postgresql/</link>
      <pubDate>Tue, 07 Oct 2014 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2014-10-07-dbup-meet-postgresql/</guid>
      <author></author>
      <description>&lt;blockquote&gt;
&lt;p&gt;DbUp is a .NET library that helps you to deploy changes to &lt;code&gt;SQL Server&lt;/code&gt; databases. It tracks which SQL scripts have been run already, and runs the change scripts that are needed to get your database up to date.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;DbUp is a simple, mature, sql script-based database deployment tool. I typically use it for all of my projects that use Sql Server. I like the idea so much that I have previously implemented similar systems for &lt;a href=&quot;https://github.com/liammclennan/couchpotato&quot;&gt;CouchDb&lt;/a&gt; and Postgresql. It occurred to me that instead of badly re-implementing half of the features of DbUp I should just add new database support to DbUp (open source right?).&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;DbUp now supports Postgresql&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;show-me-the-codez-&quot;&gt;Show me the Codez!&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;var upgrader = DeployChanges.To
    .PostgresqlDatabase(&amp;quot;Server=127.0.0.1;Database=testo;Port=5432;User Id=*****;Password=*******;&amp;quot;)
    .WithScriptsEmbeddedInAssembly(Assembly.GetExecutingAssembly())
    .LogToConsole()
    .Build();

var result = upgrader.PerformUpgrade();
&lt;/code&gt;&lt;/pre&gt;&lt;blockquote&gt;
&lt;p&gt;NOTE: at the time of writing this update has been merged but not yet made available via Nuget.&lt;/p&gt;
&lt;/blockquote&gt;
</description>
    </item>
    <item>
      <title>PostgresDoc now works with C#</title>
      <link>http://withouttheloop.com/articles/2014-10-05-postgresdoc-csharp/</link>
      <pubDate>Sun, 05 Oct 2014 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2014-10-05-postgresdoc-csharp/</guid>
      <author></author>
      <description>&lt;p&gt;&lt;a href=&quot;http://withouttheloop.com/articles/2014-09-30-postgresql-nosql/&quot;&gt;PostgresDoc&lt;/a&gt; is a simple F# library for working with document data in Postgresql. Recently, I have been experimenting with ways to use it from C#.&lt;/p&gt;
&lt;h2 id=&quot;using-an-f-library-from-c-&quot;&gt;Using an F# Library from C#&lt;/h2&gt;
&lt;p&gt;It is certainly possible to use an F# library from C#, but the syntax can be difficult. To ease the pain I experimented with ways to make the API more C# friendly, and ultimately &lt;a href=&quot;https://twitter.com/liammclennan/status/516546495156203520&quot;&gt;gave up&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;twitter.png&quot; alt=&quot;giving up on a shared C#/F# API&quot; /&gt;&lt;/p&gt;
&lt;h2 id=&quot;wrapping-an-f-library-for-c-consumers&quot;&gt;Wrapping an F# Library for C# consumers&lt;/h2&gt;
&lt;p&gt;The approach that ultimately worked for me was to create a new C# project that wraps the F# version of PostgresDoc and provides an API that is optimised for C#. The unit of work is represented by a Queue. New operations are added via the &lt;code&gt;Enqueue&lt;/code&gt; method, and created via static factory methods on the Operation class, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;unitOfWork.Enqueue(Operation.Insert(ernesto._id, ernesto));
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;the-postgresdoccs-c-api&quot;&gt;The PostgresDocCs C# API&lt;/h2&gt;
&lt;p&gt;Here is a simple example of working with a document from C#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class Person 
{
    public Guid _id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
    public string[] FavouriteThings { get; set; }
}

var ernesto = new Person
        {
            _id = Guid.NewGuid(),
            Name = &amp;quot;Ernesto&amp;quot;,
            Age = 31,
            FavouriteThings = new[] { &amp;quot;Pistachio Ice Cream&amp;quot;, &amp;quot;Postgresql&amp;quot;, &amp;quot;F#&amp;quot; }
        };
var connString = &amp;quot;Server=127.0.0.1;Port=5432;User Id=******;Password=*****;Database=testo;&amp;quot;;

var unitOfWork = new Queue&amp;lt;Operation&amp;lt;Guid&amp;gt;&amp;gt;();

// insert a document
unitOfWork.Enqueue(Operation.Insert(ernesto._id, ernesto));

// modify a document
ernesto.Age = 32;
unitOfWork.Enqueue(Do.Update(ernesto._id, ernesto));

// persist the changes in a transaction
UnitOfWork.Commit(connString, unitOfWork)
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;querying&quot;&gt;Querying&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;var ernesto = Query&amp;lt;Person&amp;gt;.For(
            connString, 
            &amp;quot;select data from Person where id = :id&amp;quot;, 
            new Dictionary&amp;lt;string, object&amp;gt; { {&amp;quot;id&amp;quot;, ernesto._id} });
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>Postgresql as a Nosql Document Store</title>
      <link>http://withouttheloop.com/articles/2014-09-30-postgresql-nosql/</link>
      <pubDate>Tue, 30 Sep 2014 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2014-09-30-postgresql-nosql/</guid>
      <author></author>
      <description>&lt;p&gt;&lt;a href=&quot;http://www.postgresql.org/&quot;&gt;Postgresql&lt;/a&gt; makes a &lt;a href=&quot;http://www.infoq.com/news/2014/05/postgresql-9-4&quot;&gt;fairly decent schemaless Nosql document database&lt;/a&gt;. It is the only database I can think of that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;is mature&lt;/li&gt;
&lt;li&gt;is fast&lt;/li&gt;
&lt;li&gt;has an extensive plugin ecosystem&lt;/li&gt;
&lt;li&gt;has ACID compliance&lt;/li&gt;
&lt;li&gt;supports schemaless document storage&lt;/li&gt;
&lt;li&gt;supports relational data storage&lt;/li&gt;
&lt;li&gt;can join across documents and relational data&lt;/li&gt;
&lt;li&gt;can index into documents as well as relational data&lt;/li&gt;
&lt;li&gt;has built-in full text search&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Postgres already had most of this. The only thing they had to add to facilitate document storage was a json data type and the ability to create indexes on json properties. &lt;/p&gt;
&lt;h2 id=&quot;an-example&quot;&gt;An Example&lt;/h2&gt;
&lt;p&gt;If I want to store Person documents I might create a table called &lt;code&gt;Person&lt;/code&gt; with a json column to hold the document:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;create table Person ( data json NOT NULL );
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The documents will have a unique identifier &lt;code&gt;_id&lt;/code&gt; which I need to be able to query on, so I add an index:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CREATE UNIQUE INDEX people_id ON Person ((data-&amp;gt;&amp;gt;&amp;#39;_id&amp;#39;));
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then the query to select a document is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;select data from Person where data-&amp;gt;&amp;gt;&amp;#39;_id&amp;#39; = &amp;#39;A158CCB9-BB68-4FC2-8123-79B32053B2A3&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;better-tooling&quot;&gt;Better Tooling&lt;/h2&gt;
&lt;p&gt;A typical application scenario will make changes to multiple documents. We can take advantage of Postgres’s transaction support by accumulating changes and commiting them within the same transaction. If there are no problems then the changes are persisted, but if something goes wrong the entire transaction is reverted, leaving the database in a consistent state. &lt;/p&gt;
&lt;p&gt;I have been working on a project I call &lt;a href=&quot;https://github.com/liammclennan/PostgresDoc&quot;&gt;PostgresDoc&lt;/a&gt; to make working with postgres documents easier. Currently it is an F# project but I will add a C# wrapper soon. Use it like so&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// accumulate a stack of changes
let julio = { _id = System.Guid.NewGuid(); age = 30; name = &amp;quot;Julio&amp;quot; }
let uow = [Insert julio]
let uow2 = Update { julio with age = 31} :: uow
let uow3 = Delete julio :: uow2

commit store uow3
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This approach is great for testing (just make assertions against the unit of work) and is free from many of the awful consistency problems that plague ORMs such as NHibernate and Entity Framework. &lt;/p&gt;
&lt;p&gt;Queries are easy too:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let peopleWhoAreThirty = 
    [ &amp;quot;age&amp;quot;, box (30) ] 
    |&amp;gt; query&amp;lt;Person&amp;gt; store &amp;quot;select data from people where data-&amp;gt;&amp;gt;&amp;#39;age&amp;#39; = :age&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;more&quot;&gt;More&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.postgresql.org/docs/9.4/static/datatype-json.html&quot;&gt;Postgresql JSON Datatypes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.postgresql.org/docs/9.4/static/functions-json.html&quot;&gt;Postgresql JSON Functions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.craigkerstiens.com/2014/03/24/Postgres-9.4-Looking-up/&quot;&gt;PostgreSQL 9.4 - Looking Up (With JSONB and Logical Decoding)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    <item>
      <title>Converting to TypeScript</title>
      <link>http://withouttheloop.com/articles/2014-09-25-converting-to-typescript/</link>
      <pubDate>Thu, 25 Sep 2014 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2014-09-25-converting-to-typescript/</guid>
      <author></author>
      <description>&lt;p&gt;My most recent side project is a web based curl - &lt;a href=&quot;http://wurl.io&quot;&gt;wurl&lt;/a&gt; - intended to be &lt;a href=&quot;http://withouttheloop.com/articles/2014-02-09-aristotle/&quot;&gt;a convenient interface for experimenting with HTTP APIs&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;Wurl is a useful tool that I created to satisfy a need - but it is also a project that I use to experiment with development techniques and technologies. &lt;/p&gt;
&lt;p&gt;In the browser we are limited to JavaScript, a dynamic language not easily integrated with whatever server-side technology is in use (in this case Asp.Net MVC and F#). To help prevent runtime JavaScript bugs I recently converted wurl from JavaScript to &lt;a href=&quot;http://www.typescriptlang.org/&quot;&gt;TypeScript&lt;/a&gt;, a statically typed superset of JavaScript. The purpose of this post is to document that experience.&lt;/p&gt;
&lt;h2 id=&quot;where-to-start-&quot;&gt;Where to Start?&lt;/h2&gt;
&lt;p&gt;It is not entirely obvious where to start a JavaScript -&amp;gt; TypeScript migration. I found that the best way is to start with bits of JavaScript that are small and have few dependencies. &lt;/p&gt;
&lt;h2 id=&quot;converting-a-javascript-module-to-typescript&quot;&gt;Converting a JavaScript Module to TypeScript&lt;/h2&gt;
&lt;p&gt;Wurl has a JavaScript module used to contain its models. The &lt;code&gt;Template&lt;/code&gt; model represents an HTTP request and how it is transformed. &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;﻿define(&amp;#39;models&amp;#39;, [], function() {

    var Template = dbc.makeConstructor({
        id: [{validator:&amp;#39;type&amp;#39;,args:[&amp;#39;string&amp;#39;]}],
        label: [{validator:&amp;#39;type&amp;#39;,args:[&amp;#39;string&amp;#39;]}],
        request: [{validator:&amp;#39;type&amp;#39;,args:[&amp;#39;string&amp;#39;]}],
        transformer: [{validator:&amp;#39;type&amp;#39;,args:[&amp;#39;string&amp;#39;]}],
        view: [{validator:&amp;#39;type&amp;#39;,args:[&amp;#39;string&amp;#39;]}]
    });
    Template.url = &amp;#39;/template&amp;#39;;

    return {
        Template: Template
    };
});
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Step 1 was to rename the file with a .ts extension. Visual Studio immediately displayed a compilation error because the type of the &lt;code&gt;define&lt;/code&gt; function is not known. &lt;code&gt;define&lt;/code&gt; is a function that comes from the &lt;a href=&quot;https://github.com/liammclennan/smodules&quot;&gt;smodules&lt;/a&gt; (small modules) JavaScript module library. To be able to use smodules, a JavaScript library, from TypeScript I need a &lt;a href=&quot;http://www.typescriptlang.org/Handbook#writing-dts-files&quot;&gt;type definitions file&lt;/a&gt; that defines all the types exposed by smodules. To create a type definition for smodules I create a new file with the same name as the smodules library file, but with the extension .d.ts. In that file I add a type declaration for the define function. &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;﻿declare function define(name:string, dependencies: string[], moduleFactory: any): void;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This tells TypeScript that define is a function, with arguments of type string, string array and any. Define does not return anything. I also add a declaration for the other function exposed by smodules:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;declare function require(name: string) : any;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The issue now is that TypeScript does not know where to look for the type definitions, so I add a reference to the models module:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;﻿/// &amp;lt;reference path=&amp;quot;packages\02-smodules.d.ts&amp;quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now when I try to compile I get no errors about smodules, instead the compiler complains about the call to &lt;code&gt;dbc.makeConstructor&lt;/code&gt;. &lt;a href=&quot;https://github.com/liammclennan/dbc&quot;&gt;dbc&lt;/a&gt; is a library providing runtime type assertions. Here it is being used to define a runtime ‘type’ check. This compilation error is fixed according to the same strategy: create a .d.ts file for dbc containing:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;﻿declare module dbc {
    function makeConstructor(spec: any): any;

    function check(o: any, spec: any, message?: string): void;
} 
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;using-well-known-javascript-libraries&quot;&gt;Using Well-Known JavaScript libraries&lt;/h2&gt;
&lt;p&gt;wurl makes use of many JavaScript libraries including:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;* underscore
* react
* jquery
* q
* toastr
* codemirror
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To be able to use these libraries from TypeScript I need type definitions for them all. Fortunately, there is a &lt;a href=&quot;https://github.com/borisyankov/DefinitelyTyped&quot;&gt;github repository containing many type definition files&lt;/a&gt; and they are available as nuget packages. &lt;/p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;
&lt;p&gt;Wurl has perhaps 1,000 lines of JavaScript, so it is a small project. It took me about two hours to convert it to TypeScript, without having any idea what I was doing. It is easier to start a project with TypeScript from the beginning, however doing a JavaScript -&amp;gt; TypeScript conversion is perfectly feasible, even for larger projects.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Prometheus - Linking F# Records to Typescript Classes</title>
      <link>http://withouttheloop.com/articles/2014-09-20-Prometheus/</link>
      <pubDate>Sat, 20 Sep 2014 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2014-09-20-Prometheus/</guid>
      <author></author>
      <description>&lt;p&gt;I would like to program in a way that is as strict, unambiguous and correct as possible. I want the compiler to assist as much as possible, for new development and for refactoring. SPJ has described a compiler as a, “weak theorem prover” and I want my theorems weakly proven. But there is a problem. A lot of my work is in the browser where JavaScript is the only option, and JavaScript does not meet any of my stated requirements. Fortunately, there is a neat little project called &lt;a href=&quot;http://www.typescriptlang.org/&quot;&gt;TypeScript&lt;/a&gt; that adds static type checking to JavaScript. &lt;/p&gt;
&lt;p&gt;For C# solutions there is a tool called &lt;a href=&quot;https://github.com/praeclarum/Netjs&quot;&gt;netjs&lt;/a&gt; that can compile C# code to TypeScript and thence to JavaScript. I tested it on a simple C# solution with success, however, it does not work for F# projects. &lt;/p&gt;
&lt;p&gt;For F# web projects my minimum requirement is a way to synchronize F# records with TypeScript classes, so that I may share equivalent type defininitions between my F# server application and TypeScript/JavaScript client application. I’m not a big fan of classes in F#, and neither discriminated unions nor tuples have an obvious mapping to JavaScript so for now I am content to stick to F# records.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/liammclennan/Prometheus&quot;&gt;Prometheus&lt;/a&gt; is a pre-alpha project (most of mine stay that way) that converts an F# assembly to a TypeScript file containing class equivalents of all the records in the F# assembly. By running prometheus immediately prior to your normal compilation step the sequence is something like:&lt;/p&gt;
&lt;blockquote&gt;
    Prometheus generates typescript definitions -&amp;gt; F# compilation -&amp;gt; TypeScript compilation
&lt;/blockquote&gt;  

&lt;p&gt;The flaw here is that sometimes you may have to build twice to get everything synced properly but for now that is a 1st world problem. The fix is to move the Prometheus compilation between the F# compilation and the TypeScript compilation. &lt;/p&gt;
&lt;p&gt;Give an F# assembly containing the following module:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace MyModels

    type Address = { number: int; street: string }
    type Person = { name: string; age: int; address: Address }
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Prometheus produces the following valid TypeScript file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;module MyModels { 
    export class Address {
        constructor(public number: number, public street: string) {}
    }
}

module MyModels { 
    export class Person {
        constructor(public name: string, public age: number, public address: Address) {}
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now if my server and client side model definitions fall out of sync it will be a glorious compilation error. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>React Flux Etc</title>
      <link>http://withouttheloop.com/articles/2014-05-29-react-flux-etc/</link>
      <pubDate>Thu, 29 May 2014 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2014-05-29-react-flux-etc/</guid>
      <author></author>
      <description>&lt;p&gt;I’ve been enjoying working with &lt;a href=&quot;http://pluralsight.com/training/courses/TableOfContents?courseName=react-fundamentals&quot;&gt;React&lt;/a&gt; for a while now. I like it’s emphasis on stateless, composable components. &lt;/p&gt;
&lt;p&gt;Unlike Angular, React does not give the developer much help with the design of their application. To address this the React team recently starting talking about &lt;a href=&quot;http://facebook.github.io/react/blog/&quot;&gt;Flux&lt;/a&gt;, the architecture they use at Facebook. Flux has many pieces but the significant idea is that events no longer bubble back up the component hierarchy, instead they go out to an event aggregator that changes the application state, causing the UI to update. Much is made of the single directional data flow, state -&amp;gt; UI -&amp;gt; events -&amp;gt; aggregator -&amp;gt; change state -&amp;gt; UI etc. I like this design and I’ll add one important rule:&lt;/p&gt;
&lt;blockquote&gt;
Use the same state for all related application specific components. Some components will get more data than they need, but having a single state model simplifies changes. 
&lt;/blockquote&gt;

&lt;p&gt;The other common criticism of React is that is does not include batteries (again compared to Angular). This doesn’t bother me much since I have strong opinions and have therefore created my own version of most components that I need. &lt;/p&gt;
&lt;p&gt;The first missing piece that a developer is likely to encouter is a client-side router. I have heard of many people using the Backbone router, which is nice because it supports both html5 style pushstate routing and the older hash fragment style routing. I’ve been using &lt;a href=&quot;https://github.com/flatiron/director&quot;&gt;Flatiron Director&lt;/a&gt; which is fine.&lt;/p&gt;
&lt;p&gt;For server communication I have become comfortable with Backbone’s resource-oriented style. Angular provides $resource for this purpose. I use &lt;a href=&quot;https://github.com/liammclennan/resourceclient&quot;&gt;resourceclient&lt;/a&gt; because it is better. It uses Q promises instead of the broken jQuery promises and integrates with another library to provide object validation and type coercion. Where most similar libraries return json data without methods resourceclient is smart enough to return actual instances of your client-side models. &lt;/p&gt;
&lt;p&gt;Integrated with resourceclient I use &lt;a href=&quot;https://github.com/liammclennan/dbc&quot;&gt;dbc&lt;/a&gt; to validate that objects match certain requirements and to create constructors that enure objects are valid. &lt;/p&gt;
&lt;p&gt;For example, I might create a constructor like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var Person = dbc.makeConstructor({
    name: [{validator:&amp;#39;type&amp;#39;,args:[&amp;#39;string&amp;#39;]}],
    age: [{validator:&amp;#39;type&amp;#39;,args:[&amp;#39;number&amp;#39;]}]
});
Person.url = &amp;#39;/api/person/&amp;#39;;
var personGateway = resourceclient(Person);

var firstPerson = new Person({
    name: &amp;#39;Alice&amp;#39;,
    age: 58
});

personGateway.create(firstPerson).then(function (data) {
    // data is the model returned from the server
});
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The next missing piece is support for forms and validation. For that I use a set of purpose-built modules that aren’t reusable at the moment.  &lt;/p&gt;
&lt;p&gt;If you have to do client-side / JavaScript work then React is the best of the bunch. Enjoy. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>PostgresDoc</title>
      <link>http://withouttheloop.com/articles/2014-04-22-postgresdoc/</link>
      <pubDate>Tue, 22 Apr 2014 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2014-04-22-postgresdoc/</guid>
      <author></author>
      <description>&lt;h2 id=&quot;story-so-far&quot;&gt;Story so far&lt;/h2&gt;
&lt;p&gt;Lately I have been moving towards more functional style programming. One way that you can categorize functional languages is those that have their own complete ecosystem (haskell, erlang, oCaml) and those that piggyback off an existing ecosystem, runtime and standard library (F#, scala, clojure). It is clear that the second category has a substantial advantage for adoption. The runtimes are well established, reliable and fast. The standard libraries and package managers provide the best guarantee possible that I will not be left missing a critical component. There are downsides too. The integration between the functional programming syntax and underlying standard library are well designed but awkward. However, on balance the piggyback functional languages (F#, scala and clojure) provide a practical and valuable way to move to functional programming. &lt;/p&gt;
&lt;p&gt;For me F# has some distinct advantages. I think types are one of the most important tools we have for writing working software, so dynamic languages like clojure have less appeal. Having spent 10 years working with .net the CLR is more approachable to me than the JVM. Finally, scala displeases me aesthetically. &lt;/p&gt;
&lt;p&gt;Recently, &lt;a href=&quot;http://readify.net/&quot;&gt;my employer&lt;/a&gt; sponsored a professional development activity where &lt;a href=&quot;http://withouttheloop.com/articles/2014-01-14-fsharp-for-consulting-projects/&quot;&gt;I investigated the feasibility of applying functional programming to .net consulting projects&lt;/a&gt;. I found that it is practical, even simple, to partially or completely utilize functional programming via F# in this context. &lt;/p&gt;
&lt;h2 id=&quot;struggle&quot;&gt;Struggle&lt;/h2&gt;
&lt;p&gt;The last remaining awkward area was data access. I could not find a nice solution for data access from F#. Entity framework can be done, but involves a lot of compromise, essentially writing F# code in a C# style (the worst of both worlds). RavenDB seems like a good fit, which is why &lt;a href=&quot;http://ravendb.net/docs/1.0/client-api/fsharp&quot;&gt;many&lt;/a&gt; &lt;a href=&quot;http://colinbul.wordpress.com/2013/04/29/f-3-and-raven-db/&quot;&gt;have tried hard&lt;/a&gt; to make it work, but without support from the developers of RavenDB the result is disappointing. MongoDB may be web scale, but there &lt;a href=&quot;http://blog.mongodb.org/post/59584347005/enhancing-the-f-developer-experience-with-mongodb&quot;&gt;effort at supporting F#&lt;/a&gt; never made it out of alpha. &lt;/p&gt;
&lt;p&gt;What I wanted was a document database, with transactions, decent performance, simple querying and powerful indexes. I could not find one. &lt;/p&gt;
&lt;h2 id=&quot;resolution&quot;&gt;Resolution&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://www.postgresql.org/&quot;&gt;Postgresql&lt;/a&gt; is an &lt;a href=&quot;http://www.wekeroad.com/2012/07/19/postgresql-rising/&quot;&gt;amazing&lt;/a&gt; open-source relational database. It ain’t pretty but it is powerful. The latest version (9.3) includes &lt;a href=&quot;http://www.postgresql.org/&quot;&gt;comprehensive support for working with structures serialized as json&lt;/a&gt;. It is possible to project queries over json documents, to query based on values in json documents and to create indexes (including unique indexes) on values in json documents. Being a typical relational database transactions are obviously available. Postgresql has all the basic features I want in a document database. All it needs is a nice, F# friendly, API.&lt;/p&gt;
&lt;h2 id=&quot;postgresdoc&quot;&gt;PostgresDoc&lt;/h2&gt;
&lt;p&gt;For a long weekend project I built &lt;a href=&quot;https://github.com/liammclennan/PostgresDoc&quot;&gt;PostgresDoc, a new API on top of postgresql&lt;/a&gt; and &lt;a href=&quot;http://npgsql.projects.pgfoundry.org/&quot;&gt;npgsql&lt;/a&gt;. It simplifies the syntax, optimizes for document data and adds an explicit unit of work pattern. Here is the examples from the readme:&lt;/p&gt;
&lt;h2 id=&quot;unit-of-work-api&quot;&gt;Unit of Work API&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;type Person = 
    { _id: System.Guid; age: int; name: string }
    interface IDocument with
        member x.tableName() = &amp;quot;People&amp;quot;
        member x.id() = x._id

let store = { connString = &amp;quot;Server=127.0.0.1;Port=5432;User Id=postgres;Password=*****;Database=testo;&amp;quot; }

let julio = { _id = System.Guid.NewGuid(); age = 30; name = &amp;quot;Julio&amp;quot; }
let timmy = { _id = System.Guid.NewGuid(); age = 3; name = &amp;quot;Timmy&amp;quot; }

// list is backwards so operations can be consed
let uow = [ 
    Delete timmy
    Update { julio with age = 31 };
    Insert julio;
    Insert timmy;
    ]
commit store uow
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;document-api&quot;&gt;Document API&lt;/h2&gt;
&lt;h3 id=&quot;query&quot;&gt;Query&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;let peopleWhoAreThirty = 
    [ &amp;quot;age&amp;quot;, box (30) ] 
    |&amp;gt; Map.ofList
    |&amp;gt; query&amp;lt;Person&amp;gt; store &amp;quot;select data from people where data-&amp;gt;&amp;gt;&amp;#39;age&amp;#39; = :age&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The idea is that the unit of work is built up during execution by appending data operations (insert, update or delete). The example unit of work is really shorthand for:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let uow = Delete timmy :: Update { julio with age = 31 } :: InsertJulio :: [Insert timmy]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The unit of work is committed in a transaction (beat that mongodb). &lt;/p&gt;
&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;
&lt;p&gt;PostgresDoc is the document database that I wished I had. It provides a nice API for F# and seems to work!  &lt;/p&gt;
</description>
    </item>
    <item>
      <title>State Machines in F# and C#</title>
      <link>http://withouttheloop.com/articles/2014-04-18-fsharp-csharp-statemachines/</link>
      <pubDate>Fri, 18 Apr 2014 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2014-04-18-fsharp-csharp-statemachines/</guid>
      <author></author>
      <description>&lt;p&gt;A couple of months ago I wrote a &lt;a href=&quot;https://gist.github.com/liammclennan/8949046&quot;&gt;simple library for building state machines in C#&lt;/a&gt;. It allows a programmer to attach a state machine to a type and control:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the set of states that the type may have&lt;/li&gt;
&lt;li&gt;the transitions between those states&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The first system that used the library contained functionality for managing the lifecycle of contracts. The contracts begin in a draft state, they may then move to an approved state, and finally they may enter the historical state. They cannot go from draft to historical, from approved to draft, from historical to draft etc. Using the state machine added a valuable invariant guarantee to the code. &lt;/p&gt;
&lt;p&gt;As much as my state machine library was a successful solution to a problem I can’t help but realise that this problem simply doesn’t exist in F#. F#’s type system is sufficiently advanced so that it can represent state machines as part of the type. This meets the stated goal of my C# state machine library. To use the previous contracts example, the F# type would look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type Particulars = { buyer: string; seller: string }

type Contract = 
    private
    | Draft of Particulars
    | Approved of (Particulars * DateTime)
    | Historical of (Particulars * DateTime)

let createDraft particulars = 
    Draft particulars

let approve timestamp = function
    | Draft p -&amp;gt; Approved (p, timestamp)
    | _ -&amp;gt; failwith &amp;quot;Invalid transition&amp;quot;

let retire timestamp = function 
    | Approved (p,t) -&amp;gt; Historical (p, timestamp)
    | _ -&amp;gt; failwith &amp;quot;Invalid transition&amp;quot;

// usage
let contract = createDraft { buyer = &amp;quot;Acme&amp;quot;; seller = &amp;quot;Initech&amp;quot; }
let approved = approve DateTime.Now contract
let retired = retire DateTime.Now approved
retired |&amp;gt; printfn &amp;quot;%+A&amp;quot;

// output = Historical ({buyer = &amp;quot;Acme&amp;quot;; seller = &amp;quot;Initech&amp;quot;;}, 
//                          18/04/2014 1:27:20 PM)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The type system models the relationship between Contract and each of the possible states (a Contract is a draft, or approved or historical) as well as the data attached to each state (a draft doesn’t have a timestamp).&lt;/p&gt;
</description>
    </item>
    <item>
      <title>wurl - A much improved web based HTTP client</title>
      <link>http://withouttheloop.com/articles/2014-03-11-wurl/</link>
      <pubDate>Tue, 11 Mar 2014 07:00:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2014-03-11-wurl/</guid>
      <author></author>
      <description>&lt;p&gt;Previously I wrote about &lt;a href=&quot;http://withouttheloop.com/articles/2014-02-09-aristotle/&quot;&gt;Aristotle&lt;/a&gt;, my attempt at a usable http test client in the browser. Over the last two months Aristotle has been renamed &lt;a href=&quot;http://wurl.azurewebsites.net&quot;&gt;wurl&lt;/a&gt;, received a much improved user interface and many new features.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;wurl.PNG&quot; alt=&quot;wurl user interface&quot;/&gt;&lt;/p&gt;
&lt;p&gt;Here is the short list of improvements:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;new fullscreen tabbed layout&lt;/li&gt;
&lt;li&gt;support for endpoints that don’t support CORS&lt;/li&gt;
&lt;li&gt;realtime filtering of results&lt;/li&gt;
&lt;li&gt;realtime rendering of views&lt;/li&gt;
&lt;li&gt;save templates&lt;/li&gt;
&lt;li&gt;request a template by url (&lt;a href=&quot;http://wurl.azurewebsites.net/request?url=https://api.github.com/users/neovim/repos&quot;&gt;http://wurl.azurewebsites.net/request?url=https://api.github.com/users/neovim/repos&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;request.PNG&quot; alt=&quot;wurl user interface&quot;/&gt;&lt;/p&gt;
&lt;h2 id=&quot;what-s-missing&quot;&gt;What’s Missing&lt;/h2&gt;
&lt;p&gt;wurl is optimised for what I need most, which is querying json apis. Some things not yet implemented are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;support for xml responses&lt;/li&gt;
&lt;li&gt;identifying and linking urls in responses so that an api can be navigated&lt;/li&gt;
&lt;li&gt;more advanced non-cors requests&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    <item>
      <title>Aristotle - A web based HTTP client</title>
      <link>http://withouttheloop.com/articles/2014-02-09-aristotle/</link>
      <pubDate>Sun, 09 Feb 2014 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2014-02-09-aristotle/</guid>
      <author></author>
      <description>&lt;p&gt;Working with HTTP APIs I have found that there is a lack of GUI tooling to experiment and test requests. APIs are often documented as cURL commands, which is great, but cURL is a poor interface for experimenting. For example, if I want to post a document via cURL, I need to do something like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl -vX POST https://api.github.com/users/liammclennan/repos 
    -H &amp;quot;content-type: application/json&amp;quot; -d &amp;#39;{&amp;quot;whatever&amp;quot;: &amp;quot;value&amp;quot;}&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;There are many options for testing HTTP APIs. Here some that I have tried.&lt;/p&gt;
&lt;h2 id=&quot;postman&quot;&gt;Postman&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://chrome.google.com/webstore/detail/postman-rest-client/fdmmgilgnpjigdojojpjoooidkmcomcm?hl=en&quot;&gt;Postman&lt;/a&gt; is a chrome app. It is good for crafting HTTP requests. One nice feature is that it records all of the requests, so it is easy to reply past requests. I don’t like that postman requires me to sign in to my google account to install it. Also, I have mostly stopped using Chrome for similar reasons.&lt;/p&gt;
&lt;h2 id=&quot;fiddler&quot;&gt;Fiddler&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://www.telerik.com/download/fiddler&quot;&gt;Fiddler&lt;/a&gt; is a windows GUI proxy that provides the ability to execute arbitrary HTTP requests. &lt;/p&gt;
&lt;h1 id=&quot;aristotle&quot;&gt;Aristotle&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;http://aristotle.onashirt.net/&quot;&gt;Aristotle&lt;/a&gt; exists because I want a HTTP client with the following features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;easily execute a wide range of HTTP requests&lt;/li&gt;
&lt;li&gt;save and restore requests&lt;/li&gt;
&lt;li&gt;nicely format the response headers and body&lt;/li&gt;
&lt;li&gt;transform the response body and render views of the data&lt;/li&gt;
&lt;li&gt;cross-platform&lt;/li&gt;
&lt;li&gt;make requests to non-CORS-enabled APIs&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After stuffing around for some time trying to design a nice interface for describing requests I realized that only developers need to experiment with HTTP APIs and therefore it is OK to require a bit of code to define the request, and jquery already has an API for defining a request that lots of developers are already familiar with. Therefore, when using Aristotle you define a request by calling $.ajax. The only actual requirement is to specify an expression that returns a jquery style promise that will be resolved with the right arguments. Here is one of the example requests templates used by Aristotle:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$.ajax({
    type: &amp;#39;GET&amp;#39;,
    url: &amp;#39;https://api.github.com/users/liammclennan/repos&amp;#39;,
    dataType: &amp;#39;json&amp;#39;
});
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Any request that can be specified as a call to $.ajax will work. Aristotle will then display the response headers and the response body as syntax highlighted json. &lt;/p&gt;
&lt;p&gt;But wait, there’s more.&lt;/p&gt;
&lt;p&gt;Often I am making requests to CouchDB and the results are difficult to interpret because there is too much data and json is not that easy to read. To solve this problem Aristotle allows you to define views. Corresponding to the above request to the github API Aristotle has a template to render the expected response. The code is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;%
// manipulate the data some
var mapped = data.map(function (repo) {
   return repo.name;
   });   
%&amp;gt;

&amp;lt;!-- define a template --&amp;gt;
&amp;lt;ul&amp;gt;
    &amp;lt;% mapped.forEach(function(name) {%&amp;gt;
        &amp;lt;li&amp;gt;&amp;lt;%=name%&amp;gt;&amp;lt;/li&amp;gt;
    &amp;lt;% }) %&amp;gt;
&amp;lt;/ul&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It firstly maps the response data to something more useful for the view and then uses an underscore template (similar to ejs) to render a list of my github repos. The output is&lt;/p&gt;
&lt;ul&gt;

      &lt;li&gt;angularserver&lt;/li&gt;

            &lt;li&gt;author-quiz&lt;/li&gt;

                  &lt;li&gt;backbone-basics&lt;/li&gt;

                        &lt;li&gt;browsertest&lt;/li&gt;

                              &lt;li&gt;Builder&lt;/li&gt;

                                    &lt;li&gt;coffeescript-course&lt;/li&gt;

                                          &lt;li&gt;coffeescript-game-of-life&lt;/li&gt;

                                                &lt;li&gt;coffeescript-koans&lt;/li&gt;

                                                      &lt;li&gt;couchpotato&lt;/li&gt;

                                                            &lt;li&gt;dbc&lt;/li&gt;

                                                                  &lt;li&gt;dddbrisbane13-fsharp&lt;/li&gt;

                                                                        &lt;li&gt;dddbrisbane2012&lt;/li&gt;

                                                                              &lt;li&gt;designbycontract&lt;/li&gt;

                                                                                    &lt;li&gt;dotfiles&lt;/li&gt;

                                                                                          &lt;li&gt;eclipsewebsolutions.com.au&lt;/li&gt;

                                                                                                &lt;li&gt;functional-game-of-life&lt;/li&gt;

                                                                                                      &lt;li&gt;gistblog&lt;/li&gt;

                                                                                                            &lt;li&gt;git-deploy&lt;/li&gt;

                                                                                                                  &lt;li&gt;giv.n&lt;/li&gt;

                                                                                                                        &lt;li&gt;googleajaxurls&lt;/li&gt;

                                                                                                                              &lt;li&gt;haskell-notes&lt;/li&gt;

                                                                                                                                    &lt;li&gt;Herald&lt;/li&gt;

                                                                                                                                          &lt;li&gt;JavaScript-Koans&lt;/li&gt;

                                                                                                                                                &lt;li&gt;JsBdd&lt;/li&gt;

                                                                                                                                                      &lt;li&gt;KeyRef&lt;/li&gt;

                                                                                                                                                            &lt;li&gt;Liam-s-Presentations&lt;/li&gt;

                                                                                                                                                                  &lt;li&gt;listagram_build&lt;/li&gt;

                                                                                                                                                                        &lt;li&gt;mobile-dev&lt;/li&gt;

                                                                                                                                                                              &lt;li&gt;node-test&lt;/li&gt;

                                                                                                                                                                                    &lt;li&gt;onashirt&lt;/li&gt;

                                                                                                                                                                                      &lt;/ul&gt;

&lt;p&gt;Substitute any github user name in the url to get a list of that user’s github repositories. &lt;/p&gt;
&lt;h2 id=&quot;what-s-missing&quot;&gt;What’s Missing&lt;/h2&gt;
&lt;p&gt;Most things are missing. Proper error handling is missing. Saving requests is missing. Support for non-cors-enabled APIs is missing. Support for non-json responses is missing. A large selection of useful request templates is missing. &lt;/p&gt;
&lt;p&gt;I plan to keep working on Aristotle - mostly because it is a tool that I want to use. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>Applying Functional Programming to .net Consulting Projects</title>
      <link>http://withouttheloop.com/articles/2014-01-14-fsharp-for-consulting-projects/</link>
      <pubDate>Tue, 14 Jan 2014 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2014-01-14-fsharp-for-consulting-projects/</guid>
      <author></author>
      <description>&lt;p&gt;The benefits of &lt;a href=&quot;http://en.wikipedia.org/wiki/Functional_programming&quot;&gt;functional programming&lt;/a&gt; are &lt;a href=&quot;http://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf&quot;&gt;well known&lt;/a&gt;, and &lt;a href=&quot;http://callvirt.net/blog/post/Why-F-%28TechEd-09-DEV450%29.aspx&quot;&gt;well documented&lt;/a&gt;. The rest of this article will assume that this argument has been digested and accepted.  Given the benefits of functional programming the relatively low adoption can be attributed to general resistance to change, the front-loaded learning curve, a degree of complacency, and uncertainty about how to accomplish common programming tasks with a functional toolset. This article focuses on the latter, particularly in the context of .net consulting projects.&lt;/p&gt;
&lt;h2 id=&quot;functional-programming-for-the-net-programmer&quot;&gt;Functional Programming for the .net Programmer&lt;/h2&gt;
&lt;p&gt;A common fallacy is that we can achieve the benefits of functional programming by applying a functional style within a procedural language. Immutability is essential to functional programming and procedural languages, such as c#, do not encourage or support immutability. Whilst a functional style of c# programming is certainly an improvement we must not pretend that it is a reasonable substitute for a proper functional programming language. For the programmer working with .net tools in the .net ecosystem F# is the obvious prime candidate for a functional programming language. It is the only first-class, functional-first .net language.&lt;/p&gt;
&lt;p&gt;Some project managers worry that embracing a functional programming language will cause hiring difficulty. This fallacy possibly occurs because the push for functional programming generally comes from the programmers themselves. Non-programmers associated with software projects have little visibility into the rise and popularity of functional programming. Here in Brisbane the &lt;a href=&quot;http://www.meetup.com/Brisbane-Functional-Programming-Group/&quot;&gt;local functional programming user group&lt;/a&gt; has 484 members. Each year Brisbane hosts a &lt;a href=&quot;http://www.yowconference.com.au/lambdajam/&quot;&gt;well attended conference&lt;/a&gt; dedicated to functional programming. The amount of functional programming talent available for hire is underestimated. &lt;/p&gt;
&lt;p&gt;Finally, the notion of sticking to tools that make hiring easier contradicts the ‘right tool for the job’ directive that we should strive for. If the majority of unemployed programmers were assembler experts would you chose assembler for your next project?&lt;/p&gt;
&lt;h2 id=&quot;mixed-solutions&quot;&gt;Mixed Solutions&lt;/h2&gt;
&lt;p&gt;An important tool when introducing F# to a project is the ability to include F# and other .net languages within the same application. This reduces risk considerably because we retain the ability to fall back to another .net language (usually c#) in the event that F# is deemed to be unsuitable for a particular purpose. The reality is that this is not likely to ever be necessary - still there is value in reducing the perception of risk. &lt;/p&gt;
&lt;p&gt;A solution will be simpler, and more cohesive, if F# is used exclusively, however .net supports mixed solutions by allowing different projects to use different languages, and by supporting interoperability in both directions. &lt;/p&gt;
&lt;h2 id=&quot;interoperability-between-f-and-c-&quot;&gt;Interoperability Between F# and C#&lt;/h2&gt;
&lt;p&gt;Calling from F# into c# is a simple matter of using c# style syntax. &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;new RiakObjectId(&amp;quot;logs&amp;quot;, kvp.Key)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note the use of the new keyword to create an object, paranthesis to delimit method arguments, and commas to separate method arguments. &lt;/p&gt;
&lt;p&gt;Calling from c# into F# is similarly straightforward. F# functions appear in c# as static methods on static classes that map to the F# modules. The following F# and c# code are equivalent:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;open Data
nowToTodayString DateTime.Now

Data.nowToTodayString(DateTime.Now)
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;f-for-web-applications&quot;&gt;F# for Web Applications&lt;/h2&gt;
&lt;p&gt;F# is unfortunately not currently treated as a first-class .net language by visual studio. There is no built-in template for creating a web or desktop application with F#. The only supported scenarios are library and command line projects. In the absense of built-in templates the community has provided some excellent templates for a wide variety of scenarios.&lt;/p&gt;
&lt;p&gt;The visual studio online project templates include an excellent template called &lt;a href=&quot;http://visualstudiogallery.msdn.microsoft.com/3d2bf938-fc9e-403c-90b3-8de27dc23095&quot;&gt;F# and C# Web Application template&lt;/a&gt;. It creates a minimal c# web project and an auxillary F# library containing as much of the code as possible, including the controllers, view models, and application instance. The only application code required to be implemented within the c# web application project is the views. The case study discussed later is built on this template.&lt;/p&gt;
&lt;h2 id=&quot;f-for-windows-services&quot;&gt;F# for Windows Services&lt;/h2&gt;
&lt;p&gt;Despite there being no built-in template for F# windows services, F# is well suited to this task. The Visual C# Windows Service project actually does very little so it is trivial to manually implement an F# service, as described in the MSDN article &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/vstudio/hh297113%28v=vs.100%29.aspx#gff&quot;&gt;Creating Windows Services in F#&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Implementing a service only requires a &lt;code&gt;ServiceBase&lt;/code&gt; implementation and a service &lt;code&gt;Installer&lt;/code&gt; implementation. &lt;/p&gt;
&lt;h2 id=&quot;f-tooling-support&quot;&gt;F# Tooling Support&lt;/h2&gt;
&lt;p&gt;F# tooling support is minimal, compared to c# and VB.NET. As mentioned previously there is a shortage of built-in project templates, but this is easily rectified by the online, community contributed templates. Many .net technologies, such as asp.net and WPF, do not explicitly support F#, meaning that the F# programmer has some extra work to do. Also, third party productivity tools, such as ReSharper, typically do not support F#. When our productivity tools become a contributing factor for foundational technology decisions it is time to question, “have we lost control?”.&lt;/p&gt;
&lt;h2 id=&quot;f-data-access&quot;&gt;F# Data Access&lt;/h2&gt;
&lt;p&gt;Most data access methods assume mutability, which negates some of the benefits of FP. The exceptions are the explicity immutable data stores, such as &lt;a href=&quot;http://www.datomic.com/&quot;&gt;Datomic&lt;/a&gt; and &lt;a href=&quot;http://geteventstore.com/&quot;&gt;Event Store&lt;/a&gt; and the http based datastores like &lt;a href=&quot;http://couchdb.apache.org/&quot;&gt;CouchDB&lt;/a&gt; and &lt;a href=&quot;http://basho.com/riak/&quot;&gt;Riak&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;The case study included with this article uses Riak for its data store. F# has no direct support for Riak, however, it is trivial to use the &lt;a href=&quot;http://corrugatediron.org/&quot;&gt;CorrugatedIron&lt;/a&gt; client (written in c#) to communicate with Riak. All of the aforementioned data stores provide an HTTP interface, so a specialized client is not strictly necessary. &lt;/p&gt;
&lt;h2 id=&quot;case-study-logging-you&quot;&gt;Case Study - Logging You&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;screen.png&quot; alt=&quot;Logging You - A data driven web application written in F#&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://loggingyou.azurewebsites.net/&quot;&gt;Logging You&lt;/a&gt; is a bad demonstration of F#’s advantages. It includes none of F#’s core competency (computation) and lots of F#’s weaker areas (interop, GUI programming, transactional data access). Indeed the purpose of this case study is to investigate the feasibility of F# as a standard tool for .net consultants, therefore the important question to answer is, “how well does it handle those weaker areas?”.&lt;/p&gt;
&lt;p&gt;Logging you is a log dashboard built as an asp.net mvc web application. It’s two use cases are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;display a summary of the currently stored logs. This includes the alltime total count of logs, the count of today’s logs, and the list of today’s log messages.&lt;/li&gt;
&lt;li&gt;allow the user to enter a new informational log message&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These simple requirements forced the development of mvc integration, data queries and mvc model binding. F# handled all of these non-ideal (for a functional programming language) tasks with aplomb. Being a standard asp.net website Logging You is hosted on Azure without any special modifications. The &lt;a href=&quot;https://bitbucket.org/liammclennan/loggingyou&quot;&gt;source&lt;/a&gt; is available on bitbucket. &lt;/p&gt;
&lt;h2 id=&quot;find-out-more&quot;&gt;Find Out More&lt;/h2&gt;
&lt;p&gt;If you are interested in learning more about applied functional programming in .net, here are some helpful resources:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://fsharpforfunandprofit.com/why-use-fsharp/&quot;&gt;FSharp for Fun and Profit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://fsharp.org/&quot;&gt;The F# Software Foundation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.tryfsharp.org/&quot;&gt;Try F#&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    <item>
      <title>F# String Calculator</title>
      <link>http://withouttheloop.com/articles/2013-11-07-fsharp-stringcalc/</link>
      <pubDate>Thu, 07 Nov 2013 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2013-11-07-fsharp-stringcalc/</guid>
      <author></author>
      <description>&lt;p&gt;I’ve done the &lt;a href=&quot;http://osherove.com/tdd-kata-1/&quot;&gt;string calculator kata&lt;/a&gt; before, most recently &lt;a href=&quot;http://withouttheloop.com/articles/2013-05-31-stringcalckata/&quot;&gt;in Haskell&lt;/a&gt;. Here it is again in F#:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let lToS (l:char list) = System.String.Concat(Array.ofList(l))

let sumString =
    let parse (l:string) =
        let guessDelimeter (l:string) =
            match Seq.toList l with
                | &amp;#39;/&amp;#39;::&amp;#39;/&amp;#39;::c::&amp;#39;\n&amp;#39;::_ -&amp;gt; c
                | _ -&amp;gt; Seq.find (fun i -&amp;gt; i = &amp;#39;,&amp;#39; || i = &amp;#39;\n&amp;#39;) l
        let valuePart = (fun (s:string) -&amp;gt;
            match Seq.toList s with
                | &amp;#39;/&amp;#39;::&amp;#39;/&amp;#39;::c::&amp;#39;\n&amp;#39;::r -&amp;gt; r
                | v -&amp;gt; v) &amp;gt;&amp;gt; lToS
        Array.map int ((valuePart l).Split(guessDelimeter l))
    (parse &amp;gt;&amp;gt; Array.fold (fun acc i -&amp;gt; acc + i ) 0)

 sumString &amp;quot;3,9,11&amp;quot; |&amp;gt; printfn &amp;quot;%d&amp;quot;
 sumString &amp;quot;3\n9\n11&amp;quot; |&amp;gt; printfn &amp;quot;%d&amp;quot;
 sumString &amp;quot;//;\n3;9;11&amp;quot; |&amp;gt; printfn &amp;quot;%d&amp;quot;
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>Are we doing MVC wrong?</title>
      <link>http://withouttheloop.com/articles/2013-10-20-are-we-doing-mvc-wrong/</link>
      <pubDate>Sun, 20 Oct 2013 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2013-10-20-are-we-doing-mvc-wrong/</guid>
      <author></author>
      <description>&lt;p&gt;The naive way to build user interfaces with the MVC pattern is to include the application’s logic in controller actions - effectively recreating &lt;a href=&quot;http://martinfowler.com/eaaCatalog/transactionScript.html&quot;&gt;transaction script&lt;/a&gt; that is: &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;organizes business logic by procedures where each procedure handles a single request from the presentation.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Recognising that this is bad, many &lt;a href=&quot;http://lostechies.com/jimmybogard/2013/07/17/how-we-do-mvc-4-years-later/&quot;&gt;smart people&lt;/a&gt; have thought about &lt;a href=&quot;http://paulstovell.com/blog/clean-aspnet-mvc-controllers&quot;&gt;how to do mvc better&lt;/a&gt;. A couple of things still bother me:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;What is the responsibility of the controller? They always seem to combine UI decisions (choosing a view, reading the request, http status codes, http redirects) with application logic.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The application itself has no interface. Controllers are a UI that consume the application, but there is no clear application boundary that defines what the application itself does.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To solve these problems I have started using a different technique for mvc. I will demonstrate by refactoring a typical controller.&lt;/p&gt;
&lt;h2 id=&quot;a-typical-controller&quot;&gt;A Typical Controller&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;public class LibraryController : Controller
{
    private readonly IBookRepository _bookRepository;
    private readonly IBorrowings _borrowings;
    private readonly IUsers _users;

    public LibraryController(IBookRepository bookRepository, IBorrowings borrowings, IUsers users)
    {
        _bookRepository = bookRepository;
        _borrowings = borrowings;
        _users = users;
    }

    public ActionResult Catalogue()
    {
        return View(_bookRepository.AllBooks());
    }

    public ActionResult Borrow(BookModel book)
    {
        var fullCatalogue = _bookRepository.AllBooks();
        var bookIsInCatalogue = fullCatalogue.Any(b =&amp;gt; b.ISBN == book.ISBN);
        if (!bookIsInCatalogue)
        {
            SetErrorFlash(&amp;quot;The selected book is not in the catalogue&amp;quot;);
            return RedirectToAction(&amp;quot;Catalogue&amp;quot;);
        }

        var borrowedBooks = _borrowings.BorrowedBooks();
        var bookIsOutOnLoan = borrowedBooks.Any(b =&amp;gt; b.ISBN == book.ISBN);
        if (bookIsOutOnLoan)
        {
            SetErrorFlash(&amp;quot;The selected book is currently out on loan&amp;quot;);
            return RedirectToAction(&amp;quot;Catalogue&amp;quot;);
        }

        var user = _users.GetAuthenticatedUser();
        var canBorrow = user.HasPermissionToBorrow();
        if (!canBorrow)
        {
            SetErrorFlash(&amp;quot;The selected book is currently out on loan&amp;quot;);
            return RedirectToAction(&amp;quot;Catalogue&amp;quot;);
        }

        var bookEntity = _bookRepository.GetByISBN(book.ISBN);
        var result = _borrowings.Borrow(bookEntity);

        if (result != null)
        {
            SetSuccessFlash(&amp;quot;Book borrowed&amp;quot;);
            return View(&amp;quot;Borrowed&amp;quot;, result);
        }
        else
        {
            return View(&amp;quot;BorrowFailed&amp;quot;);
        }
    }

    private void SetErrorFlash(string message) {}
    private void SetSuccessFlash(string message) {}
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;One problem here is that there is no differentiation between the user interface behaviour and the function provided by the application. Both are implemented in the controller, mixed together in the same method (&lt;code&gt;Borrow&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Another problem is that as the library functionality grows more dependencies will be added to the controller. Not all of the actions will use all of the dependencies, so cohesion is low, and coupling is high.&lt;/p&gt;
&lt;h2 id=&quot;application-feature-api&quot;&gt;Application Feature API&lt;/h2&gt;
&lt;p&gt;Instead of the above controller I prefer to make the features an application provides into a first class API. I model each feature as a class, so the logic in &lt;code&gt;Borrow&lt;/code&gt; action moves into a feature class called &lt;code&gt;BorrowABook&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The genesis of the ideas show here come from Uncle Bob’s presentation &lt;a href=&quot;http://www.youtube.com/watch?v=WpkDN78P884&quot;&gt;‘Architecture the Lost Years’&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class BorrowABook
{
    public enum BorrowABookOutcomes
    {
        NotInCatalogue,
        OutOnLoan,
        InsufficientPermission,
        BorrowFailed,
        BorrowSucceeded
    }

    public Feature&amp;lt;BorrowABookOutcomes,Book&amp;gt; Borrow(BookModel book)
    {
        // .. implement application logic
        return new Feature&amp;lt;BorrowABookOutcomes,Book&amp;gt;(BorrowABookOutcomes.BorrowSucceeded, borrowedBook);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Features return a glorified tuple (&lt;code&gt;Feature&amp;lt;TOutcome,TResult&amp;gt;&lt;/code&gt;) that combines an enum value that represents what the outcome was, with a value that represents the result of the operation. In this case I am returning the success outcome and the book that was borrowed. As the boundary of your application Features are an excellent target for behaviour tests. You can &lt;a href=&quot;https://gist.github.com/liammclennan/78ea542e2fc120bc643b&quot;&gt;test them without dealing with UI layer concerns&lt;/a&gt;.  &lt;/p&gt;
&lt;h2 id=&quot;simplified-controller&quot;&gt;Simplified Controller&lt;/h2&gt;
&lt;p&gt;Given a feature such as &lt;code&gt;BorrowABook&lt;/code&gt; the controller action simplifies to the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public ActionResult Borrow(BookModel book)
{
    var result = _feature.Borrow(book);
    switch (result.Outcome)
    {
        case BorrowABook.BorrowABookOutcomes.NotInCatalogue:
            {
                SetErrorFlash(&amp;quot;The selected book is not in the catalogue&amp;quot;);
                return RedirectToAction(&amp;quot;Catalogue&amp;quot;);
            }
        case BorrowABook.BorrowABookOutcomes.OutOnLoan:
            {
                SetErrorFlash(&amp;quot;The selected book is currently out on loan&amp;quot;);
                return RedirectToAction(&amp;quot;Catalogue&amp;quot;);
            }
        case BorrowABook.BorrowABookOutcomes.InsufficientPermission:
            {
                SetErrorFlash(&amp;quot;You do not have permission to borrow books&amp;quot;);
                return RedirectToAction(&amp;quot;Catalogue&amp;quot;);
            }
        case BorrowABook.BorrowABookOutcomes.BorrowFailed:
            {
                return View(&amp;quot;BorrowFailed&amp;quot;);
            }
        case BorrowABook.BorrowABookOutcomes.BorrowSucceeded:
            {
                SetSuccessFlash(&amp;quot;Book borrowed&amp;quot;);
                return View(&amp;quot;Borrowed&amp;quot;, result.Result);
            }
        default: throw new Exception(&amp;quot;Unknown result &amp;quot; + result.Outcome);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note that the application logic has all been removed. The controller action is reduced to the minimum required to implement the UI.&lt;/p&gt;
&lt;h2 id=&quot;update&quot;&gt;Update&lt;/h2&gt;
&lt;p&gt;Thanks to David Tchepak for providing &lt;a href=&quot;https://gist.github.com/dtchepak/7168143&quot;&gt;this F# version&lt;/a&gt; of the above example. Note that it is untested and meant simply as an example of what an F# version might look like.&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/dtchepak/7168143.js&quot;&gt;&lt;/script&gt;
</description>
    </item>
    <item>
      <title>dbc 2.0.0</title>
      <link>http://withouttheloop.com/articles/2013-08-24-dbc2/</link>
      <pubDate>Sat, 24  Aug 2013 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2013-08-24-dbc2/</guid>
      <author></author>
      <description>&lt;p&gt;Today I released a new version of my &lt;a href=&quot;https://rawgithub.com/liammclennan/dbc/master/docs/dbc.html&quot;&gt;JavaScript Design-by-Contract Library (dbc)&lt;/a&gt;. As well as documentation and other minor improvements the two big new features are:&lt;/p&gt;
&lt;h1 id=&quot;makeconstructor&quot;&gt;makeConstructor&lt;/h1&gt;
&lt;p&gt;MakeConstructor generates a constructor from a spec. The constructor validates that the created objects meet the spec. ie&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    var Person = dbc.MakeConstructor({
       name: [{validator:&amp;#39;type&amp;#39;,args:&amp;#39;string&amp;#39;}],
       age: [{validator:&amp;#39;type&amp;#39;,args:&amp;#39;number&amp;#39;}]
    });
    Person.prototype.canDrive = dbc.wrap(function () { 
         return this.age &amp;gt; 16;
    }, null, [{validator:&amp;#39;type&amp;#39;,args:&amp;#39;number&amp;#39;}]);
    var p = new Person(&amp;#39;John&amp;#39;, 22);
    p.canDrive(); // true 
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&quot;wrap&quot;&gt;wrap&lt;/h1&gt;
&lt;p&gt;Wrap returns a wrapped function that applies ‘specs’ validators to the functions arguments and ‘returnSpec’ validators to the return value. eg&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var add = dbc.wrap(function (f,s) { 
    return f + s;
}, {
    // validators for the first arg
    0: [{validator:&amp;#39;type&amp;#39;, args:[&amp;#39;number&amp;#39;]}],
    // validators for the second arg
    1:[{validator:&amp;#39;type&amp;#39;, args:[&amp;#39;number&amp;#39;]}]
},
    // validators for the return value 
    [{validator: &amp;#39;type&amp;#39;, args:[&amp;#39;number&amp;#39;]}]);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Dbc is available on &lt;a href=&quot;https://github.com/liammclennan/dbc&quot;&gt;github&lt;/a&gt; or via npm &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm install dbc
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>CoffeeScript Game of Life with Ristretto Type Annotations</title>
      <link>http://withouttheloop.com/articles/2013-08-11-coffeescript-gameoflife-ristretto/</link>
      <pubDate>Sun, 11  Aug 2013 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2013-08-11-coffeescript-gameoflife-ristretto/</guid>
      <author></author>
      <description>&lt;p&gt;This weekend at &lt;a href=&quot;http://campjs.com/&quot;&gt;campjs&lt;/a&gt; one of my projects has been porting my &lt;a href=&quot;http://withouttheloop.com/articles/2013-05-12-functional-game-of-life-3-haskell/&quot;&gt;Haskell Game of Life&lt;/a&gt; to CoffeeScript, with type annotations courtesy of &lt;a href=&quot;http://code.google.com/p/ristretto-js/&quot;&gt;Ristretto&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/liammclennan/coffeescript-game-of-life&quot;&gt;https://github.com/liammclennan/coffeescript-game-of-life&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;ristretto&quot;&gt;Ristretto&lt;/h2&gt;
&lt;p&gt;Given a function from string to int:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;number_of_chars = (s) -&amp;gt; s.length
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Ristretto can enfore the types given the following annotated version:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;number_of_chars = T &amp;#39;number_of_chars :: String -&amp;gt; Int&amp;#39;, (s) -&amp;gt;
    s.length
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The format of the type annotation will be familiar to Haskellers. Read &lt;code&gt;::&lt;/code&gt; as ‘has the type’. All types to the left of a -&amp;gt; are function arguments and the type to the right of the last -&amp;gt; is the return type. So the above function &lt;code&gt;number_of_chars&lt;/code&gt; has the type &lt;code&gt;String&lt;/code&gt; to &lt;code&gt;Int&lt;/code&gt;. &lt;/p&gt;
&lt;p&gt;Ristretto can also define data types. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;T &amp;#39;typedef Person :: { name: String, age: Int }&amp;#39;
class Person
    constructor: (@name, @age) -&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The JavaScript equivalent is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;T(&amp;#39;typedef Person :: { name: String, age: Int }&amp;#39;);
function Person(name,age) {
    this.name = name;
    this.age = age;
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;game-of-life&quot;&gt;Game of Life&lt;/h2&gt;
&lt;p&gt;Here is my Game of Life implementation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;require &amp;#39;coffee-script&amp;#39;
T = require &amp;#39;./ristrettoAssert&amp;#39;
_ = require &amp;#39;underscore&amp;#39;

# Define a type for a living cell
T &amp;#39;typedef Cell :: {x:Int, y:Int}&amp;#39;
class Cell
    constructor: (@x,@y) -&amp;gt;

# seed the initial living cells
r_pentomino = [new Cell(2, 1), new Cell(3, 1), new Cell(1,2), new Cell(2,2), new Cell(2,3)]

# determine if a coordinate (x,y) is a neighbour of a cell
is_neighbour = T(&amp;#39;is_neighbour :: Cell -&amp;gt; Int -&amp;gt; Int -&amp;gt; Bool&amp;#39;, (c, x, y) -&amp;gt;
    Math.abs(x-c.x) &amp;lt; 2 and Math.abs(y-c.y) &amp;lt; 2 and (not (x is c.x and y is c.y))
)

living_neighbours = T(&amp;#39;living_neighbours :: [Cell] -&amp;gt; Int -&amp;gt; Int -&amp;gt; Int&amp;#39;, (cs,x,y) -&amp;gt;
    (cell for cell in cs when is_neighbour cell, x, y).length
)

is_on = T(&amp;#39;is_on :: [Cell] -&amp;gt; Int -&amp;gt; Int -&amp;gt; Bool&amp;#39;, (cs,x,y) -&amp;gt;
    (cell for cell in cs when cell.x is x and cell.y is y).length &amp;gt; 0
)

largest_x = T &amp;#39;largest_x :: [Cell] -&amp;gt; Int&amp;#39;, (cs) -&amp;gt;
    _.max(cs, (i) -&amp;gt; i.x).x

largest_y = T &amp;#39;largest_y :: [Cell] -&amp;gt; Int&amp;#39;, (cs) -&amp;gt;
    _.max(cs, (i) -&amp;gt; i.y).y

alive_next_generation = T &amp;#39;alive_next_generation :: [Cell] -&amp;gt; Int -&amp;gt; Int -&amp;gt; Bool&amp;#39;, (cs,x,y) -&amp;gt;
    false
    (is_on(cs, x, y) and 2 &amp;lt;= living_neighbours(cs, x, y) &amp;lt;=3) or ((not is_on(cs, x, y)) and (living_neighbours(cs,x,y) is 3))

tick = T &amp;#39;tick :: [Cell] -&amp;gt; [Cell]&amp;#39;, (cs) -&amp;gt;
    ncs = []
    for x in [0..largest_x(cs)+1]
        for y in [0..largest_y(cs)+1]
            ncs.push(new Cell(x,y)) if alive_next_generation cs, x, y
    ncs

visualize = T &amp;#39;visualize :: [Cell] -&amp;gt; String&amp;#39;, (cs) -&amp;gt;
    result = &amp;#39;&amp;#39;
    for y in [0..largest_y(cs)+1]
        for x in [0..largest_x(cs)+1]
            result += if is_on(cs,x,y) then &amp;#39;x&amp;#39; else &amp;#39;-&amp;#39;
            if x is largest_x(cs)+1
                result += &amp;#39;\n&amp;#39;
    result

[1..50].reduce((p,c,i) -&amp;gt;
    console.log visualize p
    tick p
, r_pentomino)
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;thoughts&quot;&gt;Thoughts&lt;/h2&gt;
&lt;p&gt;While re-implementing game of life my experience was that ristretto frequently alerted me to type errors. Without Ristretto these errors would have manifested later in the program with a greater distance between the problem and the runtime error. &lt;/p&gt;
&lt;p&gt;Ristretto does not provide the full benefits of a static type checker. It is more like a type-based &lt;a href=&quot;http://en.wikipedia.org/wiki/Design_by_contract&quot;&gt;design-by-contract&lt;/a&gt; library. Personally, I have been frustrated by type errors in Javascript, which led me to implement a &lt;a href=&quot;https://github.com/liammclennan/dbc&quot;&gt;basic runtime type checker for JavaScript&lt;/a&gt;, but I think that Ristretto is a better and more logically consistent solution.&lt;/p&gt;
&lt;h2 id=&quot;output&quot;&gt;Output&lt;/h2&gt;
&lt;p&gt;The output of my CoffeeScript Game of Life for the first 50 generations takes 22s on my Chromebook and is printed below. To generate the full 1103 generations before this pattern stabilises will likely require a better algorithm. &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-----
--xx-
-xx--
--x--
-----

-----
-xxx-
-x---
-xx--
-----

--x--
-xx--
x--x-
-xx--
-----

-xx--
-xxx-
x--x-
-xx--
-----

-x-x-
x--x-
x--x-
-xx--
-----

--x---
xx-xx-
x--x--
-xx---
------

-xxx--
xx-xx-
x--xx-
-xx---
------

xx-xx-
x-----
x---x-
-xxx--
------

xx----
x--xx-
x-xx--
-xxx--
--x---
------

xx----
x--xx-
x-----
------
-xxx--
------

xx--
x---
----
-xx-
--x-
--x-
----

xx---
xx---
-x---
-xx--
--xx-
-----

xx---
--x--
-----
-x-x-
-xxx-
-----

-x---
-x---
--x--
-x-x-
-x-x-
--x--
-----

-----
-xx--
-xx--
-x-x-
-x-x-
--x--
-----

-----
-xx--
x--x-
xx-x-
-x-x-
--x--
-----

------
-xx---
x--x--
xx-xx-
xx-x--
--x---
------

------
-xx---
x--xx-
---xx-
x--xx-
-xx---
------

-------
-xxx---
-x--x--
--x--x-
-x--x--
-xxx---
-------

--x----
-xxx---
-x--x--
-xxxxx-
-x--x--
-xxx---
--x----
-------

-xxx---
-x-x---
x----x-
xx---x-
x----x-
-x-x---
-xxx---
-------

-x-x----
xx-xx---
x-x-x---
xx--xxx-
x-x-x---
xx-xx---
-x-x----
--x-----
--------

xx-xx-
x---x-
--x---
x-x-x-
--x---
x---x-
xx-xx-
--x---
------

xx-xx-
x-x-x-
------
--x---
------
x-x-x-
xxxxx-
-xxx--
------

xxxxx-
x-x-x-
-x-x--
------
-x-x--
x-x-x-
x---x-
x---x-
--x---
------

x-x-x--
x---x--
-xxx---
-------
-xxx---
x-x-x--
x---xx-
-x-x---
-------

-x-x---
x---x--
-xxx---
-------
-xxx---
x-x-xx-
x-x-xx-
----x--
-------

-------
x---x--
-xxx---
-------
-xxxx--
x----x-
-------
---xxx-
-------

-------
-xxx---
-xxx---
----x--
-xxxx--
-xxxx--
-----x-
----x--
----x--
-------

--x----
-x-x---
-x--x--
----x--
-x---x-
-x---x-
--x--x-
----xx-
-------

--x-----
-x-x----
--xxx---
----xx--
----xx--
-xx-xxx-
-----xx-
----xx--
--------

--x-----
-x--x---
--x--x--
--------
--------
---x----
---x----
----xxx-
--------

-------
-xxx---
-------
-------
-------
-------
---x-x-
----xx-
-----x-
-------

--x-----
--x-----
--x-----
--------
--------
--------
-----x--
-----xx-
----xx--
--------

--------
-xxx----
--------
--------
--------
--------
-----xx-
------x-
----xxx-
--------

--x------
--x------
--x------
---------
---------
---------
-----xx--
----x--x-
-----xx--
-----x---
---------

---------
-xxx-----
---------
---------
---------
---------
-----xx--
----x--x-
----xxx--
-----xx--
---------

--x------
--x------
--x------
---------
---------
---------
-----xx--
----x--x-
----x--x-
----x-x--
---------

---------
-xxx-----
---------
---------
---------
---------
-----xx--
----x--x-
---xx-xx-
-----x---
---------

--x------
--x------
--x------
---------
---------
---------
-----xx--
---xx--x-
---xx-xx-
----xxx--
---------

---------
-xxx-----
---------
---------
---------
---------
----xxx--
---x---x-
-------x-
---xx-xx-
-----x---
---------

--x-------
--x-------
--x-------
----------
----------
-----x----
----xxx---
----xx-x--
---xx--xx-
----xxxx--
----xxx---
----------

----------
-xxx------
----------
----------
----------
----xxx---
----------
-------xx-
---x----x-
--------x-
----x--x--
-----x----
----------

--x--------
--x--------
--x--------
-----------
-----x-----
-----x-----
-----xxx---
-------xx--
--------xx-
-------xx--
-----------

-----------
-xxx-------
-----------
-----------
-----------
----xx-----
-----x-xx--
---------x-
---------x-
-------xxx-
-----------

--x---------
--x---------
--x---------
------------
------------
----xxx-----
----xxx-x---
---------x--
---------xx-
--------xx--
--------x---
------------

------------
-xxx--------
------------
------------
-----x------
----x-xx----
----x-xx----
-----x--xxx-
----------x-
--------x-x-
--------xx--
------------

--x----------
--x----------
--x----------
-------------
-----xx------
----x--x-----
----x----x---
-----xxxxxx--
--------x-xx-
--------x-x--
--------xx---
-------------

-------------
-xxx---------
-------------
-------------
-----xx------
----x-x------
----x----xx--
-----xxx---x-
------x----x-
-------xx-xx-
--------xx---
-------------

--x-----------
--x-----------
--x-----------
--------------
-----xx-------
----x-x-------
----x--x--x---
-----xxx---x--
-----x--x--xx-
-------xx-xx--
-------xxxx---
--------------
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>Ubuntu Linux on the Samsung Chromebook</title>
      <link>http://withouttheloop.com/articles/2013-07-26-samsung-chromebook-ubuntu/</link>
      <pubDate>Fri, 26 Jul 2013 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2013-07-26-samsung-chromebook-ubuntu/</guid>
      <author></author>
      <description>&lt;p&gt;Are you looking for a cheap, poorly made, underpowered ultrabook? If yes, then the Samsung Chromebook is for you!&lt;/p&gt;
&lt;p&gt;It may be a bit slow, and it may be rough, but I love this thing. It is amazingly fast considering it has the processor from a 10” tablet. The 1366 x 768 display has a narrow viewing angle but is otherwise quite nice. The chromebook weighs 1.1kg and has a 6 hour battery life.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2013-07-26-samsung-chromebook-ubuntu/chromebook.jpg&quot; alt=&quot;Samsung Chromebook&quot;/&gt;&lt;/p&gt;
&lt;p&gt;The chromebook I like, and ChromeOS even grew on me somewhat, but I bought my chromebook to run Linux. &lt;/p&gt;
&lt;h2 id=&quot;converting-the-samsung-chromebook-to-ubuntu&quot;&gt;Converting the Samsung Chromebook to Ubuntu&lt;/h2&gt;
&lt;p&gt;First I tried Crouton, which is a side-by-side Ubuntu with ChromeOS, but the Ubuntu experience was third rate. I had better luck with &lt;a href=&quot;http://chromeos-cr48.blogspot.com.au/2013/05/chrubuntu-one-script-to-rule-them-all_31.html&quot;&gt;ChrUbuntu&lt;/a&gt;, which is an Ubuntu installer for Chromebooks. The default installation works well but I was left with some minor issues. &lt;/p&gt;
&lt;h3 id=&quot;fixing-the-trackpad&quot;&gt;Fixing the Trackpad&lt;/h3&gt;
&lt;p&gt;After installing ChrUbuntu the trackpad will be rubbish. It is not hard to &lt;a href=&quot;http://craigerrington.com/blog/fixing-touchpad-issues-on-arm-chromebook-chrubuntu/&quot;&gt;find a fix on the internet&lt;/a&gt;. After running that fix my trackpad worked great. In fact, it is one of the best trackpads I have used. &lt;/p&gt;
&lt;h3 id=&quot;fixing-bash&quot;&gt;Fixing Bash&lt;/h3&gt;
&lt;p&gt;The terminal was driving me nuts. The up arrow didn’t retrieve history and tab completion didn’t work. So I posted a question on the usually helpful &lt;a href=&quot;http://craigerrington.com/blog/fixing-touchpad-issues-on-arm-chromebook-chrubuntu/&quot;&gt;askubuntu&lt;/a&gt; where unfortunately my question was closed, because apparently ChrUbuntu is not an Ubuntu. &lt;/p&gt;
&lt;p&gt;Could have fooled me.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2013-07-26-samsung-chromebook-ubuntu/screen.png&quot; alt=&quot;Not Ubuntu&quot;/&gt;&lt;/p&gt;
&lt;p&gt;Anyway I &lt;a href=&quot;http://askubuntu.com/questions/165143/install-history-command-package&quot;&gt;found the solution myself&lt;/a&gt;. The problem is that ChrUbuntu doesn’t use bash for the terminal. So install bash:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo apt-get install bash
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;then set bash as the default terminal:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;chsh -s /bin/bash
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Enjoy.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>dbc type assertion library</title>
      <link>http://withouttheloop.com/articles/2013-07-16-dbcupdate/</link>
      <pubDate>Tue, 16 Jul 2013 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2013-07-16-dbcupdate/</guid>
      <author></author>
      <description>&lt;p&gt;Today I updated my javascript dbc assertion library. I wanted to be able to guarantee that javascript objects match certain type constraints. Imagine a backbone view:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; View = Backbone.View.extend({

    &lt;span class=&quot;attr&quot;&gt;render&lt;/span&gt;: &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; (&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.$el.html(&lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.model.get(&lt;span class=&quot;string&quot;&gt;'a'&lt;/span&gt;) + &lt;span class=&quot;string&quot;&gt;' '&lt;/span&gt; + &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.model.get(&lt;span class=&quot;string&quot;&gt;'b'&lt;/span&gt;));
    }

});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can see from inspection that this view will fail to render if its model does not have an &lt;code&gt;a&lt;/code&gt; and a &lt;code&gt;b&lt;/code&gt; property. &lt;code&gt;dbc&lt;/code&gt; can improve this as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; View = Backbone.View.extend({
    &lt;span class=&quot;attr&quot;&gt;initialize&lt;/span&gt;: &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; (&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
        dbc.check(&lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.model.toJSON(), {
            &lt;span class=&quot;attr&quot;&gt;a&lt;/span&gt;: [{&lt;span class=&quot;attr&quot;&gt;validator&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'required'&lt;/span&gt;}],
            &lt;span class=&quot;attr&quot;&gt;b&lt;/span&gt;: [{&lt;span class=&quot;attr&quot;&gt;validator&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'required'&lt;/span&gt;}]
        });
    },
    &lt;span class=&quot;attr&quot;&gt;render&lt;/span&gt;: &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; (&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.$el.html(&lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.model.get(&lt;span class=&quot;string&quot;&gt;'a'&lt;/span&gt;) + &lt;span class=&quot;string&quot;&gt;' '&lt;/span&gt; + &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.model.get(&lt;span class=&quot;string&quot;&gt;'b'&lt;/span&gt;));
    }
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It will still fail, but now it will fail when the view is created, and it will be obvious that the failure was caused by bad data. &lt;/p&gt;
&lt;h1 id=&quot;the-readme&quot;&gt;The Readme&lt;/h1&gt;
&lt;p&gt;&lt;code&gt;dbc&lt;/code&gt; is a small library for design-by-contract defensive coding in javascript. &lt;/p&gt;
&lt;p&gt;It focuses especially on type assertions in an attempt to provide a small compensation for JavaScript’s unfortunate dynamicness.&lt;/p&gt;
&lt;p&gt;Have a function that requires a numeric argument? Try:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; (&lt;span class=&quot;params&quot;&gt;num&lt;/span&gt;) &lt;/span&gt;{
    dbc.type(num, &lt;span class=&quot;string&quot;&gt;'number'&lt;/span&gt;);
    &lt;span class=&quot;comment&quot;&gt;// the rest of your function&lt;/span&gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or if the function argument is an object, and you want to collect the validation results:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; (&lt;span class=&quot;params&quot;&gt;myComplexObject&lt;/span&gt;) &lt;/span&gt;{
    &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; messages = dbc.validate(myComplexObject, {
        &lt;span class=&quot;attr&quot;&gt;firstProp&lt;/span&gt;: [{&lt;span class=&quot;attr&quot;&gt;validator&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'required'&lt;/span&gt;}]
    });
    &lt;span class=&quot;comment&quot;&gt;// the rest of your function&lt;/span&gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;features&quot;&gt;Features&lt;/h2&gt;
&lt;p&gt;Check a value:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;    dbc.type(&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'number'&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'optional error message'&lt;/span&gt;);
    dbc.isFunction(&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; (&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{}, &lt;span class=&quot;string&quot;&gt;'optional error message'&lt;/span&gt;);
    dbc.functionArity(&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; (&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{}, &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;'optional error message'&lt;/span&gt;);
    &lt;span class=&quot;comment&quot;&gt;// etc&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Check an object:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;    dbc.check({
        &lt;span class=&quot;attr&quot;&gt;a&lt;/span&gt;: &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;,
        &lt;span class=&quot;attr&quot;&gt;b&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;cat in the hat&quot;&lt;/span&gt;,
        &lt;span class=&quot;attr&quot;&gt;c&lt;/span&gt;: &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; (&lt;span class=&quot;params&quot;&gt;f, s&lt;/span&gt;) &lt;/span&gt;{ &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; f + s; }
    }, {
        &lt;span class=&quot;attr&quot;&gt;a&lt;/span&gt;: [
            {&lt;span class=&quot;attr&quot;&gt;validator&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'required'&lt;/span&gt;, &lt;span class=&quot;attr&quot;&gt;args&lt;/span&gt;: [&lt;span class=&quot;string&quot;&gt;'optional error message'&lt;/span&gt;]}, 
            {&lt;span class=&quot;attr&quot;&gt;validator&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'type'&lt;/span&gt;, &lt;span class=&quot;attr&quot;&gt;args&lt;/span&gt;: [&lt;span class=&quot;string&quot;&gt;'number'&lt;/span&gt;]}, 
            {&lt;span class=&quot;attr&quot;&gt;validator&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'custom'&lt;/span&gt;, &lt;span class=&quot;attr&quot;&gt;args&lt;/span&gt;: [ &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; (&lt;span class=&quot;params&quot;&gt;v&lt;/span&gt;) &lt;/span&gt;{ 
                &lt;span class=&quot;comment&quot;&gt;// custom validator function should return a boolean&lt;/span&gt;
                &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; v &amp;gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;; 
            }]}
        ],
        &lt;span class=&quot;attr&quot;&gt;b&lt;/span&gt;: [{&lt;span class=&quot;attr&quot;&gt;validator&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'type'&lt;/span&gt;, &lt;span class=&quot;attr&quot;&gt;args&lt;/span&gt;: [&lt;span class=&quot;string&quot;&gt;'string'&lt;/span&gt;]}],
        &lt;span class=&quot;attr&quot;&gt;c&lt;/span&gt;: [{&lt;span class=&quot;attr&quot;&gt;validator&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'isFunction'&lt;/span&gt;}, {&lt;span class=&quot;attr&quot;&gt;validator&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'functionArity'&lt;/span&gt;, &lt;span class=&quot;attr&quot;&gt;args&lt;/span&gt;: [&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;, {&lt;span class=&quot;attr&quot;&gt;message&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'This is a more advanced error object'&lt;/span&gt;, &lt;span class=&quot;attr&quot;&gt;field&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'c'&lt;/span&gt;}]}]
    });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Validate an object (same as check except that it returns an array of errors instead of throwing an exception at the first error):&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-javascript&quot;&gt;    dbc.validate({
        &lt;span class=&quot;attr&quot;&gt;a&lt;/span&gt;: &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;,
        &lt;span class=&quot;attr&quot;&gt;b&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;cat in the hat&quot;&lt;/span&gt;,
        &lt;span class=&quot;attr&quot;&gt;c&lt;/span&gt;: &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; (&lt;span class=&quot;params&quot;&gt;f, s&lt;/span&gt;) &lt;/span&gt;{ &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; f + s; }
    }, {
        &lt;span class=&quot;attr&quot;&gt;a&lt;/span&gt;: [
            {&lt;span class=&quot;attr&quot;&gt;validator&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'required'&lt;/span&gt;, &lt;span class=&quot;attr&quot;&gt;args&lt;/span&gt;: [&lt;span class=&quot;string&quot;&gt;'optional error message'&lt;/span&gt;]}, 
            {&lt;span class=&quot;attr&quot;&gt;validator&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'type'&lt;/span&gt;, &lt;span class=&quot;attr&quot;&gt;args&lt;/span&gt;: [&lt;span class=&quot;string&quot;&gt;'number'&lt;/span&gt;]}, 
            {&lt;span class=&quot;attr&quot;&gt;validator&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'custom'&lt;/span&gt;, &lt;span class=&quot;attr&quot;&gt;args&lt;/span&gt;: [ &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; (&lt;span class=&quot;params&quot;&gt;v&lt;/span&gt;) &lt;/span&gt;{ 
                &lt;span class=&quot;comment&quot;&gt;// custom validator function should return a boolean&lt;/span&gt;
                &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; v &amp;gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;; 
            }]}
        ],
        &lt;span class=&quot;attr&quot;&gt;b&lt;/span&gt;: [{&lt;span class=&quot;attr&quot;&gt;validator&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'type'&lt;/span&gt;, &lt;span class=&quot;attr&quot;&gt;args&lt;/span&gt;: [&lt;span class=&quot;string&quot;&gt;'string'&lt;/span&gt;]}],
        &lt;span class=&quot;attr&quot;&gt;c&lt;/span&gt;: [{&lt;span class=&quot;attr&quot;&gt;validator&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'isFunction'&lt;/span&gt;}, {&lt;span class=&quot;attr&quot;&gt;validator&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'functionArity'&lt;/span&gt;, &lt;span class=&quot;attr&quot;&gt;args&lt;/span&gt;: [&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;, {&lt;span class=&quot;attr&quot;&gt;message&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'This is a more advanced error object'&lt;/span&gt;, &lt;span class=&quot;attr&quot;&gt;field&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'c'&lt;/span&gt;}]}]
    });
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;test&quot;&gt;Test&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;npm install -g jasmine-node
jasmine-node --coffee spec/
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>Resourceserver as a backend for SPA and Backbone apps</title>
      <link>http://withouttheloop.com/articles/2013-07-15-resourceserverbackbone/</link>
      <pubDate>Mon, 15 Jul 2013 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2013-07-15-resourceserverbackbone/</guid>
      <author></author>
      <description>&lt;p&gt;Some &lt;a href=&quot;http://www.reddit.com/r/javascript/comments/1i9rc5/http_resource_server/&quot;&gt;reddit pundits were confused about resourceserver&lt;/a&gt; and what the point of it might be. In this post I demonstrate the use of resourceserver as a backend for the todomvc SPA demo.&lt;/p&gt;
&lt;h2 id=&quot;using-resourceserver-as-a-backend-for-an-spa-backbone-app&quot;&gt;Using Resourceserver as a backend for an SPA / Backbone app&lt;/h2&gt;
&lt;h3 id=&quot;install-redis-http-redis-io-&quot;&gt;Install &lt;a href=&quot;http://redis.io/&quot;&gt;redis&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;You’re on your own for this one. It is not hard and can be accomplished on *nix or windows.&lt;/p&gt;
&lt;h3 id=&quot;get-resourceserver&quot;&gt;Get resourceserver&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;git clone git@github.com:liammclennan/resourceserver.git
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;get-todomvc&quot;&gt;Get Todomvc&lt;/h3&gt;
&lt;p&gt;Todomvc is a reference app used to compare client-side web app libraries. It includes the same app (a todo app) built with a wide variety of libraries. We will use it as a client-side app to connect to resource server.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git clone git@github.com:tastejs/todomvc.git
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;enable-redis&quot;&gt;Enable redis&lt;/h3&gt;
&lt;p&gt;This is optional. By default resourceserver will just store resources in memory. Edit resourceserver’s config.coffee:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;module.exports =

   use_redis: true

   redis_config:
     host: &amp;#39;localhost&amp;#39;
     port: 6379
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Make sure the &lt;code&gt;redis_config&lt;/code&gt; settings match your redis installation.&lt;/p&gt;
&lt;h3 id=&quot;start-resourceserver&quot;&gt;Start resourceserver&lt;/h3&gt;
&lt;p&gt;In the directory where you cloned resourceserver:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm start
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;modify-todomvc&quot;&gt;Modify todomvc&lt;/h3&gt;
&lt;p&gt;We need to make a small modification to todomvc to enable server persistence. &lt;/p&gt;
&lt;p&gt;Modify architecture-examples/backbone/js/collections/todos.js:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-               localStorage: new Backbone.LocalStorage(&amp;#39;todos-backbone&amp;#39;),
+               url: &amp;#39;http://localhost:3002/todos&amp;#39;,
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;enjoy&quot;&gt;Enjoy&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2013-07-15-resourceserverbackbone/demo.png&quot; alt=&quot;Backbone and resourceserver&quot;/&gt;&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Resourceserver</title>
      <link>http://withouttheloop.com/articles/2013-07-14-resourceserver/</link>
      <pubDate>Sun, 14 Jul 2013 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2013-07-14-resourceserver/</guid>
      <author></author>
      <description>&lt;p&gt;Lately I have been resurecting an old project of mine - now called &lt;a href=&quot;https://github.com/liammclennan/resourceserver&quot;&gt;Resourceserver&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It is a simple, in-memory, resource-oriented http server, designed to be used during testing and development of rich-client web apps.&lt;/p&gt;
&lt;p&gt;Here is the README:&lt;/p&gt;
&lt;h1 id=&quot;resourceserver&quot;&gt;Resourceserver&lt;/h1&gt;
&lt;p&gt;TODO: Implement a persistent version (probably using redis).&lt;/p&gt;
&lt;p&gt;Implements an in-memory resource oriented HTTP server, provding 5 basic operations (shown in curl_tests.sh)&lt;/p&gt;
&lt;h3 id=&quot;post-collection&quot;&gt;POST /:collection&lt;/h3&gt;
&lt;p&gt;Create a new resource.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl -vX POST http://localhost:3002/people -H &amp;#39;content-type: application/json&amp;#39; -d &amp;#39;{&amp;quot;name&amp;quot;: &amp;quot;Liam&amp;quot;, &amp;quot;age&amp;quot;: 29}&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;{
  &amp;quot;name&amp;quot;: &amp;quot;Liam&amp;quot;,
  &amp;quot;age&amp;quot;: 29,
  &amp;quot;id&amp;quot;: 2
}
&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;curl -vX POST http://localhost:3002/people -H &amp;#39;content-type: application/json&amp;#39; -d &amp;#39;{&amp;quot;name&amp;quot;: &amp;quot;Noah&amp;quot;, &amp;quot;age&amp;quot;: 1}&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;{
  &amp;quot;name&amp;quot;: &amp;quot;Noah&amp;quot;,
  &amp;quot;age&amp;quot;: 1,
  &amp;quot;id&amp;quot;: 2
}
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;get-collection-id&quot;&gt;GET /:collection/:id&lt;/h3&gt;
&lt;p&gt;Retrieve the &lt;code&gt;:collection&lt;/code&gt; resource with id &lt;code&gt;:id&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl -v http://localhost:3002/people/1
&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;{
  &amp;quot;name&amp;quot;: &amp;quot;Liam&amp;quot;,
  &amp;quot;age&amp;quot;: 29,
  &amp;quot;id&amp;quot;: 1
}
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;get-collection&quot;&gt;GET /:collection&lt;/h3&gt;
&lt;p&gt;Retrieve an array of all &lt;code&gt;:collection&lt;/code&gt; resources.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl -v http://localhost:3002/people
&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;[
  {
    &amp;quot;name&amp;quot;: &amp;quot;Liam&amp;quot;,
    &amp;quot;age&amp;quot;: 29,
    &amp;quot;id&amp;quot;: 1
  },
  {
    &amp;quot;name&amp;quot;: &amp;quot;Noah&amp;quot;,
    &amp;quot;age&amp;quot;: 1,
    &amp;quot;id&amp;quot;: 2
  }
]
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;put-collection-id&quot;&gt;PUT /:collection/:id&lt;/h3&gt;
&lt;p&gt;Override the &lt;code&gt;:collection&lt;/code&gt; resource with id &lt;code&gt;:id&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl -vX PUT http://localhost:3002/people/1 -H &amp;#39;content-type: application/json&amp;#39; -d &amp;#39;{&amp;quot;name&amp;quot;: &amp;quot;LiamO&amp;quot;, &amp;quot;age&amp;quot;: 30}&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;{
  &amp;quot;name&amp;quot;: &amp;quot;LiamO&amp;quot;,
  &amp;quot;age&amp;quot;: 30,
  &amp;quot;id&amp;quot;: &amp;quot;1&amp;quot;
}
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;delete-collection-id&quot;&gt;DELETE /:collection/:id&lt;/h3&gt;
&lt;p&gt;Delete the &lt;code&gt;:collection&lt;/code&gt; resource with id &lt;code&gt;:id&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl -vX DELETE http://localhost:3002/people/1
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It uses the &lt;a href=&quot;https://developer.mozilla.org/en/http_access_control&quot;&gt;CORS headers&lt;/a&gt; to allow cross-origin requests.&lt;/p&gt;
&lt;h2 id=&quot;usage&quot;&gt;Usage&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Clone the repository&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install node.js&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install the dependencies with &lt;code&gt;npm install&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Start the server with &lt;code&gt;npm start&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[Optional] Run tests with &lt;code&gt;cd test &amp;amp;&amp;amp; ./curl_tests.sh&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
</description>
    </item>
    <item>
      <title>Clojure FizzBuzz</title>
      <link>http://withouttheloop.com/articles/2013-07-10-clojure-fizzbuzz/</link>
      <pubDate>Wed, 10 Jul 2013 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2013-07-10-clojure-fizzbuzz/</guid>
      <author></author>
      <description>&lt;p&gt;Here is my clojure fizzbuzz:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(defn fizzbuzz []
  (let [divisibleBy3 (fn [x]
                       (= 0 (mod x 3)))
        divisibleBy5 (fn [x]
                       (= 0 (mod x 5)))
        calcz (fn [i]
               (cond
                 (and (divisibleBy3 i) (divisibleBy5 i)) &amp;quot;FizzBuzz&amp;quot;
                 (divisibleBy5 i) &amp;quot;Buzz&amp;quot;
                 (divisibleBy3 i) &amp;quot;Fizz&amp;quot;
                 :else i))
        ]
     (map calcz (range 1 101))))

(fizzbuzz)
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>Haskell String Calculator Kata</title>
      <link>http://withouttheloop.com/articles/2013-05-31-stringcalckata/</link>
      <pubDate>Fri, 31 May 2013 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2013-05-31-stringcalckata/</guid>
      <author></author>
      <description>&lt;h2 id=&quot;the-kata&quot;&gt;The Kata&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2013-05-31-stringcalckata/calc.jpg&quot; align=&quot;right&quot; style=&quot;margin: 0px 0px 20px 20px;&quot; alt=&quot;string calculator&quot;/&gt;&lt;a href=&quot;http://osherove.com/tdd-kata-1/&quot;&gt;Roy Osherove’s string calculator kata&lt;/a&gt; is a very simple kata designed (I believe) to demonstrate the basic TDD workflow. &lt;/p&gt;
&lt;p&gt;The basic idea is to write a program (function?) that sums the integers in a string. “1,2,3” -&amp;gt; 6.&lt;/p&gt;
&lt;h2 id=&quot;setting-up-a-haskell-package-for-the-kata&quot;&gt;Setting Up a Haskell Package for the Kata&lt;/h2&gt;
&lt;p&gt;I like to start by initialising an isolated package for each new project.&lt;/p&gt;
&lt;p&gt;I used &lt;a href=&quot;https://github.com/Paczesiowa/hsenv&quot;&gt;hsenv&lt;/a&gt; to create an isolated environment (similar to rbenv etc). Then added a cabal configuration file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;name:                stringcalc
version:             0.1.0.0
author:              Liam
build-type:          Simple
cabal-version:       &amp;gt;=1.8

library
  exposed-modules:     StringCalc
  -- other-modules:       
  hs-source-dirs:      src/
  build-depends:       base ==4.6.*

test-suite tests
  type:               exitcode-stdio-1.0
  hs-source-dirs:     test/
  main-is:            Spec.hs
  build-depends:      base ==4.6.*
                      , hspec
                      , stringcalc
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This says that my project is library exporting one module, StringCalc, and that it has a test project in Spec.hs.&lt;/p&gt;
&lt;p&gt;To get this to build / run I need to create the library src/StringCalc.hs:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;module StringCalc where
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and the test file test/Spec.hs (these tests use the hspec test library):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import Test.Hspec
import Test.QuickCheck
import Control.Exception (evaluate)
import StringCalc

main :: IO ()
main = hspec $ do

  describe &amp;quot;Example Spec&amp;quot; $ do
    it &amp;quot;should pass&amp;quot; $ do
      (0 :: Int) `shouldBe` (0 :: Int)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;then build with cabal:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cabal configure --enable-tests
cabal install --enable-tests --only-dependencies
cabal build
cabal test
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;implementing-the-kata&quot;&gt;Implementing the Kata&lt;/h2&gt;
&lt;h3 id=&quot;step-1-&quot;&gt;Step 1: “”&lt;/h3&gt;
&lt;p&gt;The first thing to do is to get the program to handle the empty string input.&lt;/p&gt;
&lt;p&gt;Start with the test:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;main :: IO ()
main = hspec $ do

  describe &amp;quot;StringCalc&amp;quot; $ do
    it &amp;quot;should sum the empty string&amp;quot; $ do
      sumString &amp;quot;&amp;quot; `shouldBe` (0 :: Int)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and then the implementation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;module StringCalc (sumString) where

sumString :: String -&amp;gt; Int
sumString &amp;quot;&amp;quot; = 0
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;next deal with adding a single number:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;describe &amp;quot;add single number&amp;quot; $ do
      it &amp;quot;should add positive number&amp;quot; $ do
        sumString &amp;quot;1&amp;quot; `shouldBe` (1 :: Int)

      it &amp;quot;should add negative number&amp;quot; $ do
        sumString &amp;quot;-2&amp;quot; `shouldBe` (-2 :: Int)
&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;sumString :: String -&amp;gt; Int
sumString &amp;quot;&amp;quot; = 0
sumString s = sum $ map rInt (split s)
  where rInt :: String -&amp;gt; Int
        rInt s = read s
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The next step is, “Allow the Add method to handle an unknown amount of numbers”:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;describe &amp;quot;add two numbers&amp;quot; $ do
      describe &amp;quot;add 3 and 9&amp;quot; $ do
        it &amp;quot;should give 12&amp;quot; $ do
          sumString &amp;quot;3,9&amp;quot; `shouldBe` (12 :: Int)
&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;module StringCalc (sumString) where

sumString :: String -&amp;gt; Int
sumString &amp;quot;&amp;quot; = 0
sumString s = sum $ map rInt (split s)
  where rInt :: String -&amp;gt; Int
        rInt s = read s

split :: String -&amp;gt; [String]
split &amp;quot;&amp;quot; = []
split (&amp;#39;,&amp;#39;:ss) = split ss
split s = [takeWhile isNotComma s :: String] ++ (split $ dropWhile isNotComma s)
  where isNotComma :: Char -&amp;gt; Bool
        isNotComma c = c /= &amp;#39;,&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The sumString function now needs to be changed to use commas or newlines as the separator:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;describe &amp;quot;with newline separators&amp;quot; $ do
  let input = &amp;quot;1\n2\n3&amp;quot;

  it &amp;quot;should give 6&amp;quot; $ do
    sumString input `shouldBe` (6::Int)
&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;sumString :: String -&amp;gt; Int
sumString &amp;quot;&amp;quot; = 0
sumString s = sum $ map rInt (split s)
  where rInt :: String -&amp;gt; Int
        rInt s = read s

split :: String -&amp;gt; [String]
split &amp;quot;&amp;quot; = []
split (&amp;#39;,&amp;#39;:ss) = split ss
split (&amp;#39;\n&amp;#39;:ss) = split ss
split s = [takeWhile isNotSeparator s :: String] ++ (split $ dropWhile isNotSeparator s)
  where isNotSeparator :: Char -&amp;gt; Bool
        isNotSeparator c = c /= &amp;#39;,&amp;#39; &amp;amp;&amp;amp; c /= &amp;#39;\n&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The final requirement is to support different delimeters. Here it is, with some refactoring:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;module StringCalc (sumString) where

import Data.List
import Data.List.Split

hasExplicitDelimeter :: String -&amp;gt; Bool
hasExplicitDelimeter (&amp;#39;/&amp;#39;:&amp;#39;/&amp;#39;:s:&amp;#39;\n&amp;#39;:ss) = True
hasExplicitDelimeter _                   = False

trimmed :: String -&amp;gt; String
trimmed input | hasExplicitDelimeter input = drop 4 input
              | otherwise                  = input

sumString :: String -&amp;gt; Int
sumString &amp;quot;&amp;quot; = 0
sumString s = sum . map rInt $ splitOn [guessDelimeter s] (trimmed s)

  where rInt :: String -&amp;gt; Int
        rInt s = read s

        guessDelimeter :: String -&amp;gt; Char
        guessDelimeter input  | hasExplicitDelimeter input     = input !! 2
                              | &amp;quot;\n&amp;quot; `isInfixOf` trimmed input = &amp;#39;\n&amp;#39;
                              | otherwise                      = &amp;#39;,&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;blockquote&gt;
&lt;p&gt;UPDATE: &lt;a href=&quot;http://vimeo.com/18423904&quot;&gt;Michael Feathers performs the string calculator kata&lt;/a&gt; and arrives at a similar solution, except that his is point free&lt;/p&gt;
&lt;/blockquote&gt;
</description>
    </item>
    <item>
      <title>Reading Code - robots-txt</title>
      <link>http://withouttheloop.com/articles/2013-05-30-reading-code/</link>
      <pubDate>Thu, 30 May 2013 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2013-05-30-reading-code/</guid>
      <author></author>
      <description>&lt;p&gt;&lt;img src=&quot;/articles/2013-05-30-reading-code/cave.jpg&quot; align=&quot;left&quot; style=&quot;margin: 0px 20px 20px 0px;&quot; alt=&quot;spelunking&quot;/&gt; Scott Hanselman has or had a series called &lt;a href=&quot;http://www.hanselman.com/blog/TheWeeklySourceCode59AnOpenSourceTreasureIronyNETLanguageImplementationKit.aspx&quot;&gt;the weekly source code&lt;/a&gt;, in which he reviewed open source code as a learning exercise. I have enjoyed looking through the source of &lt;a href=&quot;https://github.com/meanpath/robots&quot;&gt;robots-txt&lt;/a&gt; by &lt;a href=&quot;https://github.com/mwotton&quot;&gt;Mark Wotton&lt;/a&gt; so I will follow Mr Hanselman’s lead and document my experience spelunking this source.&lt;/p&gt;
&lt;h2 id=&quot;robots-txt-cabal&quot;&gt;robots-txt.cabal&lt;/h2&gt;
&lt;p&gt;The first thing I noticed, in the root of the repository, is the robots-txt.cabal file. This file defines how the project will be packaged for use as a dependency of other projects and also the dependencies of the current project for installation. robots-txt is defined as a library, meaning that it exports things to be used in other applications and does not have its own executable. &lt;/p&gt;
&lt;p&gt;Below the standard package definition robots-txt.cabal includes a setting I have not seen before, &lt;a href=&quot;http://www.haskell.org/cabal/users-guide/developing-packages.html&quot;&gt;test-suite&lt;/a&gt;. robots-txt uses the older exitcode-stdio-1.0 + main-is style of test suite ‘that indicate test failure with a non-zero exit code’. Adding the test-suite configuration means that the project’s tests can be run with &lt;code&gt;cabal test&lt;/code&gt;. Yet another reason to add cabal configuration to all projects, not just the ones that are intended to be distributed as cabal packages.&lt;/p&gt;
&lt;p&gt;The usage of &lt;code&gt;hs-source-dirs&lt;/code&gt; for both the library and test-suite configuration is also interesting. &lt;/p&gt;
&lt;h2 id=&quot;tests&quot;&gt;Tests&lt;/h2&gt;
&lt;p&gt;The robots-txt.cabal file defines the entry point for testing as test/Spec.hs. Spec.hs references &lt;a href=&quot;https://github.com/sol/hspec-discover&quot;&gt;hspec-discover&lt;/a&gt; in a GHC_OPTIONS pragma. hspec-discover looks for and executes all tests in the directory and any subdirectories. This is a convenient way to avoid having to maintain a list of tests to execute. In the case of robots-txt there is only one test file to discover test/RobotSpec.hs.&lt;/p&gt;
&lt;h3 id=&quot;robotspec-hs&quot;&gt;RobotSpec.hs&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/meanpath/robots/blob/master/test/RobotSpec.hs&quot;&gt;RobotSpec.hs&lt;/a&gt; uses &lt;a href=&quot;http://hspec.github.io/&quot;&gt;hspec&lt;/a&gt; and the specification style of tests to define the behaviour of the project. It is curious that this style (describe… it… should) is popular on so many platforms and yet I have not seen a .NET implementation. &lt;/p&gt;
&lt;p&gt;RobotSpec.hs uses the &lt;code&gt;{-# LANGUAGE CPP #-}&lt;/code&gt; pragma, which allows it to use the special symbol &lt;strong&gt;FILE&lt;/strong&gt; which is presumably replaced by the current filename pre compilation. &lt;/p&gt;
&lt;p&gt;I don’t understand how RobotSpec is executed, since it doesn’t declare a main function like the hspec examples and it doesn’t export anything. &lt;/p&gt;
&lt;p&gt;At first I didn’t understand the use of forM_, but a bit of googling, and particularly &lt;a href=&quot;http://stackoverflow.com/questions/5856709/what-is-the-difference-between-liftm-and-mapm-in-haskell&quot;&gt;this stackoverflow question&lt;/a&gt; provided some insight.&lt;/p&gt;
&lt;h3 id=&quot;network-http-robots&quot;&gt;Network.HTTP.Robots&lt;/h3&gt;
&lt;p&gt;The actual program is contained within the &lt;a href=&quot;https://github.com/meanpath/robots/blob/master/src/Network/HTTP/Robots.hs&quot;&gt;Network.HTTP.Robots module&lt;/a&gt;. It defines a number of data structures and some functions for operating on them. Some of it is confusing to me, such as the directiveP function. I suspect I need to spend some more time with Control.Applicative&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Looking through Robots has been both fun and enlightening. The code is simple enough for me to understand (mostly) and it is small enough to be easily digestable. I’ve learnt a few things, particularly about how to setup testing which is an area that I have been planning to improve. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>Maybe Haskell?</title>
      <link>http://withouttheloop.com/articles/2013-05-19-maybe-haskell/</link>
      <pubDate>Sun, 19 May 2013 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2013-05-19-maybe-haskell/</guid>
      <author></author>
      <description>&lt;p&gt;Usual disclaimer - I don’t know Haskell at all. What follows is my rambling experimentation with the &lt;code&gt;Maybe&lt;/code&gt; type.&lt;/p&gt;
&lt;p&gt;Haskell has &lt;a href=&quot;http://www.haskell.org/ghc/docs/6.12.2/html/libraries/base-4.2.0.1/Data-Maybe.html&quot;&gt;a useful type called &lt;code&gt;Maybe&lt;/code&gt;&lt;/a&gt;. F# and probably most other functional languages have something similar. Even C# has Nullable&lt;T&gt; which is somewhat in similar in that its purpose is &lt;a href=&quot;http://www.haskell.org/ghc/docs/6.12.2/html/libraries/base-4.2.0.1/Data-Maybe.html&quot;&gt;“to encapsulate an optional value”&lt;/a&gt;. To put it another way, &lt;code&gt;Maybe&lt;/code&gt; is a parameterised or polymorphic type that represents that we possibly have a value of the type parameter. So &lt;code&gt;Maybe Int&lt;/code&gt; means maybe we have an &lt;code&gt;Int&lt;/code&gt;, maybe we don’t (ie we have Nothing).&lt;/p&gt;
&lt;p&gt;Because Haskell doesn’t allow &lt;code&gt;null&lt;/code&gt; values we might use &lt;code&gt;Maybe&lt;/code&gt; for a function that returns its input if the input is a positive number.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;giveIfEvan :: Int -&amp;gt; Maybe Int
giveIfEvan n = if n `mod` 2 == 0
                then Just n 
                else Nothing
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;Maybe&lt;/code&gt; is a monad, which, to me, means primarily that it provides a function to convert from a &lt;code&gt;Maybe&lt;/code&gt; of some type to a &lt;code&gt;Maybe&lt;/code&gt; of some other type (&lt;code&gt;&amp;gt;&amp;gt;= :: Maybe a -&amp;gt; Maybe b&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Imagine I want a function that given a &lt;code&gt;Maybe Int&lt;/code&gt; adds 1 to the value (if there is a value). One terrible way to write this is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;addOne :: Maybe Int -&amp;gt; Maybe Int
addOne n = if isJust n
            then Just (fromJust n + 1)
            else Nothing
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;or with pattern matching:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;addOne :: Maybe Int -&amp;gt; Maybe Int
addOne (Just a) = Just (a + 1)
addOne Nothing = Nothing
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;since &lt;code&gt;Maybe&lt;/code&gt; is a monad we can use do notation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;addOne n = do
        v &amp;lt;- n
        return (v + 1)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The benefit here is that &lt;code&gt;addOne&lt;/code&gt; handles the nothing case without an explicit conditional. &lt;/p&gt;
&lt;p&gt;If you don’t mind using a lambda you can use the de-sugared version of do &lt;code&gt;&amp;gt;&amp;gt;=&lt;/code&gt; (bind):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;addOne n = n &amp;gt;&amp;gt;= \v -&amp;gt; return (v + 1)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Or instead of a lambda we could define an extra function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;increment :: Int -&amp;gt; Maybe Int
increment v = return (v + 1)

addOne :: Maybe Int -&amp;gt; Maybe Int
addOne n = n &amp;gt;&amp;gt;= increment
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here is a complete program. Try changin the 8 to an odd number to see the nothing case.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import Data.Maybe

giveIfEvan :: Int -&amp;gt; Maybe Int
giveIfEvan n = if n `mod` 2 == 0
                then Just n 
                else Nothing

addOne :: Maybe Int -&amp;gt; Maybe Int
addOne n = do
            v &amp;lt;- n
            return (v + 1)

main = do
  return (addOne $ giveIfEvan 8)
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>Functional Game of Life part 3</title>
      <link>http://withouttheloop.com/articles/2013-05-12-functional-game-of-life-3-haskell/</link>
      <pubDate>Sun, 12 May 2013 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2013-05-12-functional-game-of-life-3-haskell/</guid>
      <author></author>
      <description>&lt;style&gt;
.cell {
    border: 2px solid black;
    width: 18px;
    height: 18px;
    position: absolute;background-color: #eee;
}
.on {
    background-color: #333;
}
&lt;/style&gt;


&lt;p&gt;This is the third part of a series investigating a functional solution to &lt;a href=&quot;http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life&quot;&gt;Conway’s Game of Life&lt;/a&gt;. &lt;a href=&quot;http://withouttheloop.com/articles/2013-05-06-functional-game-of-life/&quot;&gt;Part 1&lt;/a&gt; introduced the problem and implemented the HTML rendering of a Game of Life world using a functional style in C#. &lt;a href=&quot;http://withouttheloop.com/articles/2013-05-08-functional-gol-pt2-haskell/&quot;&gt;Part 2&lt;/a&gt; ported the C# code from part 1 to Haskell. The job now is to implement the core of a functional Game of Life, that is a function to convert one generation of cells to the next generation of cells. &lt;/p&gt;
&lt;h2 id=&quot;implementing-game-of-life&quot;&gt;Implementing Game of Life&lt;/h2&gt;
&lt;p&gt;The type declaration for the Game of Life generation function is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;liveGeneration :: [Cell] -&amp;gt; [Cell]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That is, it is a function that converts a list of living cells to another list of living cells. And here is the implementation:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;liveGeneration cs = [ Cell x y | x &amp;lt;- [0..(largestX cs) + 1], y &amp;lt;- [0..(largestY cs) + 1], aliveNextGeneration cs x y]

  where aliveNextGeneration cs xv yv = (isOn cs xv yv &amp;amp;&amp;amp; (livingNeighbours cs xv yv) `elem` [2,3])
          || (not (isOn cs xv yv) &amp;amp;&amp;amp; (livingNeighbours cs xv yv) == 3)

        livingNeighbours cs xv yv = length $ filter isNeighbour cs

          where isNeighbour (Cell xa ya)  = (xa == xv -1 &amp;amp;&amp;amp; ya == yv -1)    -- top left
                                  || (xa == xv &amp;amp;&amp;amp; ya == yv - 1)     -- above
                                  || (xa == xv + 1 &amp;amp;&amp;amp; ya == yv -1)  -- top right 
                                  || (xa == xv - 1 &amp;amp;&amp;amp; ya == yv)     -- left
                                  || (xa == xv + 1 &amp;amp;&amp;amp; ya == yv)     -- right
                                  || (xa == xv - 1 &amp;amp;&amp;amp; ya == yv + 1) -- bottom left
                                  || (xa == xv &amp;amp;&amp;amp; ya == yv + 1)     -- below
                                  || (xa == xv + 1 &amp;amp;&amp;amp; ya == yv + 1) -- bottom right
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note that the &lt;code&gt;liveGeneration&lt;/code&gt; function depends on two other functions: &lt;code&gt;aliveNextGeneration&lt;/code&gt; and &lt;code&gt;livingNeighbours&lt;/code&gt;. &lt;code&gt;aliveNextGeneration&lt;/code&gt; is a predicate that indicates if a given point (xv, yv) will be alive in the next generation. To determine if a cell will be alive in the next generation we need to know how many living neighbours it has - that is what &lt;code&gt;livingNeighbours&lt;/code&gt; is for. &lt;code&gt;livingNeighbours&lt;/code&gt; has its own local function &lt;code&gt;isNeighbour&lt;/code&gt; which is a predicate that tests if a cell is a neighbour.&lt;/p&gt;
&lt;p&gt;The following system is a classic Game of Life state known as &lt;em&gt;the R-pentomino&lt;/em&gt;:&lt;/p&gt;
&lt;div style=&quot;height: 120px;&quot;&gt;
&lt;div style=&quot;position:relative&quot;&gt;
&lt;div style=&quot;left: 20px; top: 20px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 20px; top: 40px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 20px; top: 60px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 20px; top: 80px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 40px; top: 20px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 40px; top: 40px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 40px; top: 60px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 40px; top: 80px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 60px; top: 20px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 60px; top: 40px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 60px; top: 60px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 60px; top: 80px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 80px; top: 20px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 80px; top: 40px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 80px; top: 60px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 80px; top: 80px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;

&lt;p&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;The following Haskell program runs the R-pentomino through 1 generation of the game of life:
    import Gol&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;rpentomino = [Cell 2 1, Cell 3 1, Cell 1 2, Cell 2 2, Cell 2 3]

main = do
  putStrLn $ render rpentomino
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Producing the following output:&lt;/p&gt;
&lt;div style=&quot;height: 120px;&quot;&gt;
&lt;div style=&quot;position:relative&quot;&gt;
&lt;div style=&quot;left: 20px; top: 20px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 20px; top: 40px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 20px; top: 60px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 20px; top: 80px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 40px; top: 20px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 40px; top: 40px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 40px; top: 60px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 40px; top: 80px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 60px; top: 20px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 60px; top: 40px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 60px; top: 60px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 60px; top: 80px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 80px; top: 20px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 80px; top: 40px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 80px; top: 60px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 80px; top: 80px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;


&lt;p&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;Ten generations:&lt;/p&gt;
&lt;div style=&quot;height: 160px;&quot;&gt;
&lt;div style=&quot;position:relative&quot;&gt;
&lt;div style=&quot;left: 20px; top: 20px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 20px; top: 40px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 20px; top: 60px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 20px; top: 80px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 20px; top: 100px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 40px; top: 20px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 40px; top: 40px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 40px; top: 60px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 40px; top: 80px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 40px; top: 100px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 60px; top: 20px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 60px; top: 40px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 60px; top: 60px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 60px; top: 80px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 60px; top: 100px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 80px; top: 20px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 80px; top: 40px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 80px; top: 60px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 80px; top: 80px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 80px; top: 100px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;Fifty generations:&lt;/p&gt;
&lt;div style=&quot;height: 280px;&quot;&gt;
&lt;div style=&quot;position:relative&quot;&gt;
&lt;div style=&quot;left: 20px; top: 20px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 20px; top: 40px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 20px; top: 60px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 20px; top: 80px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 20px; top: 100px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 20px; top: 120px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 20px; top: 140px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 20px; top: 160px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 20px; top: 180px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 20px; top: 200px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 20px; top: 220px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 20px; top: 240px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 40px; top: 20px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 40px; top: 40px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 40px; top: 60px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 40px; top: 80px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 40px; top: 100px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 40px; top: 120px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 40px; top: 140px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 40px; top: 160px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 40px; top: 180px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 40px; top: 200px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 40px; top: 220px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 40px; top: 240px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 60px; top: 20px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 60px; top: 40px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 60px; top: 60px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 60px; top: 80px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 60px; top: 100px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 60px; top: 120px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 60px; top: 140px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 60px; top: 160px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 60px; top: 180px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 60px; top: 200px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 60px; top: 220px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 60px; top: 240px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 80px; top: 20px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 80px; top: 40px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 80px; top: 60px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 80px; top: 80px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 80px; top: 100px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 80px; top: 120px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 80px; top: 140px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 80px; top: 160px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 80px; top: 180px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 80px; top: 200px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 80px; top: 220px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 80px; top: 240px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 100px; top: 20px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 100px; top: 40px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 100px; top: 60px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 100px; top: 80px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 100px; top: 100px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 100px; top: 120px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 100px; top: 140px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 100px; top: 160px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 100px; top: 180px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 100px; top: 200px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 100px; top: 220px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 100px; top: 240px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 120px; top: 20px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 120px; top: 40px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 120px; top: 60px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 120px; top: 80px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 120px; top: 100px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 120px; top: 120px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 120px; top: 140px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 120px; top: 160px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 120px; top: 180px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 120px; top: 200px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 120px; top: 220px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 120px; top: 240px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 140px; top: 20px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 140px; top: 40px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 140px; top: 60px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 140px; top: 80px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 140px; top: 100px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 140px; top: 120px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 140px; top: 140px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 140px; top: 160px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 140px; top: 180px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 140px; top: 200px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 140px; top: 220px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 140px; top: 240px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 160px; top: 20px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 160px; top: 40px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 160px; top: 60px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 160px; top: 80px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 160px; top: 100px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 160px; top: 120px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 160px; top: 140px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 160px; top: 160px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 160px; top: 180px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 160px; top: 200px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 160px; top: 220px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 160px; top: 240px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 180px; top: 20px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 180px; top: 40px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 180px; top: 60px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 180px; top: 80px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 180px; top: 100px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 180px; top: 120px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 180px; top: 140px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 180px; top: 160px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 180px; top: 180px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 180px; top: 200px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 180px; top: 220px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 180px; top: 240px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 200px; top: 20px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 200px; top: 40px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 200px; top: 60px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 200px; top: 80px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 200px; top: 100px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 200px; top: 120px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 200px; top: 140px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 200px; top: 160px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 200px; top: 180px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 200px; top: 200px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 200px; top: 220px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 200px; top: 240px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 220px; top: 20px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 220px; top: 40px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 220px; top: 60px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 220px; top: 80px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 220px; top: 100px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 220px; top: 120px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 220px; top: 140px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 220px; top: 160px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 220px; top: 180px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 220px; top: 200px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 220px; top: 220px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 220px; top: 240px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 240px; top: 20px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 240px; top: 40px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 240px; top: 60px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 240px; top: 80px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 240px; top: 100px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 240px; top: 120px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 240px; top: 140px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 240px; top: 160px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 240px; top: 180px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 240px; top: 200px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 240px; top: 220px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 240px; top: 240px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 260px; top: 20px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 260px; top: 40px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 260px; top: 60px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 260px; top: 80px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 260px; top: 100px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 260px; top: 120px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 260px; top: 140px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 260px; top: 160px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 260px; top: 180px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 260px; top: 200px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 260px; top: 220px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 260px; top: 240px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 280px; top: 20px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 280px; top: 40px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 280px; top: 60px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 280px; top: 80px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 280px; top: 100px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 280px; top: 120px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 280px; top: 140px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 280px; top: 160px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 280px; top: 180px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 280px; top: 200px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 280px; top: 220px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;left: 280px; top: 240px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Two hundred generations:&lt;/p&gt;
&lt;div style=&quot;height: 750px;&quot;&gt;
&lt;div style=&quot;position:relative&quot;&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 20px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 20px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 40px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 40px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 60px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 60px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 80px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 80px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 100px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 100px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 100px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 120px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 120px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 140px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 140px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 180px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 180px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 180px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 180px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 180px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 180px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 180px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 180px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 180px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 180px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 180px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 180px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 180px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 180px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 180px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 180px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 180px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 180px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 180px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 180px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 180px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 180px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 180px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 180px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 180px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 180px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 180px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 180px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 180px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 180px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 180px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 180px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 180px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 200px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 200px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 200px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 200px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 200px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 200px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 200px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 200px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 200px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 200px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 200px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 200px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 200px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 200px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 200px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 200px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 200px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 200px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 200px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 200px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 200px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 200px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 200px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 200px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 200px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 200px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 200px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 200px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 200px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 200px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 200px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 200px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 200px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 220px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 220px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 220px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 220px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 220px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 220px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 220px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 220px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 220px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 220px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 220px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 220px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 220px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 220px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 220px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 220px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 220px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 220px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 220px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 220px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 220px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 220px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 220px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 220px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 220px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 220px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 220px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 220px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 220px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 220px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 220px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 220px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 220px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 240px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 240px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 240px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 240px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 240px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 240px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 240px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 240px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 240px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 240px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 240px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 240px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 240px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 240px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 240px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 240px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 240px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 240px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 240px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 240px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 240px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 240px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 240px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 240px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 240px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 240px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 240px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 240px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 240px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 240px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 240px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 240px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 240px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 260px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 260px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 260px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 260px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 260px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 260px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 260px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 260px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 260px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 260px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 260px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 260px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 260px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 260px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 260px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 260px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 260px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 260px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 260px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 260px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 260px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 260px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 260px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 260px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 260px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 260px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 260px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 260px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 260px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 260px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 260px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 260px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 260px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 280px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 280px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 280px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 280px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 280px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 280px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 280px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 280px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 280px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 280px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 280px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 280px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 280px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 280px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 280px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 280px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 280px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 280px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 280px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 280px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 280px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 280px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 280px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 280px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 280px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 280px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 280px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 280px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 280px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 280px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 280px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 280px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 280px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 300px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 300px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 300px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 300px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 300px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 300px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 300px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 300px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 300px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 300px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 300px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 300px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 300px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 300px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 300px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 300px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 300px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 300px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 300px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 300px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 300px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 300px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 300px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 300px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 300px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 300px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 300px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 300px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 300px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 300px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 300px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 300px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 300px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 320px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 320px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 320px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 320px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 320px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 320px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 320px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 320px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 320px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 320px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 320px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 320px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 320px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 320px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 320px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 320px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 320px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 320px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 320px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 320px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 320px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 320px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 320px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 320px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 320px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 320px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 320px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 320px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 320px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 320px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 320px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 320px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 320px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 340px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 340px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 340px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 340px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 340px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 340px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 340px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 340px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 340px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 340px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 340px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 340px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 340px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 340px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 340px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 340px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 340px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 340px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 340px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 340px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 340px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 340px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 340px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 340px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 340px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 340px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 340px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 340px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 340px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 340px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 340px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 340px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 340px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 360px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 360px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 360px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 360px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 360px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 360px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 360px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 360px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 360px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 360px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 360px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 360px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 360px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 360px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 360px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 360px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 360px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 360px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 360px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 360px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 360px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 360px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 360px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 360px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 360px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 360px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 360px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 360px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 360px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 360px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 360px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 360px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 360px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 380px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 380px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 380px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 380px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 380px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 380px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 380px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 380px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 380px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 380px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 380px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 380px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 380px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 380px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 380px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 380px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 380px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 380px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 380px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 380px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 380px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 380px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 380px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 380px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 380px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 380px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 380px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 380px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 380px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 380px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 380px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 380px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 380px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 400px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 400px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 400px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 400px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 400px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 400px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 400px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 400px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 400px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 400px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 400px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 400px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 400px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 400px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 400px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 400px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 400px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 400px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 400px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 400px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 400px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 400px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 400px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 400px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 400px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 400px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 400px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 400px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 400px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 400px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 400px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 400px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 400px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 420px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 420px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 420px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 420px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 420px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 420px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 420px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 420px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 420px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 420px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 420px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 420px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 420px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 420px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 420px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 420px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 420px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 420px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 420px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 420px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 420px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 420px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 420px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 420px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 420px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 420px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 420px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 420px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 420px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 420px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 420px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 420px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 420px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 440px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 440px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 440px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 440px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 440px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 440px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 440px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 440px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 440px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 440px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 440px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 440px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 440px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 440px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 440px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 440px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 440px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 440px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 440px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 440px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 440px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 440px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 440px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 440px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 440px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 440px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 440px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 440px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 440px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 440px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 440px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 440px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 440px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 460px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 460px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 460px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 460px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 460px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 460px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 460px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 460px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 460px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 460px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 460px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 460px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 460px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 460px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 460px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 460px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 460px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 460px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 460px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 460px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 460px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 460px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 460px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 460px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 460px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 460px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 460px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 460px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 460px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 460px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 460px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 460px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 460px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 480px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 480px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 480px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 480px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 480px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 480px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 480px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 480px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 480px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 480px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 480px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 480px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 480px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 480px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 480px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 480px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 480px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 480px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 480px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 480px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 480px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 480px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 480px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 480px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 480px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 480px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 480px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 480px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 480px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 480px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 480px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 480px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 480px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 500px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 500px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 500px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 500px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 500px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 500px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 500px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 500px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 500px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 500px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 500px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 500px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 500px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 500px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 500px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 500px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 500px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 500px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 500px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 500px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 500px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 500px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 500px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 500px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 500px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 500px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 500px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 500px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 500px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 500px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 500px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 500px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 500px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 520px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 520px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 520px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 520px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 520px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 520px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 520px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 520px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 520px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 520px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 520px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 520px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 520px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 520px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 520px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 520px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 520px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 520px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 520px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 520px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 520px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 520px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 520px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 520px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 520px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 520px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 520px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 520px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 520px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 520px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 520px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 520px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 520px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 540px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 540px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 540px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 540px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 540px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 540px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 540px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 540px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 540px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 540px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 540px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 540px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 540px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 540px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 540px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 540px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 540px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 540px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 540px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 540px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 540px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 540px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 540px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 540px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 540px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 540px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 540px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 540px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 540px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 540px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 540px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 540px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 540px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 560px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 560px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 560px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 560px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 560px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 560px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 560px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 560px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 560px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 560px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 560px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 560px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 560px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 560px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 560px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 560px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 560px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 560px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 560px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 560px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 560px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 560px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 560px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 560px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 560px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 560px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 560px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 560px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 560px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 560px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 560px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 560px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 560px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 580px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 580px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 580px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 580px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 580px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 580px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 580px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 580px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 580px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 580px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 580px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 580px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 580px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 580px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 580px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 580px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 580px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 580px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 580px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 580px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 580px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 580px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 580px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 580px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 580px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 580px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 580px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 580px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 580px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 580px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 580px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 580px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 580px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 600px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 600px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 600px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 600px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 600px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 600px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 600px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 600px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 600px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 600px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 600px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 600px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 600px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 600px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 600px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 600px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 600px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 600px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 600px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 600px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 600px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 600px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 600px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 600px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 600px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 600px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 600px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 600px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 600px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 600px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 600px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 600px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 600px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 620px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 620px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 620px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 620px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 620px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 620px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 620px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 620px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 620px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 620px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 620px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 620px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 620px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 620px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 620px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 620px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 620px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 620px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 620px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 620px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 620px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 620px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 620px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 620px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 620px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 620px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 620px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 620px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 620px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 620px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 620px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 620px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 620px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 640px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 640px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 640px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 640px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 640px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 640px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 640px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 640px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 640px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 640px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 640px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 640px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 640px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 640px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 640px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 640px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 640px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 640px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 640px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 640px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 640px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 640px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 640px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 640px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 640px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 640px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 640px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 640px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 640px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 640px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 640px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 640px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 640px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 660px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 660px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 660px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 660px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 660px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 660px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 660px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 660px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 660px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 660px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 660px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 660px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 660px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 660px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 660px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 660px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 660px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 660px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 660px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 660px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 660px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 660px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 660px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 660px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 660px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 660px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 660px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 660px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 660px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 660px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 660px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 660px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 660px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 680px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 680px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 680px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 680px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 680px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 680px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 680px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 680px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 680px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 680px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 680px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 680px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 680px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 680px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 680px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 680px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 680px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 680px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 680px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 680px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 680px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 680px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 680px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 680px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 680px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 680px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 680px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 680px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 680px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 680px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 680px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 680px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 680px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 700px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 700px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 700px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 700px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 700px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 700px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 700px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 700px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 700px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 700px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 700px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 700px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 700px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 700px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 700px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 700px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 700px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 700px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 700px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 700px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 700px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 700px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 700px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 700px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 700px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 700px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 700px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 700px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 700px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 700px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 700px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 700px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 700px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 720px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 720px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 720px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 720px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 720px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 720px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 720px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 720px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 720px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 720px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 720px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 720px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 720px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 720px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 720px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 720px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 720px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 720px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 720px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 720px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 720px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 720px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 720px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 720px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 720px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 720px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 720px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 720px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 720px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 720px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 720px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 720px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 720px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 740px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 740px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 740px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 740px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 740px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 740px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 740px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 740px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 740px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 740px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 740px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 740px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 740px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 740px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 740px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 740px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 740px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 740px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 740px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 740px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 740px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 740px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 740px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 740px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 740px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 740px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 740px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 740px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 740px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 740px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 740px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 740px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 740px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 760px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 760px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 760px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 760px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 760px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 760px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 760px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 760px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 760px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 760px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 760px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 760px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 760px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 760px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 760px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 760px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 760px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 760px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 760px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 760px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 760px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 760px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 760px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 760px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 760px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 760px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 760px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 760px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 760px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 760px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 760px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 760px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 760px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 780px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 780px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 780px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 780px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 780px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 780px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 780px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 780px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 780px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 780px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 780px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 780px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 780px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 780px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 780px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 780px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 780px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 780px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 780px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 780px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 780px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 780px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 780px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 780px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 780px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 780px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 780px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 780px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 780px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 780px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 780px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 780px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 780px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 800px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 800px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 800px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 800px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 800px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 800px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 800px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 800px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 800px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 800px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 800px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 800px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 800px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 800px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 800px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 800px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 800px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 800px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 800px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 800px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 800px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 800px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 800px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 800px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 800px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 800px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 800px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 800px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 800px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 800px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 800px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 800px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 800px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 820px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 820px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 820px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 820px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 820px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 820px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 820px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 820px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 820px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 820px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 820px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 820px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 820px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 820px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 820px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 820px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 820px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 820px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 820px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 820px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 820px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 820px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 820px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 820px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 820px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 820px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 820px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 820px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 820px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 820px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 820px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 820px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 820px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 840px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 840px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 840px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 840px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 840px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 840px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 840px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 840px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 840px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 840px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 840px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 840px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 840px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 840px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 840px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 840px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 840px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 840px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 840px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 840px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 840px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 840px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 840px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 840px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 840px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 840px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 840px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 840px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 840px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 840px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 840px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 840px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 840px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 860px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 860px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 860px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 860px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 860px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 860px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 860px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 860px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 860px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 860px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 860px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 860px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 860px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 860px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 860px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 860px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 860px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 860px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 860px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 860px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 860px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 860px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 860px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 860px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 860px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 860px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 860px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 860px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 860px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 860px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 860px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 860px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 860px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 880px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 880px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 880px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 880px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 880px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 880px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 880px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 880px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 880px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 880px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 880px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 880px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 880px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 880px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 880px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 880px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 880px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 880px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 880px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 880px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 880px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 880px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 880px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 880px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 880px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 880px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 880px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 880px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 880px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 880px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 880px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 880px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 880px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 900px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 900px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 900px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 900px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 900px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 900px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 900px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 900px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 900px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 900px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 900px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 900px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 900px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 900px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 900px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 900px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 900px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 900px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 900px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 900px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 900px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 900px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 900px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 900px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 900px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 900px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 900px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 900px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 900px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 900px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 900px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 900px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 900px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 920px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 920px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 920px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 920px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 920px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 920px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 920px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 920px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 920px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 920px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 920px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 920px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 920px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 920px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 920px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 920px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 920px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 920px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 920px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 920px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 920px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 920px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 920px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 920px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 920px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 920px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 920px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 920px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 920px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 920px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 920px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 920px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 920px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 940px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 940px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 940px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 940px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 940px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 940px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 940px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 940px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 940px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 940px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 940px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 940px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 940px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 940px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 940px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 940px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 940px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 940px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 940px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 940px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 940px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 940px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 940px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 940px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 940px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 940px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 940px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 940px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 940px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 940px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 940px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 940px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 940px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 960px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 960px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 960px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 960px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 960px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 960px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 960px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 960px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 960px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 960px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 960px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 960px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 960px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 960px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 960px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 960px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 960px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 960px; top: 360px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell on&quot; style=&quot;left: 960px; top: 380px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 960px; top: 400px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 960px; top: 420px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 960px; top: 440px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 960px; top: 460px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 960px; top: 480px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 960px; top: 500px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 960px; top: 520px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 960px; top: 540px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 960px; top: 560px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 960px; top: 580px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 960px; top: 600px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 960px; top: 620px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 960px; top: 640px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cell &quot; style=&quot;left: 960px; top: 660px;&quot;&gt;&amp;nbsp;&lt;/div&gt;


&lt;p&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;At this scale the inefficiency of my algorithm is exposed. Evaluating 200 generations takes a &lt;strong&gt;long&lt;/strong&gt; time. &lt;/p&gt;
&lt;p&gt;Here is the full source for my Haskell Game of Life:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;module Gol 
(
  Cell(Cell),
  render,
  liveGeneration
) where

import Text.Printf
import Data.List

-- the definition of a living cell
data Cell = Cell {
    x       :: Int,
    y       :: Int
  } deriving (Show,Eq,Ord)

-- convert the state of the system to a html string
render :: [Cell] -&amp;gt; String
render cs = concat [renderLocation x y (isOn cs x y) | x &amp;lt;- [0..xBound], y &amp;lt;- [0..yBound]]
  where xBound = largestX cs
        yBound = largestY cs
        renderLocation xv yv on = printf 
          &amp;quot;&amp;lt;div class=\&amp;quot;cell %s\&amp;quot; style=\&amp;quot;left: %dpx; top: %dpx;\&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;lt;/div&amp;gt;\n&amp;quot; 
          (if on then &amp;quot;on&amp;quot; else &amp;quot;&amp;quot;) (20 * (xv+1)) (20 * (yv+1))

-- transition the system through one generation
liveGeneration :: [Cell] -&amp;gt; [Cell]
liveGeneration cs = [ Cell x y | x &amp;lt;- [0..(largestX cs) + 1], y &amp;lt;- [0..(largestY cs) + 1], aliveNextGeneration cs x y]

  where aliveNextGeneration cs xv yv = (isOn cs xv yv &amp;amp;&amp;amp; (livingNeighbours cs xv yv) `elem` [2,3])
          || (not (isOn cs xv yv) &amp;amp;&amp;amp; (livingNeighbours cs xv yv) == 3)

        livingNeighbours cs xv yv = length $ filter isNeighbour cs

          where isNeighbour (Cell xa ya)  = (xa == xv -1 &amp;amp;&amp;amp; ya == yv -1)    -- top left
                                  || (xa == xv &amp;amp;&amp;amp; ya == yv - 1)     -- above
                                  || (xa == xv + 1 &amp;amp;&amp;amp; ya == yv -1)  -- top right 
                                  || (xa == xv - 1 &amp;amp;&amp;amp; ya == yv)     -- left
                                  || (xa == xv + 1 &amp;amp;&amp;amp; ya == yv)     -- right
                                  || (xa == xv - 1 &amp;amp;&amp;amp; ya == yv + 1) -- bottom left
                                  || (xa == xv &amp;amp;&amp;amp; ya == yv + 1)     -- below
                                  || (xa == xv + 1 &amp;amp;&amp;amp; ya == yv + 1) -- bottom right

isOn :: [Cell] -&amp;gt; Int -&amp;gt; Int -&amp;gt; Bool
isOn cs xv yv = any cellMatch cs
  where cellMatch c = x c == xv &amp;amp;&amp;amp; y c == yv

largestX :: [Cell] -&amp;gt; Int
largestX cs = maximum $ map x cs

largestY :: [Cell] -&amp;gt; Int
largestY cs = maximum $ map y cs
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>Functional Game of Life part 2 (Haskell)</title>
      <link>http://withouttheloop.com/articles/2013-05-08-functional-gol-pt2-haskell/</link>
      <pubDate>Wed, 08 May 2013 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2013-05-08-functional-gol-pt2-haskell/</guid>
      <author></author>
      <description>&lt;style&gt;
.cell {
    border: 2px solid black;
    width: 18px;
    height: 18px;
    position: absolute;background-color: #eee;
}
.on {
    background-color: #333;
}
&lt;/style&gt;

&lt;blockquote&gt;
&lt;p&gt;DISCLAIMER: I don’t know Haskell at all. I know the code in this article is not idiomatic and I look forward to receiving constructive criticism.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In &lt;a href=&quot;http://withouttheloop.com/articles/2013-05-06-functional-game-of-life/&quot;&gt;part 1 of this series&lt;/a&gt; I began to implement the game of life cellular automaton in C# using the functional programming style (at least as I know it). Part 1 defined the data model and implemented a function to render the state of the system to HTML. &lt;/p&gt;
&lt;p&gt;For this part 2 of the series I port my C# solution to Haskell. &lt;/p&gt;
&lt;p&gt;Firstly, the data structure. As with the C# version I model the game of life as a list of living cells. The definition of a &lt;code&gt;cell&lt;/code&gt; is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;data Cell = Cell {
  x       :: Int,
  y       :: Int
} deriving (Show)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;where x and y are functions that return the cartesian coordinates of the cell. It is the same as the C# version, except that this &lt;code&gt;Cell&lt;/code&gt; type is immutable.&lt;/p&gt;
&lt;p&gt;Having defined my &lt;code&gt;Cell&lt;/code&gt; type I then defined a set of functions to do useful things with a &lt;code&gt;Cell&lt;/code&gt; or a list of cells. &lt;code&gt;renderLocation&lt;/code&gt; is a function that converts a point (xv,yv) and a boolean (indicating if the cell at that location is living) into its HTML string.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;renderLocation :: Int -&amp;gt; Int -&amp;gt; Bool -&amp;gt; String
renderLocation xv yv on = printf 
                          &amp;quot;&amp;lt;div class=\&amp;quot;cell %s\&amp;quot; style=\&amp;quot;left: %dpx; top: %dpx;\&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;lt;/div&amp;gt;\n&amp;quot; 
                          (if on then &amp;quot;on&amp;quot; else &amp;quot;&amp;quot;) (20 * (xv+1)) (20 * (yv+1))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The first line is a type definition for the function. Its C# equivalent would be &lt;code&gt;Func&amp;lt;int,int,bool,string&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To make &lt;code&gt;renderLocation&lt;/code&gt; useful I need a function to determine if a given location contains a living cell:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;isOn :: [Cell] -&amp;gt; Int -&amp;gt; Int -&amp;gt; Bool
isOn cs xv yv = any cellMatch cs
  where cellMatch c = x c == xv &amp;amp;&amp;amp; y c == yv
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This roughly translates to the C# &lt;code&gt;cs.Any(c =&amp;gt; x(c) == xv &amp;amp;&amp;amp; y(c) == yv)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The other helper functions required calculate the largest X and Y values to determine the size of the system:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;largestX :: [Cell] -&amp;gt; Int
largestX cs = maximum $ map x cs

largestY :: [Cell] -&amp;gt; Int
largestY cs = maximum $ map y cs
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;largestX&lt;/code&gt; translated to C# is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public int largestX(Cell[] cs) {
  return cs.Select(c =&amp;gt; x(c)).Max();
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Next I created three living cells, at coordinates (1,2), (3,5) and (14,13):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cells = [Cell 1 2, Cell 3 5, Cell 14 13]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now I can create a &lt;code&gt;render&lt;/code&gt; function that produces the HTML representation of a system:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;render :: [Cell] -&amp;gt; String
render cs = concat [renderLocation x y (isOn cs x y) | x &amp;lt;- [0..xBound], y &amp;lt;- [0..yBound]]
  where xBound = largestX cs
        yBound = largestY cs
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The expression &lt;code&gt;[renderLocation x y (isOn cs x y) | x &amp;lt;- [0..xBound], y &amp;lt;- [0..yBound]]&lt;/code&gt; is a list comprehension. The part after the pipe &lt;code&gt;x &amp;lt;- [0..xBound], y &amp;lt;- [0..yBound]&lt;/code&gt; produces the cartesian product of all possible x values (&lt;code&gt;[0..xBound]&lt;/code&gt;) and all possible y values (&lt;code&gt;[0..yBound]&lt;/code&gt;). For each point the &lt;code&gt;renderLocation&lt;/code&gt; function is called. The results are collected into a list of strings which is then flattened to a single string by the &lt;code&gt;concat&lt;/code&gt; function.&lt;/p&gt;
&lt;p&gt;This is equivalent to the C# version:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var results = from x in Enumerable.Range(0, largestX+1)
              from y in Enumerable.Range(0, largestY+1)
              select buildCell(x, y, IsOn(cells, x, y));
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now to get the program to actually do something I define a list of cells and then use the programs &lt;code&gt;main&lt;/code&gt; function to render my list of cells and write the result to stdout.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cells = [Cell 1 2, Cell 3 5, Cell 14 13]

main = (putStrLn . render) cells
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The output of this program is:&lt;/p&gt;
&lt;div style=&quot;clear:both;height: 400px;&quot;&gt;
&lt;div style=&quot;position:relative&quot;&gt;
  &lt;div style=&quot;left: 20px; top: 20px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 20px; top: 40px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 20px; top: 60px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 20px; top: 80px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 20px; top: 100px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 20px; top: 120px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 20px; top: 140px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 20px; top: 160px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 20px; top: 180px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 20px; top: 200px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 20px; top: 220px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 20px; top: 240px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 20px; top: 260px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 20px; top: 280px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 20px; top: 300px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 40px; top: 20px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 40px; top: 40px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 40px; top: 60px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 40px; top: 80px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 40px; top: 100px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 40px; top: 120px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 40px; top: 140px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 40px; top: 160px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 40px; top: 180px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 40px; top: 200px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 40px; top: 220px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 40px; top: 240px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 40px; top: 260px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 40px; top: 280px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 40px; top: 300px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 60px; top: 20px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 60px; top: 40px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 60px; top: 60px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 60px; top: 80px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 60px; top: 100px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 60px; top: 120px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 60px; top: 140px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 60px; top: 160px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 60px; top: 180px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 60px; top: 200px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 60px; top: 220px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 60px; top: 240px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 60px; top: 260px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 60px; top: 280px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 60px; top: 300px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 80px; top: 20px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 80px; top: 40px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 80px; top: 60px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 80px; top: 80px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 80px; top: 100px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 80px; top: 120px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 80px; top: 140px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 80px; top: 160px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 80px; top: 180px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 80px; top: 200px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 80px; top: 220px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 80px; top: 240px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 80px; top: 260px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 80px; top: 280px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 80px; top: 300px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 100px; top: 20px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 100px; top: 40px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 100px; top: 60px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 100px; top: 80px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 100px; top: 100px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 100px; top: 120px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 100px; top: 140px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 100px; top: 160px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 100px; top: 180px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 100px; top: 200px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 100px; top: 220px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 100px; top: 240px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 100px; top: 260px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 100px; top: 280px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 100px; top: 300px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 120px; top: 20px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 120px; top: 40px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 120px; top: 60px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 120px; top: 80px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 120px; top: 100px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 120px; top: 120px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 120px; top: 140px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 120px; top: 160px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 120px; top: 180px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 120px; top: 200px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 120px; top: 220px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 120px; top: 240px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 120px; top: 260px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 120px; top: 280px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 120px; top: 300px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 140px; top: 20px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 140px; top: 40px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 140px; top: 60px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 140px; top: 80px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 140px; top: 100px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 140px; top: 120px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 140px; top: 140px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 140px; top: 160px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 140px; top: 180px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 140px; top: 200px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 140px; top: 220px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 140px; top: 240px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 140px; top: 260px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 140px; top: 280px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 140px; top: 300px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 160px; top: 20px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 160px; top: 40px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 160px; top: 60px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 160px; top: 80px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 160px; top: 100px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 160px; top: 120px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 160px; top: 140px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 160px; top: 160px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 160px; top: 180px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 160px; top: 200px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 160px; top: 220px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 160px; top: 240px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 160px; top: 260px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 160px; top: 280px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 160px; top: 300px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 180px; top: 20px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 180px; top: 40px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 180px; top: 60px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 180px; top: 80px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 180px; top: 100px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 180px; top: 120px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 180px; top: 140px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 180px; top: 160px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 180px; top: 180px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 180px; top: 200px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 180px; top: 220px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 180px; top: 240px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 180px; top: 260px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 180px; top: 280px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 180px; top: 300px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 200px; top: 20px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 200px; top: 40px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 200px; top: 60px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 200px; top: 80px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 200px; top: 100px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 200px; top: 120px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 200px; top: 140px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 200px; top: 160px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 200px; top: 180px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 200px; top: 200px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 200px; top: 220px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 200px; top: 240px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 200px; top: 260px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 200px; top: 280px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 200px; top: 300px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 220px; top: 20px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 220px; top: 40px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 220px; top: 60px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 220px; top: 80px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 220px; top: 100px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 220px; top: 120px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 220px; top: 140px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 220px; top: 160px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 220px; top: 180px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 220px; top: 200px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 220px; top: 220px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 220px; top: 240px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 220px; top: 260px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 220px; top: 280px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 220px; top: 300px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 240px; top: 20px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 240px; top: 40px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 240px; top: 60px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 240px; top: 80px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 240px; top: 100px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 240px; top: 120px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 240px; top: 140px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 240px; top: 160px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 240px; top: 180px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 240px; top: 200px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 240px; top: 220px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 240px; top: 240px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 240px; top: 260px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 240px; top: 280px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 240px; top: 300px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 260px; top: 20px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 260px; top: 40px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 260px; top: 60px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 260px; top: 80px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 260px; top: 100px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 260px; top: 120px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 260px; top: 140px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 260px; top: 160px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 260px; top: 180px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 260px; top: 200px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 260px; top: 220px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 260px; top: 240px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 260px; top: 260px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 260px; top: 280px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 260px; top: 300px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 280px; top: 20px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 280px; top: 40px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 280px; top: 60px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 280px; top: 80px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 280px; top: 100px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 280px; top: 120px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 280px; top: 140px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 280px; top: 160px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 280px; top: 180px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 280px; top: 200px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 280px; top: 220px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 280px; top: 240px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 280px; top: 260px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 280px; top: 280px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 280px; top: 300px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 300px; top: 20px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 300px; top: 40px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 300px; top: 60px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 300px; top: 80px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 300px; top: 100px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 300px; top: 120px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 300px; top: 140px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 300px; top: 160px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 300px; top: 180px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 300px; top: 200px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 300px; top: 220px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 300px; top: 240px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 300px; top: 260px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 300px; top: 280px;&quot; class=&quot;cell on&quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 300px; top: 300px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 320px; top: 20px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 320px; top: 40px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 320px; top: 60px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 320px; top: 80px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 320px; top: 100px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 320px; top: 120px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 320px; top: 140px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 320px; top: 160px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 320px; top: 180px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 320px; top: 200px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 320px; top: 220px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 320px; top: 240px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 320px; top: 260px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 320px; top: 280px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
  &lt;div style=&quot;left: 320px; top: 300px;&quot; class=&quot;cell &quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Here is the full program:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import Text.Printf
import Data.List

data Cell = Cell {
    x       :: Int,
    y       :: Int
  } deriving (Show)

renderLocation :: Int -&amp;gt; Int -&amp;gt; Bool -&amp;gt; String
renderLocation xv yv on = printf 
                     &amp;quot;&amp;lt;div class=\&amp;quot;cell %s\&amp;quot; style=\&amp;quot;left: %dpx; top: %dpx;\&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;lt;/div&amp;gt;\n&amp;quot; 
                     (if on then &amp;quot;on&amp;quot; else &amp;quot;&amp;quot;) (20 * (xv+1)) (20 * (yv+1))

isOn :: [Cell] -&amp;gt; Int -&amp;gt; Int -&amp;gt; Bool
isOn cs xv yv = any cellMatch cs
  where cellMatch c = x c == xv &amp;amp;&amp;amp; y c == yv

largestX :: [Cell] -&amp;gt; Int
largestX cs = maximum $ map x cs

largestY :: [Cell] -&amp;gt; Int
largestY cs = maximum $ map y cs

render :: [Cell] -&amp;gt; String
render cs = concat [renderLocation x y (isOn cs x y) | x &amp;lt;- [0..xBound], y &amp;lt;- [0..yBound]]
  where xBound = largestX cs
        yBound = largestY cs

--cells = [Cell 1 2, Cell 3 5, Cell 14 13]
--new Cell(1,0), new Cell(0,1), new Cell(2,1), new Cell(7,16)
cells = [Cell 1 0, Cell 0 1, Cell 2 1, Cell 7 16]

main = (putStrLn . render) cells
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It is a bit longer than the C# version, but that is because I have used more explicit functions and specified more explicit types.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Functional Game of Life part 1 (C#)</title>
      <link>http://withouttheloop.com/articles/2013-05-06-functional-game-of-life/</link>
      <pubDate>Mon, 06 May 2013 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2013-05-06-functional-game-of-life/</guid>
      <author></author>
      <description>&lt;style&gt;
.cell {
    border: 2px solid black;
    width: 18px;
    height: 18px;
    position: absolute;background-color: #eee;
}
.on {
    background-color: #333;
}
&lt;/style&gt;

&lt;p&gt;&lt;img src=&quot;Gospers_glider_gun.gif&quot; align=&quot;left&quot; style=&quot;margin:20px;&quot;/&gt; I thought it might be interesting to solve the &lt;a href=&quot;http://en.wikipedia.org/wiki/Conway&amp;#39;s_Game_of_Life&quot;&gt;Conway’s Game of Life&lt;/a&gt; cellular automaton in a functional manner. Game of life is an interesting problem for experimentation because it is simple and well understood. &lt;/p&gt;
&lt;h2 id=&quot;where-to-start-&quot;&gt;Where to Start?&lt;/h2&gt;
&lt;p&gt;I’ll start by defining a way to render the world. I want to start here because it is useful to have a nice way to visualise the state of the system, also it conveniently forces me to define my data model. I will model the system as a collection of living cells, each with X and Y coordinates (zero based). The living cells define the boundaries of the system. Dead cells are implicitly the cells within the system boundary that are not living. A system defined as:&lt;/p&gt;
&lt;div style=&quot;clear: both;&quot;&gt;&lt;/div&gt;


&lt;pre&gt;&lt;code&gt;new Cell(1,0), new Cell(0,1), new Cell(2,1), new Cell(7,16)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;will produce &lt;a href=&quot;http://jsfiddle.net/P44aM/1/&quot;&gt;the following output&lt;/a&gt; (living cells are darker):&lt;/p&gt;
&lt;div style=&quot;clear:both;height: 400px;&quot;&gt;
&lt;div style=&quot;position:relative;&quot;&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell on&quot; style=&quot;left: 20px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 20px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell on&quot; style=&quot;left: 40px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 40px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell on&quot; style=&quot;left: 60px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 60px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 80px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 100px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 120px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 140px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 20px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 40px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 60px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 80px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 100px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 120px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 140px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 160px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 180px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 200px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 220px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 240px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 260px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 280px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 300px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell &quot; style=&quot;left: 160px; top: 320px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
    &lt;div class=&quot;cell on&quot; style=&quot;left: 160px; top: 340px;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;To get to this I started with a test (using &lt;a href=&quot;http://nuget.org/packages/Giv.n/&quot;&gt;giv.n&lt;/a&gt; and nunit).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[TestFixture]
public class RenderingTests
{
    private List&amp;lt;Cell&amp;gt; _cells;
    private string _result;

    [Test]
    public void RenderASmallSystem()
    {
        Giv.n(ASmallSystem);
        Wh.n(ItIsRendered);
        Th.n(() =&amp;gt; ItShouldRenderDimensions(8, 17))
            .And(() =&amp;gt; LivingCellCountIs(_cells.Count));
    }

    private void ASmallSystem()
    {
        _cells = new List&amp;lt;Cell&amp;gt; { new Cell(1,0), new Cell(0,1), new Cell(2,1), new Cell(7,16) };
    }

    private void ItIsRendered()
    {
        _result = GameOfLife.Render(_cells);
    }

    private void ItShouldRenderDimensions(int x, int y)
    {
        Assert.AreEqual(x*y, CountOccurances(_result,&amp;quot;&amp;lt;div&amp;quot;));
    }

    private void LivingCellCountIs(int count)
    {
        Assert.AreEqual(count, CountOccurances(_result,&amp;quot;on&amp;quot;));
    }

    private static int CountOccurances(string source, string sub)
    {
        return source.Select((c, i) =&amp;gt; source.Substring(i)).Count(s =&amp;gt; s.StartsWith(sub));
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and the implementation so far:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class GameOfLife
{
    public static string Render(List&amp;lt;Cell&amp;gt; cells)
    {
        var largestX = cells.Max(c =&amp;gt; c.X);
        var largestY = cells.Max(c =&amp;gt; c.Y);
        Func&amp;lt;int,int,bool, string&amp;gt; buildCell = (x,y,on) =&amp;gt; 
            string.Format(&amp;quot;&amp;lt;div class=\&amp;quot;cell {2}\&amp;quot; style=\&amp;quot;left: {0}px; top: {1}px;\&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;lt;/div&amp;gt;&amp;quot;, 20 * (x+1), 20 * (y+1), @on ? &amp;quot;on&amp;quot; : &amp;quot;&amp;quot;);

        var results = from x in Enumerable.Range(0, largestX+1)
                      from y in Enumerable.Range(0, largestY+1)
                      select buildCell(x, y, IsOn(cells, x, y));
        return string.Join(&amp;quot;\n&amp;quot;, results);
    }

    private static bool IsOn(IEnumerable&amp;lt;Cell&amp;gt; cells, int x, int y)
    {
        return cells.Any(c =&amp;gt; c.X == x &amp;amp;&amp;amp; c.Y == y);
    }
}

public struct Cell
{
    public int X;
    public int Y;

    public Cell(int x, int y)
    {
        X = x;
        Y = y;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;source&quot;&gt;Source&lt;/h2&gt;
&lt;p&gt;The source for this article is in a &lt;a href=&quot;https://github.com/liammclennan/functional-game-of-life&quot;&gt;public git repo&lt;/a&gt;, under the tag &lt;code&gt;data-and-render&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;next&quot;&gt;Next&lt;/h2&gt;
&lt;p&gt;The next post in this series will look at randomly seeding the system with living cells, so that the cellular evolution can be started. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>Didacto - Learn JavaScript with interactive, executable tutorials</title>
      <link>http://withouttheloop.com/articles/2013-04-26-didacto/</link>
      <pubDate>Fri, 26 Apr 2013 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2013-04-26-didacto/</guid>
      <author></author>
      <description>&lt;p&gt;&lt;a href=&quot;http://javascript.didacto.net/&quot;&gt;Didacto: JavaScript&lt;/a&gt; is a web site that teaches JavaScript using a set of tutorials (currently covering just the basics). What makes didacto unusual and interesting is that the tutorials include questions that can be answered and automatically evaluated. If you get a question wrong didacto can tell you and also tell you why. &lt;/p&gt;
&lt;p&gt;The executable tutorial idea was borrowed from the excellent &lt;a href=&quot;https://www.fpcomplete.com/&quot;&gt;School of Haskell&lt;/a&gt;. In a way it is the natural evolution of my old &lt;a href=&quot;https://github.com/liammclennan/JavaScript-Koans&quot;&gt;JavaScript Koans project&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I started with JavaScript because the server component of Didacto is written in JavaScript so that was easiest but I would like to extend the same idea to C# and other languages if it seems worthwhile.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://javascript.didacto.net/&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;didacto.png&quot; alt=&quot;Didacto: Learn JavaScript with interactive, executable tutorials&quot; /&gt;&lt;a/&gt;&lt;/p&gt;
</description>
    </item>
    <item>
      <title>giv.n</title>
      <link>http://withouttheloop.com/articles/2013-04-16-giv.n/</link>
      <pubDate>Tue, 16 Apr 2013 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2013-04-16-giv.n/</guid>
      <author></author>
      <description>&lt;p&gt;Today I published my &lt;a href=&quot;https://github.com/liammclennan/giv.n&quot;&gt;first nuget package&lt;/a&gt; - a ridiculously simple BDD library written by &lt;a href=&quot;http://nblumhardt.com/&quot;&gt;Nicholas Blumhardt&lt;/a&gt; and I. &lt;/p&gt;
&lt;p&gt;giv.n is a tiny DSL for grouping the steps of an executable specifications into the familiar given, when and then (or &lt;code&gt;giv.n&lt;/code&gt;, &lt;code&gt;wh.n&lt;/code&gt; and &lt;code&gt;th.n&lt;/code&gt; in giv.n language). It does not have a test runner or an assertion library so you still need NUnit or similar. Here is an example specification written with giv.n and NUnit.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;using Givn;

[Test]
public WhenIBakeACake() {
    Giv.n(IHaveFlour)
        .And(IHaveEggs);
    Wh.n(IBakeCake);
    Th.n(IHaveDeliciousSnack);
}

private void IHaveFlour() {
    _ingredients.Add(new Flour());
}

private void IHaveEggs() {
    _ingredients.Add(new Eggs());
}

private void IBakeCake() {
    _cake = _oven.Bake(_ingredients);
}

private void IHaveDeliciousSnack() {
    Assert.IsTrue(_cake.IsDelicious());
}
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>Can we stop saying 'unit tests'?</title>
      <link>http://withouttheloop.com/articles/2013-04-07-unit-tests/</link>
      <pubDate>Sun, 07 Apr 2013 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2013-04-07-unit-tests/</guid>
      <author></author>
      <description>&lt;h2 id=&quot;what-is-a-unit-test-&quot;&gt;What is a unit test?&lt;/h2&gt;
&lt;p&gt;Here is wikipedia’s definition of unit testing:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In computer programming, unit testing is a method by which individual units of source code, sets of one or more computer program modules together with associated control data, usage procedures, and operating procedures, are tested to determine if they are fit for use.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Looking carefully we notice that, “units of source code, sets of one or more computer program modules” is actually everything. Therefore, the above definition can be condensed, without changing its meaning, to:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In computer programming, unit testing is a method by which any source code is tested to determine if it is fit for use.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That is, unit testing is testing. Great.&lt;/p&gt;
&lt;p&gt;Roy Osherove’s definition is equally vague and pointless:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A unit test is a piece of a code (usually a method) that invokes another
piece of code and checks the correctness of some assumptions after-
ward. If the assumptions turn out to be wrong, the unit test has failed.
A “unit” is a method or function.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Prior to the last sentence this was a useful definition of an automated test, but the last sentence, “a unit is a method or function” is seemingly unrelated to the rest of the definition. Defining a “unit” does not help unless we choose to infer that a “unit test” is a test that tests a “unit”. If a “unit test” is a test that tests a “unit”, and a “unit is a method or function” then if we factor our programs into cooperating functions, as suggested by &lt;a href=&quot;http://en.wikipedia.org/wiki/Decomposition_%28computer_science%29&quot;&gt;functional decomposition&lt;/a&gt;, the &lt;a href=&quot;http://c2.com/ppr/wiki/WikiPagesAboutRefactoring/ComposedMethod.html&quot;&gt;composed method pattern&lt;/a&gt; and the &lt;a href=&quot;http://en.wikipedia.org/wiki/SOLID_%28object-oriented_design%29&quot;&gt;SOLID principles&lt;/a&gt; then it is impossible to write a “unit test” according to Osherove’s definition, since any function that calls another function is by definition not a “unit”. Testing a function that depends upon other functions is obviously testing all of the functions involved. &lt;/p&gt;
&lt;p&gt;Despite a lot of pretense the fact is that we do not have an accepted definition of a unit test. &lt;/p&gt;
&lt;h2 id=&quot;what-is-the-harm-&quot;&gt;What is the harm?&lt;/h2&gt;
&lt;p&gt;I have always treated “unit test” as the antonyn of “integration test”. This has been a useful dichotomy. Unit tests are fast, integration tests are slow therefore it is useful to separate them. &lt;/p&gt;
&lt;p&gt;The ambiguity of the term only becomes a problem when people malign tests with statements such as, “that’s not a unit test”. That may well be, or it may not be, it’s hard to say since there is no consistent, useful definition of a unit test.&lt;/p&gt;
&lt;p&gt;“Unit tests are good” is an empty bit of dogma that has outlived is usefullnes, finally becoming not just useless but harmful. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>Listagram</title>
      <link>http://withouttheloop.com/articles/2013-03-28-listagram/</link>
      <pubDate>Thu, 28 Mar 2013 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2013-03-28-listagram/</guid>
      <author></author>
      <description>&lt;blockquote&gt;
&lt;p&gt;UPDATE: I have made the &lt;a href=&quot;https://bitbucket.org/liammclennan/list-a-gram&quot;&gt;listagram source&lt;/a&gt; publically available for anyone who is interested.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If you have a billion dollar company, or very specific needs, then it may make sense to develop native mobile applications for multiple platforms. For everyone else it is hard to argue against the practicality of portable html-based applications. Such has been my uneducated opinion for some time. To prove that multi-platform web apps are a viable option I decided to build one.&lt;/p&gt;
&lt;h2 id=&quot;the-story-so-far&quot;&gt;The Story So Far&lt;/h2&gt;
&lt;p&gt;I travel home from work on the train. While making my way home it is not unusual for my wife to send me a list of groceries for me to pickup. I found that an SMS as a shopping list does not provide a good user experience. It is too hard to see the items and to keep track of which items remain. &lt;/p&gt;
&lt;h2 id=&quot;listagram&quot;&gt;Listagram&lt;/h2&gt;
&lt;p&gt;The app that I built is called &lt;a href=&quot;https://play.google.com/store/apps/details?id=net.onashirt.listagram&amp;amp;feature=search_result#?t=W251bGwsMSwxLDEsIm5ldC5vbmFzaGlydC5saXN0YWdyYW0iXQ..&quot;&gt;Listagram&lt;/a&gt;. It provides two features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Send a list of items, to yourself or to someone else&lt;/li&gt;
&lt;li&gt;Receive a list, view the items and complete the items as required&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;listagram.png&quot; /&gt;&lt;/p&gt;
&lt;h2 id=&quot;technical&quot;&gt;Technical&lt;/h2&gt;
&lt;h3 id=&quot;client&quot;&gt;Client&lt;/h3&gt;
&lt;p&gt;I built the app entirely as a standalone web application. It was nice to be able to develop without resorting to testing on a mobile device or emulator. I used chrome and its wonderful developer tools.&lt;/p&gt;
&lt;p&gt;The client-side and server-side code is all written as &lt;a href=&quot;http://wiki.commonjs.org/wiki/Modules/1.1&quot;&gt;commonjs modules&lt;/a&gt; and packaged for client-side use with &lt;a href=&quot;https://github.com/substack/node-browserify&quot;&gt;browserify&lt;/a&gt;. The language I used is &lt;a href=&quot;http://coffeescript.org/&quot;&gt;CoffeeScript&lt;/a&gt;, which browserify takes care of compiling.&lt;/p&gt;
&lt;p&gt;For a client-side UI framework I used &lt;a href=&quot;http://stativ.us/&quot;&gt;stativus&lt;/a&gt;. Stativus is a UI statechart very good for treating UI changes as state transition. This is helpful for preventing memory leaks and provided an interesting contract to &lt;a href=&quot;http://backbonejs.org/&quot;&gt;backbone&lt;/a&gt; - the framework that I have most experience with.&lt;/p&gt;
&lt;p&gt;The UI templates are rendered using &lt;a href=&quot;http://underscorejs.org/#template&quot;&gt;underscore’s template function&lt;/a&gt;. To precompile the UI templates and merge them into a single file I wrote a node.js module called &lt;a href=&quot;https://npmjs.org/package/underscorec&quot;&gt;underscorec&lt;/a&gt;. Underscorec can read a directory structure of templates and compile it.&lt;/p&gt;
&lt;p&gt;Client-side storage is provided by &lt;a href=&quot;http://diveintohtml5.info/storage.html&quot;&gt;localStorage&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Usage is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;underscorec views/ output.js
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;where &lt;code&gt;views/&lt;/code&gt; is a directory structure containing templates. The templates can then be used be calling a function with a name matching the name of the compiled template:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;templates[home/index]({name: &amp;#39;Peter&amp;#39;, age: 27})
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;server&quot;&gt;Server&lt;/h3&gt;
&lt;p&gt;The server is written as a node.js application. The web framework is &lt;a href=&quot;http://expressjs.com/&quot;&gt;express&lt;/a&gt; and the data is stored in &lt;a href=&quot;http://couchdb.apache.org/&quot;&gt;couchdb&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;server-deployment&quot;&gt;Server Deployment&lt;/h3&gt;
&lt;p&gt;The services that drive the app are deployed to a vps via an ssh script and git. I use &lt;a href=&quot;https://github.com/nodejitsu/forever&quot;&gt;forever&lt;/a&gt; to start the node.js app as a service. &lt;/p&gt;
&lt;h3 id=&quot;client-deployment&quot;&gt;Client Deployment&lt;/h3&gt;
&lt;p&gt;The client is packaged as a multi-platform mobile application using &lt;a href=&quot;http://phonegap.com/&quot;&gt;phonegap&lt;/a&gt;. I used the online service &lt;a href=&quot;https://build.phonegap.com&quot;&gt;Phonegap Build&lt;/a&gt; to create my app packages for each mobile platform.&lt;/p&gt;
&lt;h2 id=&quot;final-thoughts&quot;&gt;Final Thoughts&lt;/h2&gt;
&lt;p&gt;The experience turned out to be more work than I anticipated but it did confirm my suspicion that the cross-platform mobile solution is viable for most requirements. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>Things considered harmful (in C#)</title>
      <link>http://withouttheloop.com/articles/2013-03-26-things-considered-harmful/</link>
      <pubDate>Tue, 26 Mar 2013 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2013-03-26-things-considered-harmful/</guid>
      <author></author>
      <description>&lt;p&gt;Spelunking through a program recently I started to think about my coding style, particularly in C#. It occurred to me that my style is most easily defined in terms of the things that I try to avoid. Here is a quick list of things to avoid, in C#, where practical.&lt;/p&gt;
&lt;p&gt;Most of the justification for these exclusions is in my presentation &lt;a href=&quot;https://dl.dropbox.com/u/8948049/fp/dddbrisbane2012-master/reveal.js/index.html&quot;&gt;Why Functional Programming Matters&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;loops&quot;&gt;Loops&lt;/h2&gt;
&lt;p&gt;I don’t like explicit loops, for and foreach. Use linq when querying. Explicit loops are better when mutating state but let’s avoid that too. Recursion is also an option. &lt;/p&gt;
&lt;h2 id=&quot;conditional-if-&quot;&gt;Conditional (if)&lt;/h2&gt;
&lt;p&gt;Null checking type conditionals can be replaced with null coallescion in a variant of the null object pattern:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(callback ?? ()=&amp;gt; {})();
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Polymorphism allows types to replace explicit conditionals. Tell don’t ask can also eliminate conditionals. Finally, the conditional operator (?:) is preferable to the if statement because it is an expression.&lt;/p&gt;
&lt;h2 id=&quot;switch-statement-&quot;&gt;Switch statement &lt;/h2&gt;
&lt;p&gt;Switch is a particularly nasty special case of conditionals.&lt;/p&gt;
&lt;p&gt;Avoid by using polymorphism or convert to a dictionary (declarative instead of imperative). &lt;/p&gt;
&lt;h2 id=&quot;statements-&quot;&gt;Statements &lt;/h2&gt;
&lt;p&gt;C# make these hard to avoid because many C# language feature are not expressions. The solution is to use language features that are expression oriented, like linq, factor functions properly and write pure functions. Variable declarations are ok if they make code more readable.&lt;/p&gt;
&lt;h2 id=&quot;mutable-state&quot;&gt;Mutable state&lt;/h2&gt;
&lt;p&gt;Don’t have it if you don’t need it. Return copies of things.&lt;/p&gt;
&lt;h2 id=&quot;state-mutations&quot;&gt;State mutations&lt;/h2&gt;
&lt;p&gt;As above.&lt;/p&gt;
&lt;h2 id=&quot;async&quot;&gt;async&lt;/h2&gt;
&lt;p&gt;The TPL is great when you need to do something asynchronously, but it is viral in the sense that all callers become async too. Don’t use async/TPL without a good reason and do it as shallow in the callstack as possible. Separate async / IO code from pure code &lt;/p&gt;
&lt;h2 id=&quot;null&quot;&gt;null&lt;/h2&gt;
&lt;p&gt;Null is &lt;a href=&quot;http://en.wikipedia.org/wiki/Tony_Hoare&quot;&gt;Tony Hoare&lt;/a&gt;‘s fault. &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I call it my billion-dollar mistake. It was the invention of the null reference in 1965. At that time, I was designing the first comprehensive type system for references in an object oriented language (ALGOL W). My goal was to ensure that all use of references should be absolutely safe, with checking performed automatically by the compiler. But I couldn’t resist the temptation to put in a null reference, simply because it was so easy to implement. This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Eric Lippert seems to agree:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;even this is essentially an accident of history; it just so happened that when C# was first implemented it had always-nullable reference types, non-nullable value types, and no generic types at all. In a counterfactual world where the CLR had generic types from the get-go, it seems plausible that Nullable&lt;T&gt; could have been implemented to work on any type, and reference types would then be non-nullable by default. We could have a type system where Nullable&lt;string&gt; was the only legal way to represent “a string that can be null”. Keep this in mind the next time you design a new type system!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Give references default values and design types that don’t contain null members. No more null reference exceptions.&lt;/p&gt;
&lt;h2 id=&quot;ref-and-out-params&quot;&gt;ref and out params&lt;/h2&gt;
&lt;p&gt;It is often (always?) possible to replace ref and out params with other options, such as pre-testing values. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>Haskell influences in CoffeeScript</title>
      <link>http://withouttheloop.com/articles/2013-02-27-haskell-influence-coffeescript/</link>
      <pubDate>Wed, 27 Feb 2013 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2013-02-27-haskell-influence-coffeescript/</guid>
      <author></author>
      <description>&lt;p&gt;While learning a bit of Haskell I was struck by the syntactical similarites to CoffeeScript. Since Haskell predates CoffeeScript by twenty years (1990/2010) it seems that it is Haskell that has had an influence on CoffeeScript. What follows is a list of the similarities that I have observed.&lt;/p&gt;
&lt;h2 id=&quot;binding-variables&quot;&gt;Binding Variables&lt;/h2&gt;
&lt;p&gt;In Haskell we can bind a local variable to a scope using the &lt;code&gt;let... in&lt;/code&gt; syntax:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;circumference r = let pi = 3.14159
                  in  pi * 2 * r
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;CoffeeScript supports the same thing via the &lt;code&gt;do&lt;/code&gt; keyword. One interesting thing about &lt;code&gt;do&lt;/code&gt; is that it allows a way to define a variable that is (sort of) not scoped to a function.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;circumference = (r) -&amp;gt;
  do (pi = 3.14159) -&amp;gt;
    pi * 2 * r
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can read about some interesting uses of &lt;code&gt;do&lt;/code&gt; in Reginald Braithwaite’s &lt;a href=&quot;https://leanpub.com/coffeescript-ristretto&quot;&gt;CoffeeScript Ristretto&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;significant-whitespace&quot;&gt;Significant Whitespace&lt;/h2&gt;
&lt;p&gt;As you can see in the examples above Haskell and CoffeeScript both use significant whitespace in a similar way. &lt;/p&gt;
&lt;h2 id=&quot;expressions-statements&quot;&gt;Expressions &amp;gt; Statements&lt;/h2&gt;
&lt;p&gt;Both Haskell and CoffeeScript encourage us to favour expressions over statements. CoffeeScript supports statements that aren’t expressions but does &lt;a href=&quot;http://coffeescript.org/#expressions&quot;&gt;everything possible to let you avoid them&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;evenness = (i) -&amp;gt;
  if i % 2 is 0
    &amp;#39;even&amp;#39;
  else
    &amp;#39;odd&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Combining this with the &lt;code&gt;do&lt;/code&gt; notation we can do&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;evenness = (i) -&amp;gt;
  do (is_even = (n) -&amp;gt; n % 2 is 0) -&amp;gt;
    if is_even i
      &amp;#39;even&amp;#39;
    else
      &amp;#39;odd&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;comprehensions&quot;&gt;Comprehensions&lt;/h2&gt;
&lt;p&gt;Haskell and CoffeeScript have similar syntax for list comprehension. The following Haskell function selects the even elements of a list (&lt;code&gt;x mod 2 == 0&lt;/code&gt;) and maps them through a function that multiplies them by two (&lt;code&gt;x*2&lt;/code&gt;).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;double_odds xs = [x*2 | x &amp;lt;- xs, x `mod` 2 == 0]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The equivalent CoffeeScript is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;double_odds = (xs) -&amp;gt;
  x*2 for x in xs when x % 2 is 0
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;function-call-syntax&quot;&gt;Function Call Syntax&lt;/h2&gt;
&lt;p&gt;Both languages use a parenthesis free syntax for applying a function. &lt;/p&gt;
&lt;p&gt;Haskell:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;add 2 3
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;CoffeeScript:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;add 2, 3
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;ranges&quot;&gt;Ranges&lt;/h2&gt;
&lt;p&gt;For basic incrementing or decrementing integers Haskell and CoffeeScript have the same syntax.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[1..10]

[10..1]
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;literate-mode&quot;&gt;Literate Mode&lt;/h2&gt;
&lt;p&gt;Haskell and CoffeeScript both support a ‘literate’ mode that emphasizes comments over code. &lt;/p&gt;
&lt;p&gt;In &lt;a href=&quot;http://coffeescript.org/#literate&quot;&gt;CoffeeScript’s literate mode&lt;/a&gt; markdown text is interpreted as a comment. Indented text is executed as CoffeeScript code. &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Heading
=======

What I need is a function that doubles the even numbers in a list. Here&amp;#39;s one!

  double_odds = (xs) -&amp;gt;
    x*2 for x in xs when x % 2 is 0
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Haskell’s literate mode uses a &lt;code&gt;&amp;gt;&lt;/code&gt; to indicate lines of code.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;What I need is a function that doubles the even numbers in a list. Here&amp;#39;s one!

&amp;gt; double_odds xs = [x*2 | x &amp;lt;- xs, x `mod` 2 == 0]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That’s all that I can think of, but I’m sure there is more. CoffeeScript is often described as a blend of Ruby and Python that compiles to JavaScript. I think this underplays the influence of Haskell in CoffeeScript’s design.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>dbc (node.js npm module)</title>
      <link>http://withouttheloop.com/articles/2013-02-24-dbc/</link>
      <pubDate>Sun, 24 Feb 2013 15:00:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2013-02-24-dbc/</guid>
      <author></author>
      <description>&lt;h1 id=&quot;dbc&quot;&gt;dbc&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://npmjs.org/package/dbc&quot;&gt;dbc&lt;/a&gt; is my &lt;a href=&quot;https://npmjs.org/~liammclennan&quot;&gt;third npm module&lt;/a&gt;. I am experimenting with the node.js (unix?) philosophy of small, composable modules. dbc provides some basic tools for &lt;a href=&quot;http://en.wikipedia.org/wiki/Design_by_contract&quot;&gt;design-by-contract&lt;/a&gt;, something that I believe is essential when working in a loosely typed language like JavaScript. &lt;/p&gt;
&lt;p&gt;To install:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    npm install dbc
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;to run the tests:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    npm tests/ -R spec
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;which will produce this delightful output:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/articles/2013-02-24-dbc/images/dbc.png&quot; alt=&quot;dbc test output&quot; /&gt;&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Reversing a string</title>
      <link>http://withouttheloop.com/articles/2013-02-20-reverse-a-string/</link>
      <pubDate>Wed, 20 Feb 2013 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2013-02-20-reverse-a-string/</guid>
      <author></author>
      <description>&lt;p&gt;While there are many ways to skin a cat I can only think of the one involving a knife. However, I can think of many ways to reverse a string. &lt;/p&gt;
&lt;h2 id=&quot;recursive-function&quot;&gt;Recursive function&lt;/h2&gt;
&lt;p&gt;My preferred solution is a simple recursive function (gistfile1.cs). The first character of the reversed string is the last character of the input. The rest of the string is the rest of the input reversed. The only other thing required is to detect when the entire string has been processed and terminate the recursion.&lt;/p&gt;
&lt;h2 id=&quot;map-from-a-collection-of-indexes&quot;&gt;Map from a collection of indexes&lt;/h2&gt;
&lt;p&gt;Create a collection of indexes and map each one to its inverse location in the string (gistfile2.cs).&lt;/p&gt;
&lt;p&gt;The CoffeeScript version (gistfile3.coffee) has nicer syntax. It also demonstrates the affect of reversing the sequence of indexes.&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/liammclennan/4994673.js&quot;&gt;&lt;/script&gt;</description>
    </item>
    <item>
      <title>Handlebars Byte Order Mark!</title>
      <link>http://withouttheloop.com/articles/2012-08-01-handlebars-bom/</link>
      <pubDate>Wed, 01  Aug 2012 15:00:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2012-08-01-handlebars-bom/</guid>
      <author></author>
      <description>&lt;p&gt;Byte order mark (BOM) is a unicode character that signals the byte order of a UTF text file. If displayed in a text editor it most often appears as &lt;code&gt;ï»¿&lt;/code&gt;. &lt;/p&gt;
&lt;p&gt;Sometimes, when using &lt;a href=&quot;http://handlebarsjs.com/&quot;&gt;Handlebars.js&lt;/a&gt; to produce markup you will see extraneous whitespace inserted into the DOM immediately prior to your rendered template. In the chrome developer tool, this extra whitespace appears as &lt;code&gt;&amp;quot; &amp;quot;&lt;/code&gt;. In firebug it appears as EF BB BF.&lt;/p&gt;
&lt;p&gt;This problem seems to occur when using the &lt;a href=&quot;http://handlebarsjs.com/precompilation.html&quot;&gt;handlebars.js precompilation feature&lt;/a&gt; to precompile templates on the server and combine them into a single script. The precompiler doesn’t remove the BOM marks when compiling the templates so they end up in the DOM, messing with your layout. &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The solution is to make sure that the template files do not include BOMs. You can use Notepad++, Sublime Text or any good text editor to save a file as UTF-8 without BOM. &lt;/p&gt;
&lt;/blockquote&gt;
</description>
    </item>
    <item>
      <title>Currying</title>
      <link>http://withouttheloop.com/articles/2012-02-18-currying/</link>
      <pubDate>Sat, 18 Feb 2012 15:00:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2012-02-18-currying/</guid>
      <author></author>
      <description>&lt;p&gt;This is a function that does some currying:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-coffeescript&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;title&quot;&gt;add&lt;/span&gt; = &lt;span class=&quot;params&quot;&gt;(a,b)&lt;/span&gt; -&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;not&lt;/span&gt; b?
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; (c) -&amp;gt;
      c + a
  a + b
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;JavaScript provides the capability to reflect on the number of arguments:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-coffeescript&quot;&gt;add.length
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and to determine how many arguments were provided:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-coffeescript&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;title&quot;&gt;add&lt;/span&gt; = &lt;span class=&quot;params&quot;&gt;(a,b)&lt;/span&gt; -&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; arguments.length &amp;lt; add.length
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; (c) -&amp;gt;
      c + a
  a + b
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;so it seems like it should be possible to write a function that magically returns a function that requires the right number of arguments. So I could have a function:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-coffeescript&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;title&quot;&gt;f&lt;/span&gt; = &lt;span class=&quot;params&quot;&gt;(a,b,c,d,e,f)&lt;/span&gt; -&amp;gt;&lt;/span&gt;
  ..
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;if invoked with:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-coffeescript&quot;&gt;f(&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;it should return:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-coffeescript&quot;&gt;(c,d,e,f) -&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;anyone know how to do that?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Update&lt;/p&gt;
&lt;p&gt;Lots of good comments on &lt;a href=&quot;https://gist.github.com/liammclennan/3654718&quot;&gt;the original gist&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
</description>
    </item>
    <item>
      <title>Quicksort in Haskell and CoffeeScript</title>
      <link>http://withouttheloop.com/articles/2012-02-17-quicksort/</link>
      <pubDate>Fri, 17 Feb 2012 15:00:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2012-02-17-quicksort/</guid>
      <author></author>
      <description>&lt;p&gt;The definition of Quicksort, from Wikipedia is:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The steps are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Pick an element, called a pivot, from the list.&lt;/li&gt;
&lt;li&gt;Reorder the list so that all elements with values less than the pivot come before the pivot, while all elements with values greater than the pivot come after it (equal values can go either way). After this partitioning, the pivot is in its final position. This is called the partition operation.&lt;/li&gt;
&lt;li&gt;Recursively sort the sub-list of lesser elements and the sub-list of greater elements.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The base case of the recursion are lists of size zero or one, which never need to be sorted.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Quicksort in Haskell, from learn you a haskell, is:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-haskell&quot;&gt;    quicksort :: (&lt;span class=&quot;type&quot;&gt;Ord&lt;/span&gt; a) =&amp;gt; [a] -&amp;gt; [a]  
    quicksort [] = []  
    quicksort (x:xs) =   
        &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; smallerSorted = quicksort [a | a &amp;lt;- xs, a &amp;lt;= x]  
            biggerSorted = quicksort [a | a &amp;lt;- xs, a &amp;gt; x]  
        &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt;  smallerSorted ++ [x] ++ biggerSorted
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A basic quicksort in CoffeeScript is:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-coffeescript&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;title&quot;&gt;quicksort&lt;/span&gt; = &lt;span class=&quot;params&quot;&gt;([head,tail...])&lt;/span&gt; -&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; [] &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;typeof&lt;/span&gt; head &lt;span class=&quot;keyword&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;'undefined'&lt;/span&gt;
  smaller_sorted = quicksort (e &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; e &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; tail &lt;span class=&quot;keyword&quot;&gt;when&lt;/span&gt; e &amp;lt;= head)
  larger_sorted = quicksort (e &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; e &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; tail &lt;span class=&quot;keyword&quot;&gt;when&lt;/span&gt; e &amp;gt; head)
  smaller_sorted.concat([head]).concat(larger_sorted)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The CoffeeScript version is reasonable, and shares some similarity with the haskell implementation. The part I don’t like is having to check &lt;code&gt;typeof head is &amp;#39;undefined&amp;#39;&lt;/code&gt; for the base case. This is because the destructuring assignment of the function argument leaves me with no reference to the full array so the only way to tell if it is empty is to check if the head is undefined. There is probably a better way to do this. Please comment if you know what that is.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Backbone.js and Client-side Web Applications</title>
      <link>http://withouttheloop.com/articles/2012-02-16-backbone-client-web/</link>
      <pubDate>Thu, 16 Feb 2012 15:00:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2012-02-16-backbone-client-web/</guid>
      <author></author>
      <description>&lt;h1 id=&quot;backbone-js-and-client-side-web-applications&quot;&gt;Backbone.js and Client-side Web Applications&lt;/h1&gt;
&lt;p&gt;In the beginning the internet was a set of documents. Then someone decided to add hyperlinks to create a web of connections between documents. Soon static documents were not enough so we began to dynamically create documents on the server. The client-side user experience was still flat, so scripting was introduced to add dynamic behavior to pages. Finally, the most demanding and advanced web applications moved their user interface entirely to the client-side to provide the ultimate user experience. This apocryphal tale demonstrates the long, unbroken trend towards richer user interfaces on the web. &lt;/p&gt;
&lt;p&gt;The new generation of frameworks, libraries and training material make developing client-side web applications fun and approachable. &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Warning: the rest of this article assumes some knowledge of JavaScript. If you would like to learn more about JavaScript I have recorded a &lt;a href=&quot;http://pluralsight.com/training/Courses/TableOfContents/jscript-fundamentals&quot;&gt;comprehensive JavaScript introduction screencast&lt;/a&gt; for pluralsight.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;backbone-js&quot;&gt;Backbone.js&lt;/h2&gt;
&lt;p&gt;Backbone.js is a &lt;a href=&quot;http://backbonejs.org/&quot;&gt;delightfully documented&lt;/a&gt; set of tools that help us to simplify and structure client-side web applications. &lt;/p&gt;
&lt;p&gt;Backbone provides the building blocks for assembling client-side applications. Models are used to store an application’s data and to handle sending data to and from the server. Views map to user interface elements. They render markup, usually based on models, and connect event handlers to document events. Finally, backbone’s router is used to trigger and handle client-side routing. &lt;/p&gt;
&lt;p&gt;Putting these basic elements together we can assemble complex applications in an enjoyable and productive way. The rest of this article will investigate a simple application that makes use of the model and view components of Backbone.js. &lt;/p&gt;
&lt;p&gt;For a complete introduction to Backbone.js, including guidance on how to structure and test backbone.js applications, try my &lt;a href=&quot;http://pluralsight.com/training/Courses/TableOfContents/backbone-fundamentals&quot;&gt;Backbone Fundamentals screencast&lt;/a&gt; course.&lt;/p&gt;
&lt;h2 id=&quot;the-basics&quot;&gt;The Basics&lt;/h2&gt;
&lt;p&gt;Backbone.js does many things - one of the most immediately useful is the ability to bind one data object to multiple user interface components. When the underlying data model is changed each of the views is automatically updated to reflect those changes. &lt;/p&gt;
&lt;p&gt;Imagine a user interface that displays a color as its hex value, and as a swatch. The color can be represented as a backbone model. The hex display and the swatch are each a backbone view. &lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;mockup&quot; src=&quot;https://dl.dropbox.com/u/8948049/backbone/mockup.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://jsfiddle.net/ynkJE/171/&quot;&gt;Try the completed application&lt;/a&gt; but ignore the code for now. &lt;/p&gt;
&lt;p&gt;The single color model can be shared between the two views. That way there is a single authoritative data source, and no possibility of synchronization problems. &lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;class diagram&quot; src=&quot;https://dl.dropbox.com/u/8948049/backbone/static.png&quot; /&gt;&lt;/p&gt;
&lt;h2 id=&quot;a-first-backbone-js-model&quot;&gt;A first Backbone.js Model&lt;/h2&gt;
&lt;p&gt;The data object (backbone model) can be created like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-js&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; color = &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; Backbone.Model({
  &lt;span class=&quot;attr&quot;&gt;hex&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'#ff0000'&lt;/span&gt;
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For a starting point I have set the model’s hex value to &lt;code&gt;#ff0000&lt;/code&gt; which is the hex code for red.&lt;/p&gt;
&lt;h2 id=&quot;backbone-js-views&quot;&gt;Backbone.js Views&lt;/h2&gt;
&lt;p&gt;The hex view, which displays the hex value of the color in a text box is: &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-js&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; HexView = Backbone.View.extend({
    &lt;span class=&quot;attr&quot;&gt;render&lt;/span&gt;: &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; (&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
        &lt;span class=&quot;comment&quot;&gt;// create a textbox containing the model's hex attribute&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; input = &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.make(&lt;span class=&quot;string&quot;&gt;'input'&lt;/span&gt;, { &lt;span class=&quot;attr&quot;&gt;type&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'text'&lt;/span&gt;, &lt;span class=&quot;attr&quot;&gt;value&lt;/span&gt;: &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.model.get(&lt;span class=&quot;string&quot;&gt;'hex'&lt;/span&gt;) });
        &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.$el.append(input);
    }    
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;render()&lt;/code&gt; is the function that backbone uses to update a view’s markup. &lt;code&gt;this.model&lt;/code&gt; is the view’s reference to the shared color model.&lt;/p&gt;
&lt;p&gt;The swatch view, which displays a color swatch representing the color model, is implemented as:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-js&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; SwatchView = Backbone.View.extend({
    &lt;span class=&quot;attr&quot;&gt;render&lt;/span&gt;: &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; (&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.$el.html(&lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.make(&lt;span class=&quot;string&quot;&gt;'div'&lt;/span&gt;, { &lt;span class=&quot;attr&quot;&gt;class&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;swatch&quot;&lt;/span&gt;, &lt;span class=&quot;attr&quot;&gt;style&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;background-color: &quot;&lt;/span&gt; + &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.model.get(&lt;span class=&quot;string&quot;&gt;'hex'&lt;/span&gt;) }));
    }
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;see the &lt;a href=&quot;http://jsfiddle.net/ynkJE/170/&quot;&gt;full source&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;To illustrate the real power of Backbone.js we need to change the model data, and trigger an update of the views. To do this, we add a button to the hex view and handle its click event.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-js&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; HexView = Backbone.View.extend({
    &lt;span class=&quot;comment&quot;&gt;// Every view type can have an events property that declares event bindings.&lt;/span&gt;
    events: {
        &lt;span class=&quot;string&quot;&gt;'click input'&lt;/span&gt;: &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; (&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
            &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.model.set({&lt;span class=&quot;attr&quot;&gt;hex&lt;/span&gt;: &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.$(&lt;span class=&quot;string&quot;&gt;'input'&lt;/span&gt;).val()});
        }
    },

    &lt;span class=&quot;attr&quot;&gt;render&lt;/span&gt;: &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; (&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; input = &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.make(&lt;span class=&quot;string&quot;&gt;'input'&lt;/span&gt;, {&lt;span class=&quot;attr&quot;&gt;type&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'text'&lt;/span&gt;, &lt;span class=&quot;attr&quot;&gt;value&lt;/span&gt;: &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.model.get(&lt;span class=&quot;string&quot;&gt;'hex'&lt;/span&gt;)});
        &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.$el.html(input);
        &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.$el.append(&lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.make(&lt;span class=&quot;string&quot;&gt;'input'&lt;/span&gt;, {&lt;span class=&quot;attr&quot;&gt;type&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'button'&lt;/span&gt;, &lt;span class=&quot;attr&quot;&gt;value&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'update'&lt;/span&gt;}));
    }    
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When the button is clicked the view updates the model with the color currently in the text box. To get this change to show up in the swatch view we need to bind the model’s &lt;code&gt;change&lt;/code&gt; event to the swatch view’s &lt;code&gt;render()&lt;/code&gt; function. &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-js&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; SwatchView = Backbone.View.extend({
    &lt;span class=&quot;attr&quot;&gt;initialize&lt;/span&gt;: &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; (&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
        &lt;span class=&quot;comment&quot;&gt;// handle the model's `change` event&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.model.on(&lt;span class=&quot;string&quot;&gt;'change'&lt;/span&gt;, &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; (&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
            &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.render();
        }, &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;);
    },

    &lt;span class=&quot;attr&quot;&gt;render&lt;/span&gt;: &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;function&lt;/span&gt; (&lt;span class=&quot;params&quot;&gt;&lt;/span&gt;) &lt;/span&gt;{
        &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.$el.html(&lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.make(&lt;span class=&quot;string&quot;&gt;'div'&lt;/span&gt;, { &lt;span class=&quot;attr&quot;&gt;class&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;&quot;swatch&quot;&lt;/span&gt;, &lt;span class=&quot;attr&quot;&gt;style&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;&quot;background-color: &quot;&lt;/span&gt; + &lt;span class=&quot;keyword&quot;&gt;this&lt;/span&gt;.model.get(&lt;span class=&quot;string&quot;&gt;'hex'&lt;/span&gt;) }));        
    }
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;initialize()&lt;/code&gt; is a special view function that is run when an instance of the view is created (like a constructor).&lt;/p&gt;
&lt;h2 id=&quot;connecting-the-dots&quot;&gt;Connecting the dots&lt;/h2&gt;
&lt;p&gt;We have a model object (&lt;code&gt;color&lt;/code&gt;) and two view types (&lt;code&gt;HexView&lt;/code&gt; and &lt;code&gt;SwatchView&lt;/code&gt;). To initialize our application we just need to create instances of the views and call the &lt;code&gt;render()&lt;/code&gt; methods. &lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-js&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; hex = &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; HexView({&lt;span class=&quot;attr&quot;&gt;model&lt;/span&gt;: color, &lt;span class=&quot;attr&quot;&gt;el&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'#hex'&lt;/span&gt;});
hex.render();

&lt;span class=&quot;keyword&quot;&gt;var&lt;/span&gt; swatch = &lt;span class=&quot;keyword&quot;&gt;new&lt;/span&gt; SwatchView({&lt;span class=&quot;attr&quot;&gt;model&lt;/span&gt;: color, &lt;span class=&quot;attr&quot;&gt;el&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;'#swatch'&lt;/span&gt;});
swatch.render();​
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;http://jsfiddle.net/ynkJE/171/&quot;&gt;As you can see&lt;/a&gt; I can now enter a different hex code (say &lt;code&gt;#0000ff&lt;/code&gt;), click the update button and see the swatch change to blue.  &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dl.dropbox.com/u/8948049/backbone/blue.gif&quot; alt=&quot;complete backbone.js interface&quot; /&gt;
&lt;br/&gt;The completed user interface&lt;/p&gt;
&lt;p&gt;That concludes our exploration of the basic features of Backbone.js. If you are interesting in learning more about Backbone.js and building client-side web applications try For a complete introduction to Backbone.js, including guidance on how to structure and test backbone.js applications, try my &lt;a href=&quot;http://pluralsight.com/training/Courses/TableOfContents/backbone-fundamentals&quot;&gt;Backbone Fundamentals screencast&lt;/a&gt; course.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Fibonacci</title>
      <link>http://withouttheloop.com/articles/2012-02-15-Fibonacci/</link>
      <pubDate>Wed, 15 Feb 2012 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2012-02-15-Fibonacci/</guid>
      <author></author>
      <description>&lt;p&gt;Here is the fibonacci sequence calculated in haskell (1 to 100):&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-haskell&quot;&gt;&lt;span class=&quot;title&quot;&gt;fibo&lt;/span&gt; :: &lt;span class=&quot;type&quot;&gt;Int&lt;/span&gt; -&amp;gt; &lt;span class=&quot;type&quot;&gt;Int&lt;/span&gt;
&lt;span class=&quot;title&quot;&gt;fibo&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt; = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;title&quot;&gt;fibo&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt; = &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;title&quot;&gt;fibo&lt;/span&gt; n = (fibo (n&lt;span class=&quot;number&quot;&gt;-1&lt;/span&gt;)) + (fibo (n&lt;span class=&quot;number&quot;&gt;-2&lt;/span&gt;))

&lt;span class=&quot;title&quot;&gt;prn&lt;/span&gt; = map fibo [&lt;span class=&quot;number&quot;&gt;1.&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;.100&lt;/span&gt;]

&lt;span class=&quot;title&quot;&gt;prn&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and here it is in CoffeeScript&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-coffeescript&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;title&quot;&gt;fibo&lt;/span&gt; = &lt;span class=&quot;params&quot;&gt;(n)&lt;/span&gt; -&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; n &lt;span class=&quot;keyword&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;or&lt;/span&gt; n &lt;span class=&quot;keyword&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; n

  fibo(n&lt;span class=&quot;number&quot;&gt;-1&lt;/span&gt;) + fibo(n&lt;span class=&quot;number&quot;&gt;-2&lt;/span&gt;)

&lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; i &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; [&lt;span class=&quot;number&quot;&gt;1.&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;.100&lt;/span&gt;]
    &lt;span class=&quot;built_in&quot;&gt;console&lt;/span&gt;.log fibo(i)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Both of these take forever to execute. Curiously the CoffeeScript version is an order of magnitude faster. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>Sharing client and server validation</title>
      <link>http://withouttheloop.com/articles/2012-02-14-shared-validation/</link>
      <pubDate>Tue, 14 Feb 2012 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2012-02-14-shared-validation/</guid>
      <author></author>
      <description>&lt;p&gt;Client-side web applications (SPAs whatever) must perform client-side validation to achieve the required responsiveness. But the client is not a secure environment, so client-side validation is a convenience, not to be trusted. Validation has to be performed server-side to ensure security and data correctness. &lt;/p&gt;
&lt;h2 id=&quot;traditional-solutions-to-the-client-server-validation-problem&quot;&gt;Traditional Solutions to the Client / Server Validation Problem&lt;/h2&gt;
&lt;h3 id=&quot;shared-metadata&quot;&gt;Shared Metadata&lt;/h3&gt;
&lt;p&gt;Asp.net mvc exports validation metadata from server-side models and embeds it into form markup. This process is distributed throughout mvc’s form helpers. Each time a form element is generated the framework adds data- attributes to that element that describe that element’s validation. &lt;/p&gt;
&lt;p&gt;On the client-side a script runs that reads the validation metadata from the data- validation attributes and translates that metadata into a format suited to a client-side validation framework (asp.net mvc uses jquery.validation).&lt;/p&gt;
&lt;p&gt;By sharing metadata between the server and the client it is possible to have a validation framework on each side automatically working with the same metadata.&lt;/p&gt;
&lt;h3 id=&quot;doing-it-twice&quot;&gt;Doing It Twice&lt;/h3&gt;
&lt;p&gt;The solution that I am currently using is to implement completely separate validation - once on the client and once on the server. It works, but it is frustrating and boring. There is also a maintenance burden in keeping the validations synchronized.&lt;/p&gt;
&lt;h2 id=&quot;moving-client-side-validation-to-the-server&quot;&gt;Moving Client-Side Validation to the Server&lt;/h2&gt;
&lt;p&gt;The idea I have been considering is to move the client-side validation to the server. Client-side validation tests javascript objects against validation metadata and builds a set of results. Why can’t we do that on the server?&lt;/p&gt;
&lt;p&gt;My idea is to write a custom model binder that binds json data posted to the server. The post would have to include metadata that defines the schema of the data, so that we can lookup the required validation metadata. A JavaScript interpreter can then be used to apply the validation. &lt;/p&gt;
&lt;p&gt;The strength of this idea is that it uses the same validation engine and validation metadata on the client and the server. The validation only needs to be tested once and cannot possibly get out of sync.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Testing backbone models</title>
      <link>http://withouttheloop.com/articles/2012-02-13-testing-backbone-models/</link>
      <pubDate>Mon, 13 Feb 2012 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2012-02-13-testing-backbone-models/</guid>
      <author></author>
      <description>&lt;p&gt;This is this first in a planned series discussing the specifics of testing applications built with Backbone.js. &lt;/p&gt;
&lt;p&gt;Of all the components of a Backbone.js application Models are the easiest to test because they don’t have a lot of dependencies. The high level testing approach I use is:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Initialize a model with a specific state&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Test that the model’s behavior matches expectations&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Goto 1.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;testing-a-rectangle-model&quot;&gt;Testing a Rectangle Model&lt;/h2&gt;
&lt;p&gt;Imagine a Backbone model that represents a rectangle, with length and width properties. It has the following specification:&lt;/p&gt;
&lt;h3 id=&quot;rectangle-specification&quot;&gt;Rectangle Specification&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Rectangle  &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;   with length 7 and width 4  &lt;/p&gt;
&lt;blockquote&gt;
&lt;pre&gt;&lt;code&gt;   should have an area of 28  
   should have a perimeter of 22  
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;jasmine-specification&quot;&gt;Jasmine Specification&lt;/h3&gt;
&lt;p&gt;We can express the rectangle specification using the syntax of the &lt;a href=&quot;http://pivotal.github.com/jasmine/&quot;&gt;Jasmine testing tool&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;describe(&amp;#39;Rectangle&amp;#39;, function () {
  describe(&amp;#39;with length 7 and width 4&amp;#39;, function () {
    it(&amp;#39;should have an area of 28&amp;#39;, function () { 
      // assert expectations here
    });
    it(&amp;#39;should have a perimeter of 22&amp;#39;, function () { 
      // assert expectations here
    });
  });
});
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and add the expectations to get a failing test:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;describe(&amp;#39;Rectangle&amp;#39;, function() {
    var rectangle;

    beforeEach(function() {
        rectangle = new app.Rectangle();
    });

    describe(&amp;#39;with length 7 and width 4&amp;#39;, function() {
        beforeEach(function() {
            rectangle.set({
                length: 7,
                width: 4
            });
        });

        it(&amp;#39;should have an area of 28&amp;#39;, function() {
            expect(rectangle.area()).toBe(28);
        });
        it(&amp;#39;should have a perimeter of 22&amp;#39;, function() {
            expect(rectangle.perimeter()).toBe(22);
        });
    });
});
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;the-rectangle-model&quot;&gt;The Rectangle Model&lt;/h2&gt;
&lt;p&gt;The final step is to implement the Rectangle model to make the tests pass:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var app = {};

(function (shapes) {
    shapes.Rectangle = Backbone.Model.extend({
        area: function () {
            return this.get(&amp;#39;length&amp;#39;) * this.get(&amp;#39;width&amp;#39;);
        },
        perimeter: function () {
            return 2*this.get(&amp;#39;length&amp;#39;) + 2*this.get(&amp;#39;width&amp;#39;);
        }
    });
})(app);
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;et-voil-&quot;&gt;Et Voilà!&lt;/h2&gt;
&lt;p&gt;Testing Backbone models is trivial. Next in this series I will describe how I test Backbone views - a much more challenging proposition.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Backbone app framework</title>
      <link>http://withouttheloop.com/articles/2012-02-12-backbone-app-framework/</link>
      <pubDate>Sun, 12 Feb 2012 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2012-02-12-backbone-app-framework/</guid>
      <author></author>
      <description>&lt;p&gt;Backbone is a library of tools that simplify the design and implementation of client-side web applications. It is explicitly not a framwework. Backbone does not provide guidance about how to assemble an application. This post will be an initial attempt at filling that gap. It assumes an intermediate level of Backbone.js knowledge. If you have never used Backbone.js try &lt;a href=&quot;http://hackingon.net/post/Backbonejs-Basics.aspx&quot;&gt;Backbone.js Basics&lt;/a&gt; or the &lt;a href=&quot;http://backbonejs.org/&quot;&gt;Backbone.js homepage&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;the-application-root&quot;&gt;The Application Root&lt;/h2&gt;
&lt;p&gt;I like to provide a root object/namespace for my application. Let’s call it &lt;code&gt;app&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var app = {};
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;register-components-on-the-application-object&quot;&gt;Register Components on the Application Object&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;app.models =  {
    Post: Backbone.Model.extend({}),
    Comment: Backbone.Model.extend({})
};

app.views = {
    PostView: Backbone.View.extend({}),
    ComentView: Backbone.View.extend({})
};
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;de-couple-components-by-using-an-event-aggregator&quot;&gt;De-couple Components by using an Event Aggregator&lt;/h2&gt;
&lt;p&gt;An application event aggregator allows components to communicate indirectly. A simple event aggregator can be created by mixing the Backbone.Events modules into an application level object:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;app.eventAggregator = _.extend({}, Backbone.Events);
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;actions&quot;&gt;Actions&lt;/h2&gt;
&lt;p&gt;When a significant event occurs within your application raise an event. For example, the handler for the ‘add post’ button:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;_onAddPost: functin () {
    app.eventAggregator.trigger(&amp;#39;post:create&amp;#39;, this.model);
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Register an ‘action’ to handle the application event:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;app.actions = {
    createPost: Action.extend({
        event: &amp;#39;post:create&amp;#39;,
        handler: function (model) {
            var newPost = new app.Views.CreatePost({model: model});
            $(&amp;#39;#content&amp;#39;).html(newPost.render().el);
        }
    })
};
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;routing&quot;&gt;Routing&lt;/h2&gt;
&lt;p&gt;Use a route only when you want to change the url and handle the event. Otherwise just raise an event and register an action.&lt;/p&gt;
&lt;p&gt;When you do use a route, have it trigger an action. &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;app.routers = {
    postRouter: Backbone.Router.extend({
        &amp;#39;view/:postname&amp;#39;: function (postname) {
            app.eventAggregator.trigger(&amp;#39;post:view&amp;#39;, postname);
        }
    })
};
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;one-line-bootstrapping&quot;&gt;One Line Bootstrapping&lt;/h2&gt;
&lt;p&gt;Reduce your application bootstrapping to a single line.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;app.start();
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This makes it practical to test contexts that require the application to be in a usable state.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;describe(&amp;#39;adding a new post&amp;#39;, function () {
    describe(&amp;#39;initiate new post process&amp;#39;, function () {
        before(function() {
            app.start();
            var testModel = new app.models.post();
            app.eventAggregator.trigger(&amp;#39;post:create&amp;#39;, testModel);
        });
    });
});
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;start()&lt;/code&gt; function is the framework part. It registers the routers and actions and does any other required bootstrapping. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>My open source projects</title>
      <link>http://withouttheloop.com/articles/2012-02-11-my-oss-projects/</link>
      <pubDate>Sat, 11 Feb 2012 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2012-02-11-my-oss-projects/</guid>
      <author></author>
      <description>&lt;p&gt;I have a lot of projects on github now, some active and some archival. This post is a short summary of the projects that I actively maintain. &lt;/p&gt;
&lt;h2 id=&quot;watchn&quot;&gt;watchn&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/liammclennan/watchn&quot;&gt;https://github.com/liammclennan/watchn&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Watchn is a node-based file system watcher. It can be used to trigger actions when specific file system changes are detected. I use it to drive &lt;a href=&quot;http://blog.objectmentor.com/articles/2007/09/20/continuous-testing-explained&quot;&gt;continuous testing&lt;/a&gt; and for automating build tasks.&lt;/p&gt;
&lt;h2 id=&quot;git-deploy&quot;&gt;git-deploy&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/liammclennan/git-deploy&quot;&gt;https://github.com/liammclennan/git-deploy&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;git-deploy is a simple git based deployment tool. Push changes to a deployment branch and click a button to deploy. git-deploy can also run pre and post deployment scripts.&lt;/p&gt;
&lt;h2 id=&quot;snap&quot;&gt;snap&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/liammclennan/snap&quot;&gt;https://github.com/liammclennan/snap&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;snap is an automatic browser reloader for live testing web pages. It uses watchn to detect file system changes, which then cause the browser to reload. Useful for web development and for browser based testing. Similar to livereload except its free and works on windows.&lt;/p&gt;
&lt;h2 id=&quot;gistblog&quot;&gt;gistblog&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/liammclennan/gistblog&quot;&gt;https://github.com/liammclennan/gistblog&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;gistblog is my gist-based blog engine that powers &lt;a href=&quot;http://withouttheloop.com/&quot;&gt;my blog&lt;/a&gt;. &lt;/p&gt;
&lt;h2 id=&quot;backbone-server&quot;&gt;backbone-server&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/liammclennan/backbone-server&quot;&gt;https://github.com/liammclennan/backbone-server&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I use it for backbone but backbone-server is actually a generic non-persistent RESTful http server. Start the server and begin storing and retrieving resources. Data is stored in memory so it is lost when the server stops. Useful for testing and teaching backbone. See &lt;a href=&quot;http://jsfiddle.net/ynkJE/24/&quot;&gt;the demo&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;javascript-koans&quot;&gt;JavaScript Koans&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/liammclennan/JavaScript-Koans&quot;&gt;https://github.com/liammclennan/JavaScript-Koans&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;JavaScript koans is an interactive learning environment that uses failing tests to interactively teach JavaScript.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Connascence of methods</title>
      <link>http://withouttheloop.com/articles/2012-02-10-connascence-of-methods/</link>
      <pubDate>Fri, 10 Feb 2012 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2012-02-10-connascence-of-methods/</guid>
      <author></author>
      <description>&lt;p&gt;From wikipedia:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Two software components are connascent if a change in one would require the other to be modified in order to maintain the overall correctness of the system.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Connascence is a useful tool for discussing different types of coupling that occur within software. &lt;/p&gt;
&lt;p&gt;Again from wikipedia, “connascence of name is when multiple components must agree on the name of an entity”. Connascence of name one is of the list harmful and most unavoidable types of connascence because it is simple to reason about and change. While connascence of name is still connascence, and therefore bad, it is among the most amenable to refactoring. If the name of something changes then everything that refers to that thing by name must also change. This is a simple change that can be mostly statically determined and applied by tools. &lt;/p&gt;
&lt;p&gt;Connascence of position is present when changing the order of something necessitates a change elsewhere. An example is the order of function arguments. If the order of a function’s arguments is changed then every client of that function must also change. Connascence of position is worse than connascence of name (usually) because it is less explicit and therefore more difficult to reason about and successfully change. &lt;/p&gt;
&lt;h2 id=&quot;from-connascence-of-position-to-connascence-of-name&quot;&gt;From connascence of position to connascence of name&lt;/h2&gt;
&lt;p&gt;Some modern languages have slowly been migrating to connascence of name from connascence of position. As well as converting to a less harmful form of coupling this has the additional benefit of documenting the client-side of a method call. &lt;/p&gt;
&lt;h3 id=&quot;ruby&quot;&gt;Ruby&lt;/h3&gt;
&lt;p&gt;Ruby supports positional method arguments.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def full_name(first_name, middle_name, last_name)
    &amp;quot;#{first_name} #{middle_name} #{last_name}&amp;quot;
end

p full_name &amp;#39;Eric&amp;#39;, &amp;#39;Arthur&amp;#39;, &amp;#39;Blair&amp;#39;
=&amp;gt; &amp;quot;Eric Arthur Blair&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;but many ruby apis prefer the use of a single hash containing the method arguments:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def full_name(name)
    &amp;quot;#{name[:first]} #{name[:middle]} #{name[:last]}&amp;quot;
end

p full_name :first=&amp;gt;&amp;#39;Eric&amp;#39;, :middle=&amp;gt;&amp;#39;Arthur&amp;#39;, :last=&amp;gt;&amp;#39;Blair&amp;#39;
=&amp;gt; &amp;quot;Eric Arthur Blair&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;this has the benefit of converting positional parameters to named parameters and therefore connascence of position to connascence of name.&lt;/p&gt;
&lt;h3 id=&quot;javascript&quot;&gt;JavaScript&lt;/h3&gt;
&lt;p&gt;JavaScript has adopted the same convention. While positional function arguments work:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function fullName(first, middle, last) {
    return first + &amp;#39; &amp;#39; + middle + &amp;#39; &amp;#39; + last;
}

fullName(&amp;#39;Eric&amp;#39;, &amp;#39;Arthur&amp;#39;, &amp;#39;Blair&amp;#39;);
=&amp;gt; &amp;quot;Eric Arthur Blair&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;most apis favour named arguments by passing a single object containing the method arguments:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function fullName(name) {
    return name.first + &amp;#39; &amp;#39; + name.middle + &amp;#39; &amp;#39; + name.last;
}

fullName({ first: &amp;#39;Eric&amp;#39;, middle: &amp;#39;Arthur&amp;#39;, last: &amp;#39;Blair&amp;#39;});
=&amp;gt; &amp;quot;Eric Arthur Blair&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;c-sharp&quot;&gt;C sharp&lt;/h3&gt;
&lt;p&gt;C# now supports named arguments, but there usage is not popular. C# and .net has a dependable history of adopting, after a delay, the technology and techniques that have become dominant on other platforms. Therefore, I predict that usage of named method arguments in C# will increase over the next few years. Interestingly, C# is the only one of the three languages discussed that has a specific language feature for named arguments and it is also the only one that does not require a change to the definition of the method to take advantage of named arguments. The decision to use or not use named arguments is entirely at the client’s discretion.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;string FullName(string first, string middle, string last) {
    return String.Format(&amp;quot;{0} {1} {2}&amp;quot;, first, middle, last);
}

FullName(first: &amp;quot;Eric&amp;quot;, middle: &amp;quot;Arthur&amp;quot;, last: &amp;quot;Blair&amp;quot;);
=&amp;gt; &amp;quot;Eric Arthur Blair&amp;quot;
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>Hosted backbone server</title>
      <link>http://withouttheloop.com/articles/2012-02-09-hosted-backbone-server/</link>
      <pubDate>Thu, 09 Feb 2012 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2012-02-09-hosted-backbone-server/</guid>
      <author></author>
      <description>&lt;p&gt;This morning I published my &lt;a href=&quot;https://gist.github.com/2956872&quot;&gt;zero-config backbone.js server&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;It is an in-memory, restful server that implements the protocol required by Backbone.js, which is basically the same as couchdb except that ‘create’ returns the new id. As such it can be used for any purpose requiring temporary resource persistence. The service provides no durability at all. If it restarts all of the data is lost.&lt;/p&gt;
&lt;p&gt;I’m now running a public instance at &lt;a href=&quot;http://withouttheloop.com:3002&quot;&gt;http://withouttheloop.com:3002&lt;/a&gt;. It works on my machine, don’t blame me if it crashes your space shuttle. No warranty of any kind. Obviously. &lt;/p&gt;
&lt;p&gt;To use with backbone set your model or collection’s url property to &lt;code&gt;http://withouttheloop.com:3002/[yourresourcetype]&lt;/code&gt;. Have a look at &lt;a href=&quot;http://jsfiddle.net/ynkJE/24/&quot;&gt;this jsfiddle&lt;/a&gt;. If you run the example and look in Chrome’s developer tools networking tab you will see:&lt;/p&gt;
&lt;h3 id=&quot;request&quot;&gt;Request&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;POST /books HTTP/1.1
Host: withouttheloop.com:3002
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;response&quot;&gt;Response&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;HTTP/1.1 200 OK
X-Powered-By: Express

{&amp;quot;title&amp;quot;:&amp;quot;Midnight in the garden of good and evil&amp;quot;,&amp;quot;author&amp;quot;:&amp;quot;John Berendt&amp;quot;}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The model is persisted to the hosted backbone server. &lt;/p&gt;
&lt;p&gt;The set of supported operations (which match those required by backbone.js) is:&lt;/p&gt;
&lt;h2 id=&quot;create&quot;&gt;Create&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;$ curl -X POST http://withouttheloop.com:3002/people -H &amp;quot;Content-Type: application/json&amp;quot; -d &amp;#39;{&amp;quot;name&amp;quot;: &amp;quot;Bob&amp;quot;, &amp;quot;age&amp;quot;:&amp;quot;28&amp;quot;}&amp;#39;

=&amp;gt; {id: 1}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;update&quot;&gt;Update&lt;/h2&gt;
&lt;p&gt;Bob had a birthday&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ curl -X PUT http://withouttheloop.com:3002/people/1 -H &amp;quot;Content-Type: application/json&amp;quot; -d &amp;#39;{&amp;quot;name&amp;quot;: &amp;quot;Bob&amp;quot;, &amp;quot;age&amp;quot;:&amp;quot;29&amp;quot;, &amp;quot;id&amp;quot;: 1}&amp;#39;

=&amp;gt; OK
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;read-the-collection&quot;&gt;Read the Collection&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;$ curl http://withouttheloop.com:3002/people -H &amp;quot;Content-Type: application/json&amp;quot;

=&amp;gt; [{&amp;quot;name&amp;quot;:&amp;quot;Jane&amp;quot;,&amp;quot;age&amp;quot;:&amp;quot;32&amp;quot;,&amp;quot;id&amp;quot;:0},{&amp;quot;name&amp;quot;:&amp;quot;Bob&amp;quot;,&amp;quot;age&amp;quot;:&amp;quot;29&amp;quot;, &amp;quot;id&amp;quot;:1}]
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;read-a-resource&quot;&gt;Read a Resource&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;$ curl http://withouttheloop.com:3002/people/1 -H &amp;quot;Content-Type: application/json&amp;quot;

=&amp;gt; {&amp;quot;name&amp;quot;:&amp;quot;Bob&amp;quot;,&amp;quot;age&amp;quot;:&amp;quot;29&amp;quot;, &amp;quot;id&amp;quot;:1}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;destroy&quot;&gt;Destroy&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;$ curl -X DELETE http://withouttheloop.com:3002/people/1 -H &amp;quot;Content-Type: application/json&amp;quot;

=&amp;gt; OK
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>Backbone server</title>
      <link>http://withouttheloop.com/articles/2012-02-08-backbone-server/</link>
      <pubDate>Wed, 08 Feb 2012 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2012-02-08-backbone-server/</guid>
      <author></author>
      <description>&lt;p&gt;&lt;a href=&quot;https://github.com/liammclennan/backbone-server&quot;&gt;Backbone-Server&lt;/a&gt; is a zero configuration backbone.js server. For teaching, experimentation and debugging it provides an instant server-side for backbone.js apps. Once installed it is started like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;node rasterver.js
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then from the client you can work with models:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var Person = Backbone.Model.extend({}),
People = Backbone.Collection.extend({
    model: Person,
    url: &amp;#39;http://localhost:3000/People&amp;#39;
}),
people = new People();
people.add({name: &amp;#39;John&amp;#39;, age: 25});
people.at(0).save();
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That is enough to get the model saved to the server. Fetch, update and destroy all work properly. &lt;/p&gt;
&lt;p&gt;The server stores the collection data in memory, so when the server stops the data is lost. This is not a good choice for production. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>Team pomodoro</title>
      <link>http://withouttheloop.com/articles/2012-02-07-team-pomodoro/</link>
      <pubDate>Tue, 07 Feb 2012 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2012-02-07-team-pomodoro/</guid>
      <author></author>
      <description>&lt;p&gt;Many people like the pomodoro technique because it helps them focus intently on tasks. It is also helpful for preventing interruptions. If your team, and extended team, know that you are in the middle of a pomodoro then they know to avoid interrupting you. But how do you communicate that you have a pomodoro in progress? &lt;/p&gt;
&lt;p&gt;Team Pomodoro combines a tradtional pomodoro timer and a dashboard showing the status of each team member’s pomodoros. A person can see at a glance who is currently available and when each person will be available. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://github.com/liammclennan/eclipsewebsolutions.com.au/raw/master/images/blog/team-pomodoro.png&quot; alt=&quot;Team Pomodoro screen shot&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;additional-features&quot;&gt;Additional Features&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Add features for messaging team members. Choice of &lt;ul&gt;
&lt;li&gt;interrupt&lt;/li&gt;
&lt;li&gt;queue until end of pomodoro&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    <item>
      <title>Backbone sandbox</title>
      <link>http://withouttheloop.com/articles/2012-02-06-backbone-sandbox/</link>
      <pubDate>Mon, 06 Feb 2012 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2012-02-06-backbone-sandbox/</guid>
      <author></author>
      <description>&lt;p&gt;&lt;a href=&quot;http://withouttheloop.com&quot; border=&quot;0&quot;&gt;&lt;img src=&quot;https://github.com/liammclennan/gistblog/raw/master/public/img/return-button.png&quot; align=&quot;right&quot; hspace=&quot;10&quot; vspace=&quot;10&quot; alt=&quot;return to withouttheloop.com&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&quot;backbone-js-sandbox&quot;&gt;Backbone.js Sandbox&lt;/h1&gt;
&lt;p&gt;If you are working with Backbone.js it is handy to have a sandbox environment for testing simple things. &lt;/p&gt;
&lt;p&gt;This &lt;a href=&quot;http://jsfiddle.net/ynkJE/&quot;&gt;jsfiddle&lt;/a&gt; has jQuery, backbone and underscore already loaded. Type your code in the JavaScript text area, as well as markup and css in their respective text areas as required, and click the run button. I use it all the time. &lt;/p&gt;
</description>
    </item>
    <item>
      <title>Extending Underscore.js - findOr</title>
      <link>http://withouttheloop.com/articles/2012-02-05-findOr/</link>
      <pubDate>Sun, 05 Feb 2012 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2012-02-05-findOr/</guid>
      <author></author>
      <description>&lt;p&gt;As good as &lt;a href=&quot;http://underscorejs.org&quot;&gt;underscore.js&lt;/a&gt; is, sometimes you want to add functions of your own, and you can, using the &lt;a href=&quot;http://underscorejs.org/#mixin&quot;&gt;mixin() function&lt;/a&gt;. &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;_.mixin({
  capitalize : function(string) {
    return string.charAt(0).toUpperCase() + string.substring(1).toLowerCase();
  }
});
_(&amp;quot;fabio&amp;quot;).capitalize();
=&amp;gt; &amp;quot;Fabio&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;findor&quot;&gt;findOr&lt;/h2&gt;
&lt;p&gt;Underscore has a find method that returns the first element of a collection that matches a supplied predicate. For example, it can be used to find the first even number in a set:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var isEven = function (num) {
  return num % 2 === 0;
}

_([1,2,3,4,5]).find(isEven);
=&amp;gt; 2
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;findOr is a function I mixed-in to underscore so that I could have find return a default value if no element matches the predicate.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;_([1,2,3]).findOr(isEven, &amp;#39;no even numbers&amp;#39;);
=&amp;gt; 2

_([1,3]).findOr(isEven, &amp;#39;no even numbers&amp;#39;);
=&amp;gt; &amp;#39;no even numbers&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The implementation, using underscore’s mixin function, is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;_.mixin({
  &amp;#39;findOr&amp;#39;: function(list, iterator, defaultValue, context) {
    return this.find(list, iterator, context) || defaultValue;
  }
});
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Try the executable demo on &lt;a href=&quot;http://jsfiddle.net/ynkJE/22/&quot;&gt;jsfiddle&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    <item>
      <title>snap</title>
      <link>http://withouttheloop.com/articles/2012-02-04-snap/</link>
      <pubDate>Sat, 04 Feb 2012 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2012-02-04-snap/</guid>
      <author></author>
      <description>&lt;p&gt;&lt;a href=&quot;http://withouttheloop.com&quot; border=&quot;0&quot;&gt;&lt;img src=&quot;https://github.com/liammclennan/gistblog/raw/master/public/img/return-button.png&quot; align=&quot;right&quot; hspace=&quot;10&quot; vspace=&quot;10&quot; alt=&quot;return to withouttheloop.com&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This file is a fantasy readme for an tool that doesn’t exist yet. I wrote it in an attempt to apply &lt;a href=&quot;http://tom.preston-werner.com/2010/08/23/readme-driven-development.html&quot;&gt;readme driven development&lt;/a&gt;. The idea is to force yourself to define a vision for your product/tool/whatever before starting to build anything.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id=&quot;snap&quot;&gt;Snap&lt;/h1&gt;
&lt;p&gt;snap is a tool that automatically reloads your browser based on filesystem events. For example, it can be configured to automatically reload the webpage you are working on when any of your html files are modified.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;lang-js&quot;&gt;snap({
  &lt;span class=&quot;string&quot;&gt;'.'&lt;/span&gt;: &lt;span class=&quot;regexp&quot;&gt;/.+\.html/&lt;/span&gt;
});
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;usage&quot;&gt;Usage&lt;/h2&gt;
&lt;p&gt;Create a snap script (as above) and start the server:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;node snap mysnapscript.js
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Add the following script to the page that you want auto-reloaded:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;script src=&amp;quot;http://localhost:9876/snap.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    <item>
      <title>Object-object mapping</title>
      <link>http://withouttheloop.com/articles/2012-02-03-object-object-mapping/</link>
      <pubDate>Fri, 03 Feb 2012 20:32:00 +1000</pubDate>
      <guid isPermaLink="true">http://withouttheloop.com/articles/2012-02-03-object-object-mapping/</guid>
      <author></author>
      <description>&lt;h1 id=&quot;object-object-mapping-why-i-don-t-use-automapper&quot;&gt;Object-object Mapping - Why I don’t use Automapper&lt;/h1&gt;
&lt;p&gt;At the boundaries of an application it is often nice to map objects from one form to another. The most common example is mapping domain entities to view models, or mapping to dtos for network transfer. &lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/AutoMapper/AutoMapper/wiki/Getting-started&quot;&gt;Automapper&lt;/a&gt; is a library for removing the duplication from object-object mapping code by mapping by convention. When the conventions don’t map the way you want you can explicitly map properties. &lt;/p&gt;
&lt;p&gt;After using AutoMapper on a couple of projects I have stopped using it. The problem is that the convention based mappings introduce annoying bugs when property names change  or the object graph changes. When a change breaks the convention it results in a runtime exception. Very annoying. &lt;/p&gt;
&lt;h2 id=&quot;what-i-do-instead&quot;&gt;What I Do Instead&lt;/h2&gt;
&lt;p&gt;My observations from using automapper are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;If you use the convention-based mapping and a property is later renamed that becomes a runtime error and a common source of annoying bugs. &lt;/li&gt;
&lt;li&gt;If you don’t use convention-based mapping (ie you explicitly map each property) then you are just using automapper to do your projection, which is unnecessary complexity.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For larger projects I like to implement explicit type mappers and register them in an IoC container. The advantages are:
mappers are explicit. Easy to identify and test mappings
the mappers can have their own dependencies. The consumers of the mappers don’t have to depend on the mappers dependencies.&lt;/p&gt;
&lt;p&gt;=======================================================================================================================================&lt;/p&gt;
&lt;p&gt;public interface IMapper&lt;T1,T2&gt; 
{
    T2 Map(T1 input);
}&lt;/p&gt;
&lt;p&gt;public class MapAppleToOrange : IMapper&lt;Apple, Orange&gt; 
{
   public MapAppleToOrange(/&lt;em&gt; opportunity for constructor injection here. Useful for mapping VMs -&amp;gt; persisted models &lt;/em&gt;/ ISomeDependency dependency) 
   {} &lt;/p&gt;
&lt;p&gt;   Orange Map(Apple input) 
   {
       // map things here
       // make use of dependency
   }
}&lt;/p&gt;
&lt;p&gt;// usage&lt;/p&gt;
&lt;p&gt;public class HomeController
{
    // let the IoC container resolve the required mappers
    // note that HomeController does not depend on ISomeDependency 
    public HomeController(IMapper&lt;Apple, Orange&gt; mapper) 
    {}&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public ActionResult Index(Apple apple) 
{
   // do some mapping
   return View(mapper.Map(apple));
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;}&lt;/p&gt;
</description>
    </item>
  </channel>
</rss>