<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Posts on Coder Frontline</title><link>https://www.coderfrontline.com/posts/</link><description>Recent content in Posts on Coder Frontline</description><generator>Hugo -- gohugo.io</generator><language>en-nz</language><copyright>Creative Commons Attribution 4.0 International License</copyright><lastBuildDate>Sun, 28 Feb 2021 09:00:00 +1300</lastBuildDate><atom:link href="https://www.coderfrontline.com/posts/index.xml" rel="self" type="application/rss+xml"/><item><title>Delete user workspace from TFS server</title><link>https://www.coderfrontline.com/delete-user-workspace-from-tfs-server/</link><pubDate>Sun, 28 Feb 2021 09:00:00 +1300</pubDate><guid>https://www.coderfrontline.com/delete-user-workspace-from-tfs-server/</guid><description>I&amp;rsquo;m here to share a useful technique to delete a TFS 1 workspace that no longer exists locally but is still registered on the server. This was an extremely frustrating endeavour due to the lack of clear documentation, so I hope this helps someone! Jump to solution
Git may be the source versioning control of choice for most developers today, but centralized source control systems like TFS and Subversion are still used by many older repositories.</description><content type="html"><![CDATA[<p>I&rsquo;m here to share a useful technique to delete a TFS <sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> workspace that no longer exists locally but is still registered on the server. This was an extremely frustrating endeavour due to the lack of clear documentation, so I hope this helps someone! <a href="#delete-tfs-workspace-of-ex-employee">Jump to solution</a></p>
<p>Git may be the source versioning control of choice for most developers today, but centralized source control systems like TFS and Subversion are still used by many older repositories. That is the case in my company, where we have 15 year-old source code in TFS while newer repositories are in Azure DevOps (Git).</p>
<p>I was doing a repository clean-up and wanted to remove NuGet packages that were downloaded and checked-in. This was common practice back in the day of unreliable/slow Internet but is generally frowned upon these days because it bloats up the repository over time. Old packages are not automatically deleted by TFS when they&rsquo;re upgraded so they stay in the repo. Have you met many devs who lovingly curate their packages or node_modules folder by hand?</p>
<p>Sorry, digression over! Anyway, when I tried to check in my Delete operation it failed with the dreaded error message:</p>
<pre><code class="language-terminal" data-lang="terminal">Unable to perform operation on $/repo/Service/Packages. The item $/repo/Service/Packages/Utility 1.09/utility.dll is locked in workspace DEMO206;Admin - Carol Danvers
</code></pre><figure>
    <img src="locked-workspace-error.webp"
         alt="Visual Studio output window displaying a locked workspace error when deleting files from TFS"/> <figcaption>
            <h4>Locked workspace error</h4>
        </figcaption>
</figure>

<p>There are different solutions to this issue depending on your specific situation:</p>
<ol>
<li>The user is still in the organisation and have their local environment: This is the easiest scenario to be in. Just ask the user to unlock the folder in Source Control Explorer.</li>
<li>The user is no longer in the organisation but their local environment still exists (i.e. their work laptop has not been wiped): You can ask IT to re-activate their account, log in as them, and unlock the folder. But it&rsquo;s easier to ask the TFS administrator to follow my steps below.</li>
<li>The user is no longer around and their local environment no longer exists (i.e. their work laptop has been wiped): My suggestion is to delete their entire workspace, which will also remove all locks that they owned. Ask the TFS administrator to follow my steps below.</li>
</ol>
<h2 id="delete-tfs-workspace-of-ex-employee">Delete TFS workspace of ex-employee</h2>
<h3 id="pre-requisites">Pre-requisites</h3>
<ol>
<li>TFS administrator permissions</li>
<li>Windows environment with Visual Studio installed, in order to get TF.exe command line tools. A recent version of Visual Studio like 2017 or 2019 will do.</li>
</ol>
<h3 id="get-list-of-tfs-workspaces-on-the-server">Get list of TFS workspaces on the server</h3>
<p>First, we want to get the list of TFS workspaces on the server so we have the exact names that we will need for the next step.</p>
<ol>
<li>Launch Developer Command Line or Developer PowerShell for Visual Studio. This makes sure TF.exe is in the PATH.</li>
<li>Modify and run the following command, which outputs details of all workspaces registered on the TFS server into an XML file.
<pre><code class="language-terminal" data-lang="terminal">TF workspaces /collection:http://tfsvc:8080/tfs/DemoTeamProject /Owner:* /Computer:* /format:XML &gt; c:\temp\workspaces.xml
</code></pre></li>
</ol>
<p>This will result in an output like this in workspaces.xml:</p>
<div class="highlight"><pre class="chroma"><code class="language-XML" data-lang="XML">  <span class="nt">&lt;Workspace</span> <span class="na">computer=</span><span class="s">&#34;DEMO206&#34;</span> <span class="na">islocal=</span><span class="s">&#34;true&#34;</span> <span class="na">name=</span><span class="s">&#34;DEMO206&#34;</span> <span class="na">ownerdisp=</span><span class="s">&#34;Admin - Carol Danvers&#34;</span> 
  <span class="na">ownerid=</span><span class="s">&#34;S-1-5-22-2456812397-2423433832-269712057-11353&#34;</span> <span class="na">ownertype=</span><span class="s">&#34;System.Security.Principal.WindowsIdentity&#34;</span> 
  <span class="na">owner=</span><span class="s">&#34;4d74d864-53dc-4d11-8095-7ec8bb9121f6&#34;</span> <span class="na">owneruniq=</span><span class="s">&#34;4d74d864-53dc-4d11-8095-7ec8bb9121f6&#34;</span><span class="nt">&gt;</span>
    <span class="nt">&lt;Comment</span> <span class="nt">/&gt;</span>
    <span class="nt">&lt;Folders&gt;</span>
      <span class="nt">&lt;WorkingFolder</span> <span class="na">local=</span><span class="s">&#34;C:\src\DemoProject&#34;</span> <span class="na">item=</span><span class="s">&#34;$/&#34;</span> <span class="nt">/&gt;</span>
    <span class="nt">&lt;/Folders&gt;</span>
    <span class="nt">&lt;LastAccessDate&gt;</span>2019-03-28T08:42:13.39+13:00<span class="nt">&lt;/LastAccessDate&gt;</span>
    <span class="nt">&lt;OwnerAliases&gt;</span>
      <span class="nt">&lt;string&gt;</span>DEMODOMAIN\a-cdanvers<span class="nt">&lt;/string&gt;</span>
      <span class="nt">&lt;string&gt;</span>a-cdanvers<span class="nt">&lt;/string&gt;</span>
      <span class="nt">&lt;string&gt;</span>Admin - Carol Danvers<span class="nt">&lt;/string&gt;</span>
    <span class="nt">&lt;/OwnerAliases&gt;</span>
  <span class="nt">&lt;/Workspace&gt;</span>
</code></pre></div><h3 id="delete-workspace">Delete workspace</h3>
<p>Next, we will delete the user workspace with a simple command, but we may need to try various permutations of the username.</p>
<ol>
<li>Launch Developer Command Line or Developer PowerShell again if you closed it.</li>
<li>Determine workspace name possibilities, which is usually a concatenation of the <code>name</code> element and one of the user identifiers. Referring to the sample XML above, the full workspace name could be one of the following:
<ol>
<li>DEMO206;Admin - Carol Danvers <code>name;ownerdisp</code></li>
<li>DEMO206;S-1-5-22-2456812397-2423433832-269712057-11353 <code>name;ownerid</code></li>
<li>DEMO206;DEMODOMAIN\a-cdanvers <code>name;OwnerAliases</code></li>
<li>DEMO206;a-cdanvers <code>name;OwnerAliases</code></li>
</ol>
</li>
<li>Modify and run the command below, trying out one workspace name combination at a time.
<pre><code class="language-terminal" data-lang="terminal">tf workspace /server:http://tfsvc:8080/tfs/DemoTeamProject /delete &quot; DEMO206;a- cdanvers&quot;
</code></pre></li>
</ol>
<p>If it&rsquo;s the wrong combination you will see error messages like this:</p>
<pre><code class="language-terminal" data-lang="terminal">TF14061: The workspace DEMO206;S-1-5-22-2456812397-2423433832-269712057-11353 does not exist.
TF14061: The workspace DEMO206;Admin - Carol Danvers does not exist.
</code></pre><p>If it&rsquo;s the right combination you will be prompted to confirm the deletion (and please do double-check!)</p>
<p><strong>Success!</strong></p>
<h3 id="references">References</h3>
<p>I figured out the different workspace name combinations on my own. If your situation is unique you can refer to the following references or ask a question on StackOverflow.</p>
<ul>
<li><a href="https://docs.microsoft.com/en-us/azure/devops/repos/tfvc/workspaces-command?view=azure-devops-2020">tf workspaces command (Microsoft Docs)</a></li>
<li><a href="https://docs.microsoft.com/en-us/azure/devops/repos/tfvc/workspace-command?view=azure-devops-2020">tf workspace command (Microsoft Docs)</a></li>
<li><a href="https://almguide.net/2019/01/10/cleanup-workspaces/">Cleanup workspaces</a></li>
</ul>
<section class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1" role="doc-endnote">
<p>I used &ldquo;TFS&rdquo; to refer to &ldquo;TFVC&rdquo; because TFS is commonly associated with TFVC. Actually, they are two separate things: TFS = Team Foundation Server is the server-based application that manages source control, work items, and pipelines. It is now known as Azure DevOps Server. TFVC = Team Foundation Version Control is the centralized source control system bundled with TFS. <a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</section>
]]></content></item><item><title>12 Days of Learning</title><link>https://www.coderfrontline.com/12-days-of-learning/</link><pubDate>Fri, 17 Apr 2020 11:08:00 +1200</pubDate><guid>https://www.coderfrontline.com/12-days-of-learning/</guid><description>The greatest challenge for developers who want to stay on the forefront of technology is the sheer amount of innovation happening everywhere. It is simply overwhelming for anyone to know everything. My advice for people starting out is to focus on one stack, e.g. React web apps, and get really comfortable with it so you build a solid technical foundation. It is still natural to feel like you&amp;rsquo;re falling behind when others talk about some cool tech they used.</description><content type="html"><![CDATA[<p>The greatest challenge for developers who want to stay on the forefront of technology is the sheer amount of innovation happening everywhere. It is simply overwhelming for anyone to know everything. My advice for people starting out is to focus on one stack, e.g. React web apps, and get really comfortable with it so you build a solid technical foundation. It is still natural to feel like you&rsquo;re falling behind when others talk about some cool tech they used. I feel it all the time, to be honest.</p>
<p>I am in the middle of changing jobs and had roughly two weeks of &lsquo;me&rsquo; time. I was planning to take a holiday but the Covid-19 pandemic scuppered any thoughts of that nature. Therefore, I decided to make this a time of learning instead. I called it my &ldquo;12 Days of Learning&rdquo; - one new tech each workday. My goal was not to become an expert on each topic by the end of 8 hours, but to know enough to hold a conversation about it. This means I:</p>
<ul>
<li>Understand the rationale behind this technology</li>
<li>Know the right scenarios to apply this technology</li>
<li>Possess basic hands-on knowledge and can read the syntax</li>
</ul>
<p>I had set out an ideal plan of what I wanted to learn but real life has a way of throwing banana peels to slip on. I adapted my plans, and the following is a summary of my thoughts on each technology I picked up, along with the learning resources I used. Here&rsquo;s why I picked those subjects:</p>
<ul>
<li>Must cover a large surface area. I selected topics around web, backend, databases, and infrastructure.</li>
<li>I wanted to learn about the clever architectures, designs, and decisions made by people much smarter than I am.</li>
<li>It would be unlikely for me to use some of those subjects professionally, e.g. Ethereum blockchain programming and Kafka.</li>
</ul>
<h2 id="12-days-of-learning-topics">12 Days of Learning Topics</h2>
<ol>
<li><a href="#aspectoriented-programming-aop">Aspect-Oriented Programming (AOP)</a></li>
<li><a href="#graphql">GraphQL</a></li>
<li><a href="#kafka">Kafka</a></li>
<li><a href="#ethereum-blockchain-programming">Ethereum Blockchain programming</a></li>
<li><a href="#ssis">SSIS</a></li>
<li><a href="#aws-lambda-with-net">AWS Lambda with .Net</a></li>
<li><a href="#amazon-cloudsearch">Amazon CloudSearch</a></li>
<li><a href="#terraform">Terraform</a></li>
<li><a href="#react-state-management">React state management</a></li>
<li><a href="#pwa">PWA</a></li>
<li><a href="#sre">SRE</a></li>
<li><a href="#golang">GoLang</a></li>
<li><a href="#feature-management">Feature Management</a></li>
</ol>
<h2 id="aspect-oriented-programming-aop">Aspect-Oriented Programming (AOP)</h2>
<p>Learning sources:</p>
<ul>
<li>This fantastic <a href="https://www.manning.com/books/dependency-injection-principles-practices-patterns">Dependency Injection e-book</a></li>
</ul>
<p>Thoughts:</p>
<ul>
<li>AOP is a really interesting technique, which many developers will be uncomfortable with until they encounter the problems that AOP tries to solve</li>
<li>I am 💯% going to recommend this approach when I come across suitable scenarios</li>
</ul>
<h2 id="graphql">GraphQL</h2>
<p>Learning sources:</p>
<ul>
<li>Pluralsight: <a href="https://app.pluralsight.com/library/courses/building-graphql-apis-aspdotnet-core/table-of-contents">Building GraphQL APIs with ASP.NET Core</a></li>
</ul>
<p>Thoughts:</p>
<ul>
<li>GraphQL is a useful paradigm in itself, and it makes building web clients so much easier when you can succintly describe the shape of the data you want</li>
<li>However, it feels very unnatural to integrate it with Entity Framework and SQL Server. I end up introducing another abstraction layer - essentially re-implmenting EF methods in a format GraphQL understands. My many &lsquo;repository&rsquo; methods still remain rather than be replaced by GraphQL, which is what I was hoping for.</li>
<li>I see a bright future for GraphQL-like technologies, but it must be paired with a data store that has native support for GraphQL. I have so far heard of FaunaDB and Dgraph. I might add them to my next learning backlog.</li>
</ul>
<h2 id="kafka">Kafka</h2>
<p>Learning sources:</p>
<ul>
<li>Pluralsight: <a href="https://app.pluralsight.com/library/courses/designing-event-driven-applications-apache-kafka-ecosystem/table-of-contents">Designing Event-driven Applications Using Apache Kafka Ecosystem</a></li>
<li><a href="https://docs.confluent.io/current/quickstart/cos-docker-quickstart.html#cos-docker-quickstart">Confluent Community Quick Start</a></li>
</ul>
<p>Thoughts:</p>
<ul>
<li>Kafka appeared on my tech radar after a presentation by Confluent. I like the idea of a messaging model but Kafka appeared to take this many steps further.</li>
<li>It is definitely an &ldquo;enterprise&rdquo; solution. Entirely overkill for small startups based on the number of servers needed and maintenance required. This can be a niche filled by cloud providers such as <a href="https://aws.amazon.com/msk/">Amazon Managed Streaming for Apache Kafka (Amazon MSK)</a> but the pricing is still geared towards customers with cash to spend.</li>
<li>The possibility of using Kafka to do event sourcing intrigued me but I did not learn how to do this in the course.</li>
<li>I am especially impressed with how easy it is to use KSQL to set up streams and queries with a SQL-like language.</li>
</ul>
<h2 id="ethereum-blockchain-programming">Ethereum Blockchain programming</h2>
<p>Learning sources:</p>
<ul>
<li>Pluralsight: <a href="https://app.pluralsight.com/library/courses/975932a6-f99a-4c21-97ea-0353070a007d">Developing Applications on Ethereum Blockchain</a></li>
</ul>
<p>Thoughts:</p>
<ul>
<li>It was quite easy to get started with learning with a browser IDE like <a href="https://remix.ethereum.org/">Remix</a></li>
<li>The Solidity programming language is close enough to C-based languages which makes it easy to pick-up</li>
<li>I like Solidity&rsquo;s blockchain-specific enhancements to the language. They are quite intuitive.</li>
<li>Truffle framework supports unit-testing Solidity. Yes!</li>
<li>Ethereum blockchain is secure, but there are still loopholes and you can still write insecure code. It is not automatically secure.</li>
<li>Cost is calculated based on the amount of &lsquo;gas&rsquo; your code needs to run, so it really forces the developer to be efficient.</li>
</ul>
<h2 id="ssis">SSIS</h2>
<p>Learning sources:</p>
<ul>
<li>Pluralsight: <a href="https://app.pluralsight.com/library/courses/extracting-transforming-data-ssis/table-of-contents">Extracting and Transforming Data in SSIS</a></li>
</ul>
<p>Thoughts:</p>
<ul>
<li>SSIS has been around a long time but its ease of use and flexibility will ensure its longevity while relational databases are a thing.</li>
<li>My main concerns are around testability and error handling. It requires very manual testing approaches.</li>
<li>It has to drag legacy support along, such as multiple database connection drivers and Windows-only runtime, which will exclude it from many people&rsquo;s minds when starting a greenfield project. It really shouldn&rsquo;t.</li>
<li>I can see how it has influenced modern low-code platforms like Zapier and Microsoft Flow (Power Automate).</li>
<li>I also watched a few clips on Azure Data Factory, and it&rsquo;s clear they work in tandem, and ADF does not replace SSIS.</li>
</ul>
<h2 id="aws-lambda-with-net">AWS Lambda with .Net</h2>
<p>Learning sources:</p>
<ul>
<li>Official docs, e.g. <a href="https://docs.aws.amazon.com/lambda/latest/dg/lambda-csharp.html">Building Lambda Functions with C#</a> and <a href="https://docs.aws.amazon.com/lambda/latest/dg/csharp-package-cli.html">.Net Core CLI</a></li>
</ul>
<p>Thoughts from someone used to Microsoft Azure:</p>
<ul>
<li>Visual Studio (Windows) <a href="https://aws.amazon.com/visualstudio/">AWS Toolkit</a> is pretty good - it makes deployment as easy as deploying to Azure Functions</li>
<li>Lambdas do not have a HTTP endpoint built-in, unlike Azure Functions. I need to bolt on AWS API Gateway to call it. This requires changing how I deal with the default lambda function parameters significantly, which confused me for a quite awhile.</li>
<li>Resource groups in AWS are an optional construct unlike Azure whereby everything must be in a Resource Group.</li>
<li>IAM policies are very confusing. I gave up and kept my APIs open. From what I gather, I need to grant permissions on both the calling resource and the called resource, but I&rsquo;m not sure how to construct the policy code.</li>
</ul>
<h2 id="amazon-cloudsearch">Amazon CloudSearch</h2>
<p>Learning sources:</p>
<ul>
<li>Official docs, e.g. <a href="https://docs.aws.amazon.com/cloudsearch/latest/developerguide/what-is-cloudsearch.html">Developer Guide</a> and <a href="https://docs.aws.amazon.com/sdkfornet/v3/apidocs/Index.html">.Net SDK Reference</a></li>
</ul>
<p>Thoughts:</p>
<ul>
<li>Documentation for .Net SDK is basic. It is very comprehensive but hard to find what you need. It took me so long to find out where to specify the CloudSearch search endpoint in the SDK (hint: it&rsquo;s the <code>ServiceURL</code> property of the <code>AmazonCloudSearchDomainConfig</code> class)</li>
<li>The CloudSearch service itself was easy to get started and configure. I could upload my CSV dataset and it parsed it without trouble.</li>
<li>The <a href="https://aws.amazon.com/cloudsearch/pricing/">pricing</a> page notes &ldquo;Pricing is per instance-hour consumed for each search instance, from the time the instance is launched until it is terminated. Each partial instance-hour consumed is billed as a full hour.&rdquo; The second sentence puzzles me. I interpret it as: if CloudSearch gets exactly one search that takes 5 seconds to execute, Amazon will still charge me for a full hour. This could be an expensive service on a cost per search basis if your site/app only gets a few searches a day.</li>
</ul>
<p>I used AWS Lambda with API Gateway to expose a REST API to an Amazon CloudSearch domain. This was used to power the item search backend in the <a href="https://essentialornot.org.nz">Essential Or Not website</a> created by my partner Gage during the SARS-Cov-2 lockdown:</p>
<figure>
    <img src="eon-search-1.png"
         alt="Essential Or Not website item search page showing search suggestions when a user types cupcake in the search box"/> <figcaption>
            <h4>Search suggestions</h4>
        </figcaption>
</figure>

<figure>
    <img src="eon-search-2.png"
         alt="Essential Or Not website item search result for American Muffins showing that yes, it is an essential item"/> <figcaption>
            <h4>Search result showing whether an item is essential or not</h4>
        </figcaption>
</figure>

<h2 id="terraform">Terraform</h2>
<p>Learning sources:</p>
<ul>
<li>Official <a href="https://learn.hashicorp.com/terraform?track=getting-started#getting-started">HashiCorp Terraform Getting Started course</a></li>
</ul>
<p>Thoughts:</p>
<ul>
<li>I like it. It can be hard to justify using Terraform if the organisation is only using one cloud provider, but that&rsquo;s quite a rare case.</li>
<li>Azure has ARM templates that work very well, but do not have the state awareness that Terraform maintains.</li>
<li>The definition language is easy to read, similar to ARM templates but not as nested.</li>
<li>I can see Terraform relies a lot on &lsquo;magic&rsquo; by expecting certain things such as files that must be named a certain way. It can be confusing for a newcomer to pick up all the built-in assumptions that drive a lot of its smarts.</li>
<li>I did not try any examples that work with on-prem servers, besides provisioning and starting a Docker container.</li>
<li>State awareness has a downside - you need to maintain it in a central location if you&rsquo;re working in a team. HashiCorp then tries to upsell you into Terraform Cloud to be the centralized remote state store.</li>
</ul>
<h2 id="react-state-management">React state management</h2>
<p>Learning sources:</p>
<ul>
<li>CodeMash Conference 2020 talk: <a href="https://app.pluralsight.com/library/courses/codemash-session-60/table-of-contents">React State: Redux &amp; Context &amp; Hooks, Oh My: CodeMash</a></li>
</ul>
<p>Thoughts:</p>
<ul>
<li>What annoys me about React is that good state management was not built in to the initial releases, which led to an explosion of different frameworks like Redux, MobX, and StateX over the years. React in itself is simple to learn until you start throwing state at it. That is usually all the time.</li>
<li>The 40 minute talk by Michael Moran is a useful primer to the most common state management approaches in React but doesn&rsquo;t go into the nitty gritty. This was perfect for me.</li>
<li>The summary is:
<ul>
<li>He categorizes state into short-term (user input), medium-term (identity, shopping cart), and long-term (customer data)</li>
<li>You can mix and match approaches for different types of state</li>
<li>He would use React Hooks if he was starting from scratch today.</li>
<li>A useful library of custom hooks is the <a href="https://github.com/streamich/react-use">react-use project</a></li>
</ul>
</li>
</ul>
<h2 id="pwa">PWA</h2>
<p>Learning sources:</p>
<ul>
<li><a href="https://app.pluralsight.com/library/courses/building-performant-progressive-web-apps-scratch/table-of-contents">Building Performant Progressive Web Apps from Scratch</a></li>
</ul>
<p>Takeaways:</p>
<ul>
<li>To paraphrase the instructor, all web apps can be made into Portable Web Apps, but it doesn&rsquo;t mean that you should. Most apps really need to be rethought in &ldquo;native&rdquo; app terms.</li>
<li>Browser support is growing, however it is still very hidden on iOS. I think it scares Apple that there can be mobile apps that circumvent their tight grip on the App Store.</li>
<li>The basic implementation steps are pretty straightforward, and the Service Worker approach to support offline mode is probably a good thing to consider in any mobile-optimised app, even without adding to home screen.</li>
<li>PWAs can be considered a developer specialty because there is decent technical depth required to make production-quality PWAs, especially when it comes to supporting offline workloads.</li>
</ul>
<h2 id="sre">SRE</h2>
<p>Learning sources:</p>
<ul>
<li>O&rsquo;Reilly Webinar <a href="https://www.oreilly.com/webcasts/lot/2248020-site-reliability-engineering-fundamentals.html">Site Reliability Engineering Fundamentals</a></li>
</ul>
<p>Takeaways:</p>
<ul>
<li>The speakers define Site Reliability Engineering as: SRE is thinking of reliability from a business perspective and engineering towards it. Key term &ldquo;business perspective&rdquo; is making sure the reliability solutions you implement help fulfill a real business requirement.</li>
<li>The analogy they gave was for an airline aiming to be on-time at all times - it will probably lead to over-resourcing and be really expensive, but is it really what the customer expects?</li>
<li>All systems will fail: What is your acceptable level of failure, and what will you set up to handle it?</li>
<li>Stripe had &ldquo;game days&rdquo; - pick a day to deliberately fail systems to observe impact, practice incident response, and update the run book.</li>
<li>How reliable should I be? What services touch customers?</li>
<li>Choose the right SLIs (Service Level Indicators) for the satisfaction of your user. It should be specific, measurable, and actionable.</li>
<li>SLOs (Service Level Objectives) are your targets for your SLIs, e.g. 98.50% uptime. Consult multiple perspectives to calculate this number, and acknowledge what is realistic, e.g. user internet connections out of your control.</li>
<li>SLAs (Service Level Agreements) usually involve financial consequences and should not be your SLOs!</li>
<li>Toil: repetitive, predictable, constant stream of tasks related to maintaining a service. (Google)</li>
<li>We want to automate toil away, but realize that automation is a spectrum. A simple checklist is also a form of automation and is a step towards fully scripted solutions.</li>
<li>&ldquo;The root cause of falling is gravity&rdquo; perfectly describes why we want to move beyond Root Cause Analysis to blameless Post Incident Reviews.</li>
</ul>
<h2 id="golang">GoLang</h2>
<p>Learning sources:</p>
<ul>
<li>Pluralsight: <a href="https://app.pluralsight.com/library/courses/getting-started-with-go/table-of-contents">Go: Getting Started</a></li>
</ul>
<p>Thoughts:</p>
<ul>
<li>I can see why some people like the simplicity of Go. But as the instructor says, simple doesn&rsquo;t mean easy. It doesn&rsquo;t provide a lot of &lsquo;magic&rsquo; that heavier frameworks like Java and .Net provide out of the box. This means it&rsquo;s easier to read a Go program and understand the execution flow. I remember my initial confusion with ASP .Net MVC&rsquo;s routing system, which is largely by convention. Go, however, requires you to implement that logic flow yourself.</li>
<li>I like that Go discourages the use of panics, which are analogous to exceptions. It instead encourages returning error types. This, again, improves the predictability of the execution.</li>
<li>THe main thing that feels unnatural to me is how to implement some object-oriented concepts like struct methods and constructors, mainly because they are not actually classes.</li>
<li>The Pluralsight course was a beginner-level course so it did not go into concurrency, which I keep hearing is one of the main highlights of the language.</li>
</ul>
<h2 id="feature-management">Feature Management</h2>
<p>Learning sources:</p>
<ul>
<li>Pete Hodgson: <a href="https://www.martinfowler.com/articles/feature-toggles.html">Feature Toggles (aka Feature Flags)</a>
<ul>
<li>Referenced in that article is a <a href="https://dougseven.com/2014/04/17/knightmare-a-devops-cautionary-tale/">good DevOps cautionary tale</a></li>
</ul>
</li>
<li>Pluralsight: <a href="https://app.pluralsight.com/library/courses/azure-devops-feature-toggles-package-management-versioning/table-of-contents">Feature Toggles module of this wider course</a></li>
<li><a href="https://launchdarkly.com/effective-feature-management-ebook/">Effective Feature Management e-book</a> by O&rsquo;Reilly and LaunchDarkly</li>
<li>THAT Conference &lsquo;19: <a href="https://app.pluralsight.com/library/courses/that-conference-2019-session-28/table-of-contents">Feature Flags for Better DevOps</a></li>
</ul>
<p>Takeaways:</p>
<ul>
<li>There are many categories of toggles which affect how they should be stored and managed. The first blog post in my learning sources is a good foundational reading.</li>
<li>Feature Flags as a Service (FFaaS) is a thing and is <a href="https://launchdarkly.com/pricing/">quite pricey</a> but there is also a <a href="https://azure.microsoft.com/en-us/pricing/details/app-configuration/">free tier for Azure App Configuration</a> which is fairly new at the time of writing. However LaunchDarkly has a lot of features and integrations with different platforms such as Azure DevOps.</li>
<li>Feature flags decouple deployment from release, which enables canary releases, dark launches, and A/B testing.</li>
<li>Architecture patterns need to be considered to avoid tightly coupling your execution code with feature management code.</li>
<li>&ldquo;Savvy teams view their Feature Toggles as inventory which comes with a carrying cost, and work to keep that inventory as low as possible.&rdquo;</li>
</ul>
<hr>
<p>And that&rsquo;s a wrap, folks! I enjoyed doing the 12 Days of Learning because it&rsquo;s like curating and attending my own conference from the comfort of my own home. I definitely think this is a worthwhile investment for my personal growth - I will continue to organise something like this in the future but for a shorter timeframe, such as a &ldquo;Long weekend of learning&rdquo; instead of 12 days.</p>
]]></content></item><item><title>Chrome's SameSite Cookie Changes are Breaking Apps</title><link>https://www.coderfrontline.com/chromes-samesite-cookie-changes-are-breaking-apps/</link><pubDate>Sat, 22 Feb 2020 21:36:00 +1300</pubDate><guid>https://www.coderfrontline.com/chromes-samesite-cookie-changes-are-breaking-apps/</guid><description>Updated 8 April 2020 with alternative regex if your OS or framework or app automatically adds the SameSite=Lax header to your session cookies. It is important to double check what your app is emitting so you can tailor the regex to suit!
I just spent a good 6 hours of my life trying to debug a weird web app issue that I finally pinned down to the SameSite cookie attribute changes spearheaded by Google.</description><content type="html"><![CDATA[<hr>
<p><strong>Updated 8 April 2020</strong> with alternative regex if your OS or framework or app automatically adds the SameSite=Lax header to your session cookies. It is important to double check what your app is emitting so you can tailor the regex to suit!</p>
<hr>
<p>I just spent a good 6 hours of my life trying to debug a weird web app issue that I finally pinned down to the SameSite cookie attribute changes spearheaded by Google. The change has been signalled for months but I had ignored it, thinking it&rsquo;s only going to affect niche scenarios that will be updated by other packages. In fact I think this will slowly grow to have the same impact as the TLS 1.0 shut off in 2018 in terms of how many e-commerce website owners are caught out by it.</p>
<p>This was the buggy behaviour I noticed:</p>
<ol>
<li>Users initiated the checkout process</li>
<li>Users were taken to a third-party payment gateway to enter their card details</li>
<li>The payment gateway sends the user back to the site</li>
<li>The web server backend could not retrieve the session cookie, thus treating it as a new user session. This meant that it was unable to retrieve the shopping cart to finalize the order.</li>
</ol>
<p>I will cover the key points but send you off to more informative sites where necessary. I will then list some mitigating approaches for ASP .Net, my web framework of choice.</p>
<h2 id="investigation">Investigation</h2>
<p>You need to pay attention to the SameSite changes if your website or application:</p>
<ul>
<li>Uses cookies for website functionality. There may be important cookies added implicitly by the framework or imported components. Common ones include cookies that identify session and user preferences.</li>
<li>Connects to a third-party service, which includes showing their content. Common examples are authentication providers and payment gateways.</li>
<li>Can be served over non-secure HTTP protocol</li>
</ul>
<p>In my case, the web application was using ASP.NET_SessionId session cookies to keep track of the user&rsquo;s details and shopping cart contents. It was also using the Paymark Click hosted payment gateway which <a href="http://docs.dev.paymark.nz/click/#header-two-return-options">Posts to Return URL after payment details are submitted</a>. No SameSite option was set on the ASP.NET_SessionId cookie, so it was treated as &ldquo;Lax&rdquo; by default. This meant the cookie was not included when the Paymark Click page sends the POST to the return URL.</p>
<h2 id="resolution-and-mitigation">Resolution and Mitigation</h2>
<p>I highly recommend spending a fruitful 15 minutes reading Rowan&rsquo;s <a href="https://web.dev/samesite-cookies-explained/">simple explanation of the SameSite attribute</a>. Start there before implementing any solutions you find so that you understand why you&rsquo;re doing it. You can also review <a href="https://devblogs.microsoft.com/aspnet/upcoming-samesite-cookie-changes-in-asp-net-and-asp-net-core/">.Net-specific information in Barry&rsquo;s blog post</a> announcing the changes.</p>
<p>In my case, my session state cookie needed to have both <code>secure</code> and <code>SameSite=None</code> headers. Luckily my site is HTTPS-only so that solves the secure part, but what about the None header?</p>
<h3 id="asp-net-472-and-above-and-net-core-21-and-above">ASP .Net 4.7.2 and above, and .Net Core 2.1 and above</h3>
<p>Cookies have a <a href="https://docs.microsoft.com/en-us/dotnet/api/system.web.httpcookie.samesite">SameSite property</a> which can be set to one of three enum values (None, Lax, Strict) according to your needs. However, the <a href="https://docs.microsoft.com/en-us/dotnet/api/system.web.samesitemode">default behaviour for &ldquo;None&rdquo;</a> varies if you did not specify a value. In the past it would not emit any SameSite attribute, but recent Windows patches will change it to emit the SameSite=None cookie header. More importantly, FormsAuth and SessionState cookies will be issued with <code>SameSite=Lax</code>, which still wouldn&rsquo;t work properly in my encountered scenario. The <a href="https://azure.microsoft.com/en-us/updates/app-service-samesite-cookie-update/">Azure App Service was updated with these changes</a> in January 2020.</p>
<p>One approach is to add the <code>cookieSameSite=&quot;None&quot;</code> attribute to your web.config:</p>
<div class="highlight"><pre class="chroma"><code class="language-xml" data-lang="xml"><span class="nt">&lt;sessionState</span> <span class="na">mode=</span><span class="s">&#34;StateServer&#34;</span> <span class="na">cookieSameSite=</span><span class="s">&#34;None&#34;</span> <span class="na">cookieless=</span><span class="s">&#34;false&#34;</span> <span class="na">timeout=</span><span class="s">&#34;20&#34;</span> <span class="nt">/&gt;</span>
</code></pre></div><h3 id="asp-net-before-472">ASP .Net before 4.7.2</h3>
<p>The online shopping site I was supporting is built on .Net 4.5.1 which meant that it did not have the same attribute I could specify. Instead, I am using this URL Rewrite (modified off a couple of StackOverlow answers <a href="https://stackoverflow.com/a/59281131">here</a> and <a href="https://stackoverflow.com/a/59300799/824036">here</a>) that applies <code>SameSite=None</code> to ASP .Net session cookies regardless if there&rsquo;s one:</p>
<p><strong>IMPORTANT!</strong> The following solutions require the <a href="https://www.iis.net/downloads/microsoft/url-rewrite">URL Rewrite IIS extension</a>.</p>
<div class="highlight"><pre class="chroma"><code class="language-xml" data-lang="xml"><span class="nt">&lt;rewrite&gt;</span>
  <span class="nt">&lt;outboundRules&gt;</span>
    <span class="nt">&lt;rule</span> <span class="na">name=</span><span class="s">&#34;SessionCookieAddNoneHeader&#34;</span><span class="nt">&gt;</span>
      <span class="nt">&lt;match</span> <span class="na">serverVariable=</span><span class="s">&#34;RESPONSE_Set-Cookie&#34;</span> <span class="na">pattern=</span><span class="s">&#34;(.*ASP.NET_SessionId.*)&#34;</span> <span class="nt">/&gt;</span>
      <span class="c">&lt;!-- Use this regex if your OS/framework/app adds SameSite=Lax automatically to the end of the cookie --&gt;</span>
      <span class="c">&lt;!-- &lt;match serverVariable=&#34;RESPONSE_Set-Cookie&#34; pattern=&#34;((.*)(ASP.NET_SessionId)(=.*))(?=SameSite)&#34; /&gt; --&gt;</span>
      <span class="nt">&lt;action</span> <span class="na">type=</span><span class="s">&#34;Rewrite&#34;</span> <span class="na">value=</span><span class="s">&#34;{R:1}; SameSite=None&#34;</span> <span class="nt">/&gt;</span>
    <span class="nt">&lt;/rule&gt;</span>
  <span class="nt">&lt;/outboundRules&gt;</span>
<span class="nt">&lt;/rewrite&gt;</span>
</code></pre></div><h2 id="user-agent-sniffing">User Agent Sniffing</h2>
<p>There is a huge caveat to the above approaches. Some older browsers do not recognize the None option, and might reject it outright, ignore the header, or treat it as &ldquo;Strict&rdquo;. All outcomes will likely cause more problems. Check out Chromium&rsquo;s post on <a href="https://www.chromium.org/updates/same-site/incompatible-clients">known incompatible clients</a> for the latest list and UserAgent detection pseudo-code. The web.config solutions I shared above do not have this User Agent sniffing capability, which means it will break the site on affected browsers.</p>
<p>My best solution right now for existing production sites follows. I expanded my IIS URL Rewrite rule to remove <code>SameSite=None</code> header from most incompatible browsers. Kudos to CatchJS for doing real-world testing as documented in their blog: <a href="https://catchjs.com/Blog/SameSiteCookies">User-Agent Sniffing Only Way to Deal With Upcoming SameSite Cookie Changes
</a>. I modified their detection approach into a URL Rewrite pre-condition:</p>
<div class="highlight"><pre class="chroma"><code class="language-xml" data-lang="xml"><span class="nt">&lt;rewrite&gt;</span>
  <span class="nt">&lt;outboundRules&gt;</span>
    <span class="nt">&lt;preConditions&gt;</span>
      <span class="c">&lt;!-- Checks User Agent to identify browsers incompatible with SameSite=None --&gt;</span>
      <span class="nt">&lt;preCondition</span> <span class="na">name=</span><span class="s">&#34;IncompatibleWithSameSiteNone&#34;</span> <span class="na">logicalGrouping=</span><span class="s">&#34;MatchAny&#34;</span><span class="nt">&gt;</span>
        <span class="nt">&lt;add</span> <span class="na">input=</span><span class="s">&#34;{HTTP_USER_AGENT}&#34;</span> <span class="na">pattern=</span><span class="s">&#34;(CPU iPhone OS 12)|(iPad; CPU OS 12)&#34;</span> <span class="nt">/&gt;</span>
        <span class="nt">&lt;add</span> <span class="na">input=</span><span class="s">&#34;{HTTP_USER_AGENT}&#34;</span> <span class="na">pattern=</span><span class="s">&#34;(Chrome/5)|(Chrome/6)&#34;</span> <span class="nt">/&gt;</span>
        <span class="nt">&lt;add</span> <span class="na">input=</span><span class="s">&#34;{HTTP_USER_AGENT}&#34;</span> <span class="na">pattern=</span><span class="s">&#34;( OS X 10_14).*(Version/).*((Safari)|(KHTML, like Gecko)$)&#34;</span> <span class="nt">/&gt;</span>
      <span class="nt">&lt;/preCondition&gt;</span>
    <span class="nt">&lt;/preConditions&gt;</span>

    <span class="c">&lt;!-- Adds or changes SameSite to None for the session cookie --&gt;</span>
    <span class="c">&lt;!-- Note that secure header is also required by Chrome and should not be added here --&gt;</span>
    <span class="nt">&lt;rule</span> <span class="na">name=</span><span class="s">&#34;SessionCookieAddNoneHeader&#34;</span><span class="nt">&gt;</span>
      <span class="nt">&lt;match</span> <span class="na">serverVariable=</span><span class="s">&#34;RESPONSE_Set-Cookie&#34;</span> <span class="na">pattern=</span><span class="s">&#34;(.*ASP.NET_SessionId.*)&#34;</span> <span class="nt">/&gt;</span>
      <span class="c">&lt;!-- Use this regex if your OS/framework/app adds SameSite=Lax automatically to the end of the cookie --&gt;</span>
      <span class="c">&lt;!-- &lt;match serverVariable=&#34;RESPONSE_Set-Cookie&#34; pattern=&#34;((.*)(ASP.NET_SessionId)(=.*))(?=SameSite)&#34; /&gt; --&gt;</span>
      <span class="nt">&lt;action</span> <span class="na">type=</span><span class="s">&#34;Rewrite&#34;</span> <span class="na">value=</span><span class="s">&#34;{R:1}; SameSite=None&#34;</span> <span class="nt">/&gt;</span>
    <span class="nt">&lt;/rule&gt;</span>

    <span class="c">&lt;!-- Removes SameSite=None header from all cookies, for most incompatible browsers --&gt;</span>
    <span class="nt">&lt;rule</span> <span class="na">name=</span><span class="s">&#34;CookieRemoveSameSiteNone&#34;</span> <span class="na">preCondition=</span><span class="s">&#34;IncompatibleWithSameSiteNone&#34;</span><span class="nt">&gt;</span>
      <span class="nt">&lt;match</span> <span class="na">serverVariable=</span><span class="s">&#34;RESPONSE_Set-Cookie&#34;</span> <span class="na">pattern=</span><span class="s">&#34;(.*)(SameSite=None)&#34;</span> <span class="nt">/&gt;</span>
      <span class="nt">&lt;action</span> <span class="na">type=</span><span class="s">&#34;Rewrite&#34;</span> <span class="na">value=</span><span class="s">&#34;{R:1}&#34;</span> <span class="nt">/&gt;</span>
    <span class="nt">&lt;/rule&gt;</span>
  <span class="nt">&lt;/outboundRules&gt;</span>
<span class="nt">&lt;/rewrite&gt;</span>
</code></pre></div><h2 id="http-caveat">HTTP Caveat</h2>
<p>Chrome will only accept <code>SameSite=None</code> if it is paired with the <code>secure</code> header. Adding that header is not covered in this article, and can usually be added in via different code and config approaches. The <code>secure</code> header also means that the cookie must be served over HTTPS, so make sure your website handles any HTTP redirection as required.</p>
]]></content></item><item><title>Our Team Brand</title><link>https://www.coderfrontline.com/our-team-brand/</link><pubDate>Thu, 05 Dec 2019 22:08:00 +1300</pubDate><guid>https://www.coderfrontline.com/our-team-brand/</guid><description>One of my highlights at work in 2019 was taking the team through a Team Brand exercise. This is a culture definition team activity that I learned from a previous role. It is based on a simple premise: What words do you want other teams to use when describing us?
Team culture fascinates me but it often lives as a vague affirmation that &amp;ldquo;Yes, we want a good culture&amp;rdquo;. How does that translate into meanigful behaviours and actions?</description><content type="html"><![CDATA[<p>One of my highlights at work in 2019 was taking the team through a Team Brand exercise. This is a culture definition team activity that I learned from a previous role. It is based on a simple premise: What words do you want other teams to use when describing us?</p>
<p>Team <a href="/categories/culture/">culture fascinates me</a> but it often lives as a vague affirmation that &ldquo;Yes, we want a good culture&rdquo;. How does that translate into meanigful behaviours and actions? I&rsquo;ve found that the Team Brand exercise is one possible approach. This is what the team collectively came up with over several months of team meetings (minor tweaks to remove some names):</p>
<figure>
    <img src="team-brand.webp"
         alt="Team Brand poster with headings of Caring, Reliable, and Collaborative"/> <figcaption>
            <h4>Our Team Brand</h4>
        </figcaption>
</figure>

<p>I asked people&rsquo;s opinions afterwards and everyone agreed it was a worthwhile effort because we have articulated how the team wants to operate. More importantly, the team took ownership of those values because they defined it themselves. It was not a holy decree commanded down from high above the organisation chart. Having said that, it should still align with the wider company&rsquo;s vision and values. We&rsquo;re all moving in the same direction but we&rsquo;ve decided <em>how</em> we want to get there.</p>
<p>Here&rsquo;s the summarized version of the Team Brand exercise, which should happen over multiple sessions to allow for thoughts to gestate and evolve. However I have also managed to run through an end-to-end example during a 1 hour talk.</p>
<ol>
<li>Brainstorm words that you want to hear, when other people describe our team.</li>
<li>Talk through the qualities and start grouping similar ones together.</li>
<li>Do a prioritisation exercise to pick the top 3 or 4 groups of values. I recommend a variation of the <a href="https://kenpower.ie/2011/05/22/using-silent-grouping-to-size-user-stories/">Silent Grouping Technique</a> that ranks values instead of sizes them.</li>
<li>For each top-level heading, discuss 3 or 4 types of behaviours that we will portray in order to embody those values.</li>
<li>Take a break before the final step!</li>
<li>Review the values and statements again for a final opportunity to rephrase and re-order.</li>
</ol>
<p>Reach out to <a href="https://www.linkedin.com/in/shawnlamnz">me via LinkedIn</a> if you would like to learn more in detail!</p>
]]></content></item><item><title>AppDynamics APM for .Net Apps Cheat Sheet</title><link>https://www.coderfrontline.com/appdynamics-apm-for-.net-apps-cheat-sheet/</link><pubDate>Thu, 01 Aug 2019 17:28:00 +1200</pubDate><guid>https://www.coderfrontline.com/appdynamics-apm-for-.net-apps-cheat-sheet/</guid><description>I&amp;rsquo;m getting involved with Cisco AppDynamics APM (Application Performance Monitoring) at work and have been finding lots of little tricks and gotchas with instrumenting ASP .Net web applications on Windows servers. I have compiled a list of quick tips that may help you set yourself up for APM bliss.
.Net Agent Installation The .Net Agent Setup on Windows is a breeze to go through. It even installs a Windows application called AppDynamics Agent Configuration that lets you easily re-configure the agent afterwards.</description><content type="html"><![CDATA[<p>I&rsquo;m getting involved with Cisco AppDynamics APM (Application Performance Monitoring) at work and have been finding lots of little tricks and gotchas with instrumenting ASP .Net web applications on Windows servers. I have compiled a list of quick tips that may help you set yourself up for APM bliss.</p>
<h1 id="net-agent-installation">.Net Agent Installation</h1>
<p>The .Net Agent Setup on Windows is a breeze to go through. It even installs a Windows application called AppDynamics Agent Configuration that lets you easily re-configure the agent afterwards. I recommend running this right after installation because one of the final steps it does is restart IIS, which is required for the agent to start collecting information about your ASP .Net applications.</p>
<figure>
    <img src="dotnet-agent.png"
         alt=".Net Agent Configuration Wizard dialog box"/> <figcaption>
            <h4>.Net Agent Configuration Wizard</h4>
        </figcaption>
</figure>

<h1 id="machine-agent-installation">Machine Agent Installation</h1>
<p>The .Net Agent comes with basic server monitoring features (CPU, memory, disk usage levels). The Server Visiblity license, if you have it, will open up new insights such as detailed Processes list. This means you need to install a Machine Agent on the same server as the .Net Agent. There are a few configuration settings you need to change which you can <a href="https://docs.appdynamics.com/display/PRO45/.NET+Compatibility+Mode">refer to AppDynamics documentation on .Net Compatibility Mode</a>.</p>
<p>In a nutshell:</p>
<ol>
<li>Set dotnet-compatibility-mode to true</li>
<li>Set unique-host-id to the same unique-host-id of the Application. You can find the Application&rsquo;s unique-host-id by viewing your AppDynamics Agents:</li>
</ol>
<figure>
    <img src="appdynamics-agents-menu.png"
         alt="AppDynamics Agents menu"/> <figcaption>
            <h4>AppDynamics Agents menu</h4>
        </figcaption>
</figure>

<figure>
    <img src="app-agent-id.png"
         alt="AppDynamics Agents Unique Host ID"/> <figcaption>
            <h4>AppDynamics Agents Unique Host ID</h4>
        </figcaption>
</figure>

<p>Lastly, it is perfectly fine for the machine agent status to have the &ldquo;-java-MA&rdquo; suffix. This means it is running in .Net Compatibility Mode. I also noticed that the status is always INITIALIZING even though it is running normally.</p>
<figure>
    <img src="machine-agent-summary.png"
         alt="AppDynamics Machine Agent summary window"/> <figcaption>
            <h4>AppDynamics Machine Agent summary window</h4>
        </figcaption>
</figure>

<p>Hope this helps!</p>
]]></content></item><item><title>TLS 1.2 support on .Net 4.5</title><link>https://www.coderfrontline.com/tls-1.2-support-on-.net-4.5/</link><pubDate>Fri, 19 Jul 2019 14:00:00 +1200</pubDate><guid>https://www.coderfrontline.com/tls-1.2-support-on-.net-4.5/</guid><description>Part of my job involves supporting legacy software running on older .Net Frameworks. There was a period of upheaval last year when support for TLS 1.0 was switched off by many payment processing gateways. A lot of online guides use this simple trick to force .Net 4.5 application to use TLS 1.2:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; This turns out to be a bad move because the code will only support TLS 1.</description><content type="html"><![CDATA[<p>Part of my job involves supporting legacy software running on older .Net Frameworks. There was a period of upheaval last year when support for TLS 1.0 was switched off by many payment processing gateways. A lot of online guides use this simple trick to force .Net 4.5 application to use TLS 1.2:</p>
<div class="highlight"><pre class="chroma"><code class="language-csharp" data-lang="csharp"><span class="n">ServicePointManager</span><span class="p">.</span><span class="n">SecurityProtocol</span> <span class="p">=</span> <span class="n">SecurityProtocolType</span><span class="p">.</span><span class="n">Tls12</span><span class="p">;</span>
</code></pre></div><p>This turns out to be a bad move because the code will only support TLS 1.2, while older services may still need TLS 1.1 or 1.0. I found another code snippet that adds TLS 1.2 to the list of supported protocols:</p>
<div class="highlight"><pre class="chroma"><code class="language-csharp" data-lang="csharp"><span class="n">ServicePointManager</span><span class="p">.</span><span class="n">SecurityProtocol</span> <span class="p">|=</span> <span class="n">SecurityProtocolType</span><span class="p">.</span><span class="n">Tls11</span> <span class="p">|</span> <span class="n">SecurityProtocolType</span><span class="p">.</span><span class="n">Tls12</span><span class="p">;</span>
</code></pre></div><p>This approach didn&rsquo;t work for me because the older OS I was on used TLS 1.0 as the default protocol.</p>
<p>I finally found a comprehensive (if a little confusing) guide in the official Microsoft docs on <a href="https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls">Transport Layer Security (TLS) best practices with the .NET Framework</a>. The solution for my particular case is to make a Registry tweak to enforce and prefer secure protocols.</p>
<p>Taken from that page, here&rsquo;s a snippet which can be saved as a .reg file and run on the server. Please be careful when making changes to the Registry, and it is recommended to revisit the <a href="https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls">official documentation</a> for latest updates.</p>
<div class="highlight"><pre class="chroma"><code class="language-registry" data-lang="registry">Windows Registry Editor Version 5.00

<span class="k">[</span><span class="nb">HKEY_LOCAL_MACHINE</span><span class="k">\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v2.0.50727]</span>
<span class="na">&#34;SystemDefaultTlsVersions&#34;</span><span class="o">=</span><span class="nv">dword</span><span class="p">:</span><span class="m">00000001</span>
<span class="na">&#34;SchUseStrongCrypto&#34;</span><span class="o">=</span><span class="nv">dword</span><span class="p">:</span><span class="m">00000001</span>

<span class="k">[</span><span class="nb">HKEY_LOCAL_MACHINE</span><span class="k">\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319]</span>
<span class="na">&#34;SystemDefaultTlsVersions&#34;</span><span class="o">=</span><span class="nv">dword</span><span class="p">:</span><span class="m">00000001</span>
<span class="na">&#34;SchUseStrongCrypto&#34;</span><span class="o">=</span><span class="nv">dword</span><span class="p">:</span><span class="m">00000001</span>

<span class="k">[</span><span class="nb">HKEY_LOCAL_MACHINE</span><span class="k">\SOFTWARE\Microsoft\.NETFramework\v2.0.50727]</span>
<span class="na">&#34;SystemDefaultTlsVersions&#34;</span><span class="o">=</span><span class="nv">dword</span><span class="p">:</span><span class="m">00000001</span>
<span class="na">&#34;SchUseStrongCrypto&#34;</span><span class="o">=</span><span class="nv">dword</span><span class="p">:</span><span class="m">00000001</span>

<span class="k">[</span><span class="nb">HKEY_LOCAL_MACHINE</span><span class="k">\SOFTWARE\Microsoft\.NETFramework\v4.0.30319]</span>
<span class="na">&#34;SystemDefaultTlsVersions&#34;</span><span class="o">=</span><span class="nv">dword</span><span class="p">:</span><span class="m">00000001</span>
<span class="na">&#34;SchUseStrongCrypto&#34;</span><span class="o">=</span><span class="nv">dword</span><span class="p">:</span><span class="m">00000001</span>
</code></pre></div>]]></content></item><item><title>Wireshark Capture Filter by Host IP</title><link>https://www.coderfrontline.com/wireshark-capture-filter-by-host-ip/</link><pubDate>Fri, 19 Jul 2019 13:28:00 +1200</pubDate><guid>https://www.coderfrontline.com/wireshark-capture-filter-by-host-ip/</guid><description>I keep forgetting this simple syntax and hopefully this will come in handy. In Wireshark you can specify a capture filter to only log traffic to/from a specific IP address with:
host {ipAddress} Wireshark Capture Filter I needed to use a capture filter because I was running captures on a low-spec server, and without a capture filter Wireshark eats up all the memory.
Related tip: Use nslookup to get the IP address that is resolved to.</description><content type="html"><![CDATA[<p>I keep forgetting this simple syntax and hopefully this will come in handy. In Wireshark you can specify a capture filter to only log traffic to/from a specific IP address with:</p>
<pre><code>host {ipAddress}
</code></pre><figure>
    <img src="wireshark.png"
         alt="Screenshot of Wireshark&#39;s Capture Filter input"/> <figcaption>
            <h4>Wireshark Capture Filter</h4>
        </figcaption>
</figure>

<p>I needed to use a capture filter because I was running captures on a low-spec server, and without a capture filter Wireshark eats up all the memory.</p>
<p>Related tip: Use nslookup to get the IP address that is resolved to. You would usually do this from the server itself as CDNs may send you to a different IP.</p>
<pre><code>nslookup {www.domain.tld}
</code></pre>]]></content></item><item><title>Hello from DevCamp</title><link>https://www.coderfrontline.com/hello-from-devcamp/</link><pubDate>Sat, 29 Jun 2019 17:28:00 +1200</pubDate><guid>https://www.coderfrontline.com/hello-from-devcamp/</guid><description>Hello from DevCamp 2019 - Datacom&amp;rsquo;s premier developer unconference.
Hello from DevCamp Join us next year - check out Datacom Jobs</description><content type="html"><![CDATA[<p>Hello from DevCamp 2019 - Datacom&rsquo;s premier developer unconference.</p>
<figure>
    <img src="hello.jpg"
         alt="Group photo of attendees at Carl and Shawn&#39;s session"/> <figcaption>
            <h4>Hello from DevCamp</h4>
        </figcaption>
</figure>

<p>Join us next year - check out <a href="https://www.datacom.co.nz/Careers/Hiring-Now.aspx">Datacom Jobs</a></p>
]]></content></item><item><title>Update SSL Cert on Azure App Service</title><link>https://www.coderfrontline.com/update-ssl-cert-on-azure-app-service/</link><pubDate>Sat, 06 Apr 2019 09:00:00 +1300</pubDate><guid>https://www.coderfrontline.com/update-ssl-cert-on-azure-app-service/</guid><description>There are so many different tutorials on how to provision and install an SSL/TLS certificate on Azure App Services that I thought I&amp;rsquo;d write one that worked for me. I added some indicative timelines so you know how long each step may take. As a rule I recommend starting this process at least a week before the current certificate will expire.
Pre-requisites Find a different tutorial if you don&amp;rsquo;t have these exact components because your results may vary:</description><content type="html"><![CDATA[<p>There are so many different tutorials on how to provision and install an SSL/TLS certificate on Azure App Services that I thought I&rsquo;d write one that worked for me. I added some indicative timelines so you know how long each step may take. As a rule I recommend starting this process at least a week before the current certificate will expire.</p>
<h1 id="pre-requisites">Pre-requisites</h1>
<p>Find a different tutorial if you don&rsquo;t have these exact components because your results may vary:</p>
<ol>
<li>Windows computer (Windows 10 or newer, or a server edition)</li>
<li><a href="https://www.digicert.com/util/">DigiCert Certificate Utility</a></li>
<li>Azure App Service that requires a SSL certificate to be updated</li>
<li>SSL certificate available to purchase</li>
<li>Access to domain name DNS settings</li>
</ol>
<h1 id="create-certificate">Create certificate</h1>
<h2 id="generate-csr-5-minutes">Generate CSR (5 minutes)</h2>
<ol>
<li>Open the DigiCert Certificate Utility and <a href="https://www.digicert.com/util/csr-creation-microsoft-servers-using-digicert-utility.htm">follow the official steps to generate a CSR</a></li>
<li>Remember to put a wildcard URL if you are purchasing one.</li>
<li>The important thing is you don&rsquo;t need to generate the CSR on the server that you&rsquo;re going to install it on.</li>
</ol>
<h2 id="purchase-certificate-using-csr-10-minutes">Purchase certificate using CSR (10 minutes)</h2>
<ol>
<li>Purchase the certificate with the CSR generated from DigiCert Certificate Utility. This step is largely similar with all certificate sellers.</li>
</ol>
<h2 id="verify-domain-ownership-via-dns-up-to-1-hour">Verify domain ownership via DNS (up to 1 hour)</h2>
<ol>
<li>As part of the certificate generation process you will need to verify domain name ownership. I recommend using the DNS method, where you add a TXT record with a provided string. This part may take an hour or more to propagate, but is usually faster.</li>
</ol>
<h2 id="download-certificate-5-minutes">Download certificate (5 minutes)</h2>
<ol>
<li>The SSL provider will e-mail the certificate in text format.</li>
<li>Copy the certificate text into a text editor and save it with a .cer extension.</li>
</ol>
<h2 id="convert-certificate-into-pfx-10-minutes">Convert certificate into .pfx (10 minutes)</h2>
<ol>
<li>Open the DigiCert Certificate Utility on the same server you generated the CSR.</li>
<li>Import the .cer file into the server following the <a href="https://www.digicert.com/util/ssl-certificate-installation-using-digicert-utility-for-microsoft-servers.htm">installation instructions</a>.</li>
<li>Next, export it as a .pfx file following the <a href="https://www.digicert.com/util/pfx-certificate-management-utility-import-export-instructions.htm">export instructions</a>.</li>
<li>Store the password for the .pfx in a secure manner.</li>
</ol>
<h1 id="install-certificate-on-azure-app-service">Install certificate on Azure App Service</h1>
<h2 id="upload-pfx-certificate-to-azure-5-minutes">Upload PFX certificate to Azure (5 minutes)</h2>
<ol>
<li>Go to Azure Portal and access one of the App Services you wish to update. Go to the SSL settings blade.</li>
<li>Click on Private Certificate (.pfx) tab.</li>
<li>Click on Upload Certificate button.</li>
<li>Select the .pfx file exported from DigiCert Certificate Utility.</li>
<li>Enter the password used to secure the .pfx.</li>
<li>Click on Upload. This should take a few seconds. If the notifications say that it is still uploading after a minute, refresh the Portal and upload again.</li>
</ol>
<figure>
    <img src="azure-upload-pfx.png"
         alt="Screenshot showing labeled steps to upload PFX certificate to Azure"/> <figcaption>
            <h4>Upload PFX certificate to Azure</h4>
        </figcaption>
</figure>

<h2 id="assign-certificate-to-ssl-binding-5-minutes">Assign certificate to SSL Binding (5+ minutes)</h2>
<ol>
<li>Go back in the Bindings tab.</li>
<li>Scroll down to SSL Bindings section and update each binding with the new certificate.</li>
<li>Browse to the site and confirm the new certificate is being used.</li>
</ol>
<p>Refer to <a href="https://docs.microsoft.com/en-us/azure/app-service/app-service-web-tutorial-custom-SSL#bind-your-ssl-certificate">Microsoft documentation</a> because the Azure UI changes often.</p>
<p>I hope this helps someone! Probably myself, in a year&rsquo;s time.</p>
<p>Background photo credit: <a href="https://visualhunt.co/a1/5fdb850b">University of Glasgow Library</a> on <a href="https://visualhunt.com/re3/1b6991c0">Visual Hunt</a> / <a href="http://creativecommons.org/licenses/by-nc-sa/2.0/"> CC BY-NC-SA</a></p>
]]></content></item><item><title>How do you eat a giant pumpkin?</title><link>https://www.coderfrontline.com/how-do-you-eat-a-giant-pumpkin/</link><pubDate>Sun, 17 Mar 2019 09:00:00 +1300</pubDate><guid>https://www.coderfrontline.com/how-do-you-eat-a-giant-pumpkin/</guid><description>Here&amp;rsquo;s a useful analogy I use to explain how to break a feature down into its unit tests. I am using it in a TDD (Test-Driven Development) workshop I&amp;rsquo;m conducting in my team. Putting aside the fact that giant pumpkins are mainly bred for show, this will hopefully help new programmers when they&amp;rsquo;re faced with any programming challenge. I created this analogy as an alternative to &amp;ldquo;How do you eat an elephant?</description><content type="html"><![CDATA[<p>Here&rsquo;s a useful analogy I use to explain how to break a feature down into its unit tests. I am using it in a TDD (Test-Driven Development) workshop I&rsquo;m conducting in my team. Putting aside the fact that giant pumpkins are mainly bred for show, this will hopefully help new programmers when they&rsquo;re faced with any programming challenge. I created this analogy as an alternative to &ldquo;How do you eat an elephant?&rdquo; because elephants are majestic creatures and what are you, a monster? /s</p>
<figure>
    <img src="giant-pumpkin-aresauburn.jpg"
         alt="A giant pumpkin sitting in a field"/> <figcaption>
            <h4>A giant pumpkin</h4>
        </figcaption>
</figure>

<p>So how do you eat a giant pumpkin? Piece-by-piece!</p>
<p>It may seem like an uphill climb when staring up a new programming challenge. Honestly it&rsquo;s a normal feeling among experienced developers like myself. The difference is we quickly start carving that pumpkin up into large segments, otherwise known as a feature breakdown. We ask ourselves some leading questions, like:</p>
<ul>
<li>What does the user want to achieve?</li>
<li>What are we interested within our input?</li>
<li>Do our inputs have things we want to exclude?</li>
<li>What are the edge cases?</li>
<li>How do we start transforming the input into output?</li>
</ul>
<p>This will effectively chop our pumpkin up into large segments. You can call this a feature, user story, task, etc.</p>
<figure>
    <img src="pumpkin-segments-joe-shlabotnik.jpg"
         alt="Large pumpkin segments placed to the left of some hollowed out whole pumpkins"/> <figcaption>
            <h4>Pumpkin segments</h4>
        </figcaption>
</figure>

<p>The pumpkin segments are still too large to eat though. You need to break down each segment into even smaller pieces. I ask leading questions like:</p>
<ul>
<li>What are our inputs?</li>
<li>What are our expected outputs?</li>
<li>What errors might happen here?</li>
<li>Which parts of the implementation are we writing our own logic, and which are we handing off to another API or library?</li>
</ul>
<p>This thought process helps to separate distinct parts of the program. For example, you would want to encapsulate your own algorithms away from external API calls. This way you can write unit tests for your own code without worrying about coding against the API. Over time this will break the feature down to individual methods that meet the Single Responsibility Principle. In other words, they are diced into a bite-sized morsels.</p>
<figure>
    <img src="diced-pumpkin-lalibela.jpg"
         alt="Diced pumpkin pieces"/> <figcaption>
            <h4>Diced pumpkin</h4>
        </figcaption>
</figure>

<p>I should conclude before I stretch this analogy out too much. New (and old!) software developers should cultivate their pumpkin-dicing skills in order to create applications that are more maintainable and readable. I did not specifically call out any unit test approaches, but this is extremely well-suited to how we can answer that perplexing conundrum: &ldquo;How do I write a test for a method that does not exist yet?&rdquo;</p>
<p>Hope you enjoy that delicious pumpkin pie at the end!</p>
<figure>
    <img src="pumpkin-pie-autumn-holiday-baked-delicious.jpg"
         alt="A slice of pumpkin pie next to the whole pie"/> <figcaption>
            <h4>Delicious pumpkin pie</h4>
        </figcaption>
</figure>

<p>Top and background photo credit: <a href="https://www.flickr.com/photos/aresauburnphotos/1865650749/">aresauburn™</a> on <a href="https://visualhunt.com">Visual hunt</a> / <a href="http://creativecommons.org/licenses/by-sa/2.0/"> CC BY-SA</a></p>
<p>Pumpkin segments photo credit: <a href="https://www.flickr.com/photos/joeshlabotnik/10864721445/">Joe Shlabotnik</a> on <a href="https://visualhunt.com">Visual hunt</a> / <a href="http://creativecommons.org/licenses/by-nc-sa/2.0/"> CC BY-NC-SA</a></p>
<p>Diced pumpkin photo credit: <a href="https://www.flickr.com/photos/lalibela_ethiopian_restaurant/15534775139/">Lalibela Ethiopian Restaurant</a> on <a href="https://visualhunt.com">VisualHunt.com</a> / <a href="http://creativecommons.org/licenses/by-nd/2.0/"> CC BY-ND</a></p>
]]></content></item><item><title>My static CMS site architecture</title><link>https://www.coderfrontline.com/my-static-cms-site-architecture/</link><pubDate>Wed, 06 Feb 2019 15:00:00 +1300</pubDate><guid>https://www.coderfrontline.com/my-static-cms-site-architecture/</guid><description>I mentioned in my last post that I started 2019 by moving this blog off WordPress and into a Hugo static CMS set up. I will go into more detail about the particular approach I took to migrate the site over the next several posts. I will start the series off by quickly showing you the main architectural differences between a traditional CMS like WordPress and a modern static CMS like Hugo or Jekkyl.</description><content type="html"><![CDATA[<p>I mentioned in my last post that I started 2019 by <a href="/new-year-new-beginnings/">moving this blog off WordPress</a> and into a Hugo static CMS set up. I will go into more detail about the particular approach I took to migrate the site over the next several posts. I will start the series off by quickly showing you the main architectural differences between a traditional CMS like WordPress and a modern static CMS like Hugo or Jekkyl.</p>
<figure>
    <img src="wordpress.svg"
         alt="Architecture diagram showing both blogger and visitor connecting to a LAMP stack server running WordPress"/> <figcaption>
            <h4>A typical WordPress site architecture</h4>
        </figcaption>
</figure>

<p>The image above shows a typical WordPress server on the web. The blogger connects to the WordPress administrator console running on the web server to manage content, while site visitors connect to the same server, either directly or via a CDN (Content Delivery Network). The CMS builds the page on-the-fly when a request for a particular page is received.</p>
<p>It is most likely an open-source LAMP stack server, meaning it is composed of Linux (Operating System), Apache (Web Server Software), MySQL (Database), and PHP (Programming language). You can run WordPress on Windows and SQL Server, but a LAMP server starts at $0 licensing costs. This is a major factor for the LAMP stack&rsquo;s continuing popularity.</p>
<p>A static CMS pushes the page building process up the production line, to when the blogger is writing content. The image below shows a basic static CMS architecture using Hugo. The blogger will create the content on their local environment such as a PC or Mac, and then run the Hugo command-line tool to generate the static .html files. These files are then pushed onto any web server, since all web servers are capable of serving up normal .html, .css, and .js files.</p>
<figure>
    <img src="hugo-basic.svg"
         alt="Architecture diagram showing a simple Hugo site setup where the blogger publishes pre-built .html files to web server"/> <figcaption>
            <h4>A basic Hugo site architecture</h4>
        </figcaption>
</figure>

<p>This is certainly adequate and most closely resembles the traditional low-cost WordPress server set up. However, the rise of cloud computing and serverless technologies is creating new possibilities for how we host content-rich websites that are scalable and yet cost very little.</p>
<figure>
    <img src="hugo-advanced.svg"
         alt="Architecture diagram showing an advanced Hugo site setup"/> <figcaption>
            <h4>An advanced Hugo site architecture</h4>
        </figcaption>
</figure>

<p>The architecture diagram above shows how I am currently building this blog. I, the blogger, write my content on my Mac and push changes up to a Git repository hosted on <a href="https://dev.azure.com">Azure DevOps</a> (previously known as Visual Studio Team Services or Visual Studio Online). GitHub is a more popular option, but I am familiar with Azure DevOps and like its all-in-one build and release pipelines.</p>
<p>I use the <a href="https://docs.microsoft.com/en-us/azure/devops/organizations/billing/buy-more-build-vs?view=azure-devops">complimentary build and release minutes</a> included in the free tier. The amount changes from time to time but is currently 30 hours a month, which is more than adequate for my needs. My site is built in the cloud and then released into an Azure Storage Blob account, with <a href="https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blob-static-website">static website hosting</a> turned on.</p>
<p>Lastly, I place a CDN service in front of the static website to get the benefits of a cheap, hihgly-scalable, and highly-responsive content delivery system. I have specifically chosen the Premium Verizon CDN offering, and I will explain the reasons why in a future post. A site visitor will be served my content from the closest edge node, so I do not have to worry about distribution or load balancing myself.</p>
<p>The diagram also has an optional App Service API that I have not implemented because I have no need for it. This is another common component of what&rsquo;s known as the <a href="https://jamstack.org/">JAMstack</a> - an alternative to the LAMP stack. JAM in this case stands for JavaScript (Programming language), API (Backend), and Markup (Content definition language). There are a lot of well-written information about what makes a good JAMstack on that site. My blog is more a J-Mstack as it stands, but I am considering adding an API layer for site searches.</p>
<p>Next time: I write about how each component is set up.</p>
]]></content></item><item><title>New Year, New Beginnings</title><link>https://www.coderfrontline.com/new-year-new-beginnings/</link><pubDate>Mon, 31 Dec 2018 09:00:00 +1300</pubDate><guid>https://www.coderfrontline.com/new-year-new-beginnings/</guid><description>A new year presents new opportunities to transform ourselves. New changes are afoot for this blog. This is the first new post since I migrated this blog from my old WordPress installation to Hugo static CMS.
Minimum Viable Product I still need to refine many aspects of the blog so what you see as of Dec 31st, 2018 will surely change. I am taking an Agile approach by launching with my MVP (Minimum Viable Product) to gauge interest and refine my product as I go along.</description><content type="html"><![CDATA[<p>A new year presents new opportunities to transform ourselves. New changes are afoot for this blog. This is the first new post since I migrated this blog from my old WordPress installation to <a href="https://gohugo.io/">Hugo</a> static CMS.</p>
<h2 id="minimum-viable-product">Minimum Viable Product</h2>
<p>I still need to refine many aspects of the blog so what you see as of Dec 31st, 2018 will surely change. I am taking an Agile approach by launching with my MVP (Minimum Viable Product) to gauge interest and refine my product as I go along. Plus, there&rsquo;s always more motivation to work on a live product rather than one that is stuck in draft forever.</p>
<p>You will most likely read this once I&rsquo;ve improved on this version, so here are some screenshots of my old WordPress blog and the new blog (as of post date):</p>
<p><figure>
    <img src="wp-homepage-menu.png"
         alt="WordPress-based homepage and menu"/> <figcaption>
            <h4>WordPress-based homepage and menu</h4>
        </figcaption>
</figure>

<figure>
    <img src="hugo-homepage.png"
         alt="New Hugo-based homepage"/> <figcaption>
            <h4>New Hugo-based homepage</h4>
        </figcaption>
</figure>

<figure>
    <img src="hugo-post.png"
         alt="New Hugo-based post"/> <figcaption>
            <h4>New Hugo-based post</h4>
        </figcaption>
</figure>
</p>
<h2 id="reasons-for-change">Reasons for change</h2>
<ol>
<li>I wanted to massively reduce the risk of being hacked since I am not diligent with updating WordPress with the latest patches.</li>
<li>I wanted to cut my hosting costs down to the minimum because this is only a personal blog.</li>
<li>I wanted to learn new technology.</li>
</ol>
<h2 id="current-technology-stack">Current technology stack</h2>
<ul>
<li>CMS: Hugo</li>
<li>Editor: Visual Studio Code with <a href="https://github.com/Microsoft/vscode-azurestorage">Azure Storage extension</a> to simplify static website publishing</li>
<li>Hosting: Azure Storage with <a href="https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blob-static-website">Static Website hosting</a> behind Azure Premium CDN for scalability and managed TLS certificates</li>
<li>Code repository: Azure DevOps with automated build on master branch updates. I will work on automated releases in the near future.</li>
</ul>
<h2 id="new-journey">New journey</h2>
<p>I will write more about my migration journey in future posts, especially as I attempt to bundle up the Azure resource configuration into an ARM template that anyone can reuse.</p>
<p>You can also refer to Chris' blog post on <a href="https://gomakethings.com/migrating-from-wordpress-to-hugo/">Go Make Things</a> on how he migrated his site. Our approaches differ in several key areas, so his experience may be more relevant to your WordPress site setup.</p>
]]></content></item><item><title>How Zumba helped me become a better Tech Lead</title><link>https://www.coderfrontline.com/how-zumba-helped-me-become-a-better-tech-lead/</link><pubDate>Sat, 29 Sep 2018 21:50:12 +1200</pubDate><guid>https://www.coderfrontline.com/how-zumba-helped-me-become-a-better-tech-lead/</guid><description>I wrote about some of the commonalities between Zumba instructors and Tech Leads in my last post. I have a few more points to add on, which will give you an idea of the multitude of skills required to be either.
Multitasking Zumba instructors are fierce multitaskers. Our main job is to dance to the music so that participants can follow along. But we also need to think ahead to what the next move is because we need to inform the class that the change is coming.</description><content type="html"><![CDATA[<p>I wrote about some of the commonalities between Zumba instructors and Tech Leads in my <a href="/what-do-tech-leads-and-zumba-instructors-have-in-common/">last post</a>. I have a few more points to add on, which will give you an idea of the multitude of skills required to be either.</p>
<h2 id="multitasking">Multitasking</h2>
<p>Zumba instructors are fierce multitaskers. Our main job is to dance to the music so that participants can follow along. But we also need to think ahead to what the next move is because we need to inform the class that the change is coming. This is known as pre-cueing and is the next most important thing that group fitness instructors do. At the same time I visually scan the room to make sure that my class members are enjoying themselves and executing the moves safely. There have been instances where I had to get someone’s attention to tell them that their shoelaces are undone. While I kept dancing. And getting ready for move changes.</p>
<p>Tech Leads need to multitask as well. There are very few days where I can sit down and just focus on coding. My weeks are filled with code reviews, preparing statement of works, running meetings, identify roadblocks, and planning resource allocations for upcoming projects. People interrupt me throughout the day for things that they need and it’s my job to be there for them. In fact, I wrote a whole other post about how I <a href="/2018/02/context-switching-recovery-using-diary/">recover from context switching</a>.</p>
<h2 id="role-model">Role model</h2>
<p>I struggle to think of another profession where the term ‘role model’ applies better than to fitness instructors. Class members <em>literally</em> follow my every move for 55 minutes. It is important to be comfortable in front of crowds and be treated as a semi-public persona. I will admit putting on a bit of a character when I change into my Zumba clothes because I represent the Zumba brand, the gym I work for, and my personal reputation.</p>
<p>Tech Leads are role models as well. An individual contributor’s actions reflect back on their teams too, but Tech Leads have an amplified ability to influence perceptions. That is why I think great Tech Leads have to be comfortable with speaking and presenting to a crowd. I believe there are two levels to this.</p>
<p>The first level is to speak to their teams as a group. Tech Leads have the responsibility to shape and influence how technical work is done in the team, and it is more efficient to influence an entire group rather than one person at a time, although that is necessary in certain cases. For example, I did a presentation on the value of unit tests in managing the complexity of legacy code during our team meeting.</p>
<p>The second level is to speak to groups outside their teams. This can be talks inside the company, e.g. brown bag lunch sessions, or talks outside the company, e.g. Meetup gatherings. This is where Tech Leads start presenting an idealized image of their teams and companies, whatever that image may be. In blunt terms, this builds political capital and goodwill for both the Tech Lead and their teams. This makes it easier to attract new talent to the team and increase the Tech Lead’s influence when angling for new opportunities.</p>
<h2 id="continuous-improvement">Continuous Improvement</h2>
<p>Zumba instructors, and all dance instructors by extension, don’t have it easy. Casual observers may think we reuse the same material, but we have to continuously learn new songs and moves to keep our classes fresh. Les Mills programs have an entirely new class every quarter, while Zumba instructors receive about 10 new routines every two months. That’s a lot of continuous improvement. Personally, I aim to learn or choreograph one new song each week because I work better with constant, spread-out effort rather than bursts of intense learning. Either way, we have to keep working to stay in work.</p>
<p>This is no different for Tech Leads. There is no magical finish line when one becomes a Tech Lead. We don’t just sit back with our existing knowledge and start issuing epithets about how developers should write programs. At least, I don’t! On the other hand, there is too much tech to learn all of them in detail. It is a difficult balance because Tech Leads need to stay abreast of different technological trends while also knowing enough about them to make recommendations to the team. The appetite for continuous improvement is required whichever approach one takes.</p>
<h2 id="conclusion">Conclusion</h2>
<p>I hope I’ve demonstrated how two very different professions can require different skills but actually need many similar qualities. I genuinely believe that my experience being a Zumba instructor has helped me navigate my journey to be a top-notch Tech Lead. And I hope you enjoyed the insight into how much work Zumba instructors put in to create a world-class exercise program!</p>
<p>Photo credit: <a href="https://visualhunt.com/author/072fb8">pontla</a> on <a href="https://visualhunt.com/re/d06206">Visualhunt.com</a> /  <a href="http://creativecommons.org/licenses/by-nc-nd/2.0/">CC BY-NC-ND</a></p>
]]></content></item><item><title>What do Tech Leads and Zumba instructors have in common?</title><link>https://www.coderfrontline.com/what-do-tech-leads-and-zumba-instructors-have-in-common/</link><pubDate>Sun, 23 Sep 2018 15:25:58 +1200</pubDate><guid>https://www.coderfrontline.com/what-do-tech-leads-and-zumba-instructors-have-in-common/</guid><description>I’ve been a part-time Zumba instructor since 2011 and I was a certified Les Mills BodyJam instructor for a few years before that. I recently looked back at my past year being a Tech Lead at Datacom and I can see many similarities with the necessary qualities of being either. I am in a very unique position since I have inhabited both roles, hence I wrote this post to illuminate some of the non-obvious ways a group fitness instructor creates an effective workout session, and how that ties in to be a great Tech Lead.</description><content type="html"><![CDATA[<p>I’ve been a part-time Zumba instructor since 2011 and I was a certified Les Mills BodyJam instructor for a few years before that. I recently looked back at my past year being a Tech Lead at Datacom and I can see many similarities with the necessary qualities of being either. I am in a very unique position since I have inhabited both roles, hence I wrote this post to illuminate some of the non-obvious ways a group fitness instructor creates an effective workout session, and how that ties in to be a great Tech Lead.</p>
<h2 id="let-the-music-move-you">Let the music move you</h2>
<p>Music is <strong>the</strong> key differentiator in most group fitness classes. Music is used to guide the movements in a class, but the influence they have varies on the class format. They range from highly-choreographed affairs for classes like Zumba and BodyPump, then to loosely-guided classes like RPM and Les Mills GRIT, and finally to mood-setting background music for yoga classes.</p>
<p>Zumba instructors are allowed to choreograph their own dance tracks and inject them into their class. I take advantage of this by putting in popular songs and other cool dance tracks that I come across on Apple Music. I pick songs that I know will guide and lift the mood of the class.</p>
<p>A good Tech Lead interacts with his or her team members on a regular basis. My experience with choreographing dance tracks taught me that a person’s emotional state can be influenced from external sources like music. Tech Leads must recognize that they are their team’s external force – they have the power to set the mood if they choose to. This is illustrated clearly in the next section.</p>
<h2 id="tell-me-you-enjoyed-my-class">Tell me you enjoyed my class</h2>
<p>My Zumba classes are 55 minutes long and I have a standard routine after the final cooldown song: I clap my hands to congratulate the class for finishing, say thank you, and ask them to come forward with feedback or questions. I usually get some applause back and a few “Thank you!” from the crowd.</p>
<p>Something special does happen once in a while. I sometimes get first-timers come up to me and say how much they enjoyed the class and how it’s unlike any other Zumba classes they have been to. I also get regulars asking if I teach anywhere else, and that they wished I did more classes at their gym.</p>
<p>I will admit that it makes me feel good about myself. We are taught to be humble and not sing our own praises, but I allow myself some satisfaction that my efforts to lead an enjoyable class were recognized.</p>
<p>This is something that good Tech Leads do as well. They are always on the lookout for the great stuff that their team does, and actively compliment the person or the deed. This does not have to be a loud sing-and-dance in front of everyone else. It can be as simple as a passing comment at the coffee station, or a written note. I would encourage writing it down for future reference if your company does 360° reviews, which Datacom does.</p>
<h2 id="5-6-7-8">5, 6, 7, 8!</h2>
<p>The main job of a Zumba instructor is to lead the class with pre-choreographed moves to music in order to elevate their heart rate for an effective workout. We give minimal breaks because it is important to maintain that elevated heart rate. Therefore, the instructions need to happen during the track and we don’t have the luxury of going through all the moves before a song.</p>
<p>Group fitness instructors use a combination of visual and audio cueing, with visual cues being the preferred option for Zumba classes so as not to interrupt the music. Common visual cues include counting down the repetitions required, direction to travel, and getting the class’ attention when a new move is coming up. This is usually done with my hands, but the facial muscles get a workout too especially when I remind my class to smile and enjoy themselves.</p>
<p>I sometimes put on a microphone if there are more technical moves involved such as when they are facing away from me. This is required if I’m instructing another class like BodyJam where we slowly build up a 30 second routine since there are not enough hand signals in the world to represent all the moves!</p>
<p>The point that Tech Leads should take away is that communication happens via different channels. There are the obvious, conscious ones like e-mails and face-to-face, but there are also unconscious ways like body language and putting on headphones to say that you don’t want to be interrupted. Tech Leads need to be comfortable using multiple communication channels and understand what is being said (or not said!)</p>
<h2 id="next-week">Next week</h2>
<p>I will finish this post by covering <a href="/how-zumba-helped-me-become-a-better-tech-lead/">other common things</a> that Zumba instructors do that have helped me become a better Tech Lead.</p>
<p>Photo credit: <a href="https://visualhunt.com/author/7a64ee">Lifeline Australia</a> on <a href="https://visualhunt.com/re/77638c">Visual hunt</a> /  <a href="http://creativecommons.org/licenses/by/2.0/">CC BY</a></p>
]]></content></item><item><title>Starting My Functional Journey</title><link>https://www.coderfrontline.com/starting-my-functional-journey/</link><pubDate>Sun, 20 May 2018 12:44:45 +1200</pubDate><guid>https://www.coderfrontline.com/starting-my-functional-journey/</guid><description>I joined a new team as Tech Lead about 6 months ago. Rather than sit back and bark orders, it has become even more important to sharpen my technical skills. I&amp;rsquo;ve chosen to start on my functional journey to become proficient in F# - the .Net functional programming language.
F# has been around for a long time but many from the C# camp have dismissed it as a niche language for the scientific and mathematic arena.</description><content type="html"><![CDATA[<p>I joined a new team as Tech Lead about 6 months ago. Rather than sit back and bark orders, it has become even more important to sharpen my technical skills. I&rsquo;ve chosen to start on my functional journey to become proficient in F# - the .Net functional programming language.</p>
<p>F# has been around for a long time but many from the C# camp have dismissed it as a niche language for the scientific and mathematic arena. But cross-pollination started bringing functional constructs to C#&rsquo;s imperative landscape and I clearly remember my first experience with lambda expressions back in .Net 3.5 (2007):</p>
<blockquote>
<p>Man, I hate this weird syntax! It looks cool but it isn&rsquo;t optimised for performance.</p>
</blockquote>
<p>I&rsquo;ve grown to love lambdas over the last decade for its concise and descriptive nature, especially when used in conjunction with LINQ extension methods like Select and Sum, which originated in functional languages. I started thinking about designing for immutability and organising my methods into behaving like functions.</p>
<p>However I have realised that C# will always pale in comparison to a pure functional language because it is too easy to fall back to an imperative and mutable coding approach when things get tough. Hence my decision to look at F# a little closer because it is a solid functional language within the rich .Net ecosystem. Thus begins my functional journey… we&rsquo;re not in Kansas anymore!</p>
<p>The opportunity presented itself via the <a href="https://www.meetup.com/Functional-Programming-Auckland">Functional Programming Auckland Meetup</a> when they organised a Learn F# Hands-On session. Sam from <a href="http://www.codingwithsam.com/">Coding With Sam</a> was our tutor and he was great in tailoring the content to each learner&rsquo;s experience level. That real-time feedback and personalised content is something that online courses struggle to match, so I really appreciated Sam&rsquo;s guidance during and after the session.</p>
<p>(Note: I previously showcased another Functional Programming Auckland Meetup event when I wrote extensively about <a href="/first-impressions-functional-reactive-programming-sodium/">Functional Reactive Programming</a>)</p>
<p>The session focused on <a href="https://github.com/ChrisMarinos/FSharpKoans">FSharpKoans</a> and that is a great introduction to F# syntax and constructs for people who know a little programming. It is a very gentle and guided tour… until the training wheels come off midway with the Stock example. I&rsquo;ve read gripes about how some found this difficult but I relished the challenge as it shows who understood the concepts vs. those who were filling in the blanks.</p>
<p>I completed the Koans and have now moved on to <a href="http://exercism.io/languages/fsharp/exercises">exercism.io</a> to continue my F# education. It is a little fiddly to get the initial set up right, but is a great learning platform because you can use your favourite IDE to solve the problems vs. using an online-only solution like HackerRank. The exercises are focused on implementing algorithms while bringing in important techniques such as tail recursion - something I&rsquo;m still trying to get comfortable with. I like this approach because I need to get comfortable with syntax before I worry about real-world tasks like querying DBs and updating UIs.</p>
<p>Do you know other good learning resources? Sound out in the comments! I will share new resources as I learn about them.</p>
<p>Photo credit: <a href="https://visualhunt.com/author/35aae3">duncan</a> on <a href="https://visualhunt.com/re/252f2d">VisualHunt.com</a> /  <a href="http://creativecommons.org/licenses/by-nc/2.0/">CC BY-NC</a></p>
]]></content></item><item><title>Context Switching Recovery Using A Diary</title><link>https://www.coderfrontline.com/context-switching-recovery-using-a-diary/</link><pubDate>Sun, 11 Feb 2018 14:12:11 +1200</pubDate><guid>https://www.coderfrontline.com/context-switching-recovery-using-a-diary/</guid><description>The term ‘context switching’ originated from the world of computing but has migrated into popular culture in relation to the wasted time caused by human multitasking. Context switching usually causes reduced productivity due to the effort of splitting focus over multiple tasks at once. This is something that most human brains are not good at. What can we do about it?
Our modern and busy lives force us to change our focus throughout the day.</description><content type="html"><![CDATA[<p>The term ‘context switching’ originated from the world of computing but has migrated into popular culture in relation to the wasted time caused by <a href="https://en.wikipedia.org/wiki/Human_multitasking">human multitasking</a>. Context switching usually causes reduced productivity due to the effort of splitting focus over multiple tasks at once. This is something that most human brains are not good at. What can we do about it?</p>
<p>Our modern and busy lives force us to change our focus throughout the day. I find this to be especially true in my role as Tech Lead in a leading IT services company. A key responsibility of mine is to be available to other team members when they need assistance. Hence it is common to be interrupted throughout the day while I’m doing my own tasks. I would stop what I was doing, spend some time with the team member, and then have to stare blankly at my screen for five minutes as I try to piece together what I was doing before I was shoulder tapped. We’ve all experienced that, right? You’re probably nodding your head in agreement!</p>
<p>I recently implemented a system to help me reduce the cognitive burden of context switching. Meet the humble planning diary:</p>
<p><a href="/wp-content/uploads/sites/2/2018/02/a5-diary.jpg"><img src="/wp-content/uploads/sites/2/2018/02/a5-diary.jpg" alt="" width="640" height="483" class="aligncenter size-large wp-image-397" srcset="/wp-content/uploads/sites/2/2018/02/a5-diary.jpg 1024w, /wp-content/uploads/sites/2/2018/02/a5-diary.jpg 300w, /wp-content/uploads/sites/2/2018/02/a5-diary.jpg 768w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>
<p>Here is how I use my diary: The first few minutes at work is spent writing out the main tasks I want to complete that day. It is not important to put them in chronological order or go into excruciating detail. In that sense it behaves more like a to-do list. Here’s how a sample day might start off:</p>
<p>8 February (Thursday)</p>
<ul>
<li>Architecture diagram for Project E</li>
<li>Investigate bug J-4</li>
<li>Team meeting</li>
</ul>
<p>I tick each off as I finish them or strike it through if I couldn’t get to it that day. I also add tasks to it if I have to do something for a team member to keep myself accountable. This is what my diary might look like at 1pm after Ben asks me to do an urgent code review:</p>
<p>8 February (Thursday)</p>
<ul>
<li>✓ Architecture diagram for Project E</li>
<li><span style="text-decoration: line-through;">Investigate bug J-4</span></li>
<li>Team meeting</li>
<li>Code review for Ben</li>
</ul>
<p>I will also take notes from meetings and write down questions that pop up throughout the day. I went with a small diary to force me to be concise. This is the (slightly) messy result at the end of Thursday:</p>
<p>8 February (Thursday)</p>
<ul>
<li>✓ Architecture diagram for Project E</li>
<li><span style="text-decoration: line-through;">Investigate bug J-4</span></li>
<li>✓ Team meeting</li>
<li>✓ Code review for Ben</li>
<li>Meeting notes:
<ul>
<li>Team building event being planned for next month</li>
<li>Julie is onboarding a new customer next week</li>
</ul>
</li>
<li>How to convert VMWare to Hyper-V?</li>
</ul>
<p>These are the ways a diary has helped me reduce the mental load of context switching:</p>
<p>First, it helps me get back on track after being distracted. I don’t have to try to recall what I was doing before. I will scan my diary instead. The tasks act as mental way finders that usually lead me to where I need to go anyway. In the example above, I might think to myself, “That’s right, I was starting to investigate the J-4 issue, but Ben needed his code reviewed so I did that instead. I need to go to a team meeting soon so I won’t have time to actually investigate the bug. I’ll cross that out and get to it tomorrow.”</p>
<p>Second, any new commitments I make during the context switch is noted immediately without having to change computer windows. Having to minimize the IDE to switch to Outlook just to add a reminder usually makes context switching worse! In contrast, the paper diary is a dedicated screen that is always visible and available, without having to disturb the Zen of my computer workspace. I make time during my break to create calendar invites if necessary, so I get the benefit of automated reminders as well.</p>
<p>Lastly, it helps me review and remember what I did in previous weeks. This is not directly related to context switching but it is still useful! I can barely remember what I had for lunch yesterday, much less the outcome of team meetings a month ago. I also remember things better if I write them down, even if I never refer to the notes again.</p>
<p>In summary, keeping a paper diary has helped me manage the effects of context switching. A low-cost alternative is Post-It notes. You can get most of the benefits by doing the same thing within a single sticky note and sticking it next to your trackpad. That was what I started with. Let me know what other techniques you’ve found useful in the comments section!</p>
<p>Featured Photo credit: <a href="https://visualhunt.com/author/2b5ccf">Internet Archive Book Images</a> on <a href="https://visualhunt.com/re/7a6eea">Visualhunt.com</a> /  <a href="http://flickr.com/commons/usage/">No known copyright restrictions</a></p>
]]></content></item><item><title>Invest in the Best Tools You Can Afford</title><link>https://www.coderfrontline.com/invest-in-the-best-tools-you-can-afford/</link><pubDate>Sun, 03 Dec 2017 10:56:07 +1200</pubDate><guid>https://www.coderfrontline.com/invest-in-the-best-tools-you-can-afford/</guid><description>I recently bought a new steam iron. I’ve been wearing more business shirts to work lately, which resulted in an increased number of creased shirts every wash. I have a working steam iron and I only bought the new one because it was heavily discounted. My usual philosophy is to use a piece of equipment until it breaks before getting a replacement, but I had a niggling feeling that I needed it.</description><content type="html"><![CDATA[<p>I recently bought a new steam iron. I’ve been wearing more business shirts to work lately, which resulted in an increased number of creased shirts every wash. I have a working steam iron and I only bought the new one because it was heavily discounted. My usual philosophy is to use a piece of equipment until it breaks before getting a replacement, but I had a niggling feeling that I needed it.</p>
<p>Boy, was I right! My original steam iron was a small Warehouse Necessities iron (entry-level home-brand from a big box store, for you non-Kiwi readers). It worked, but not very well. The surface area was small, it didn’t get very hot, and it would drip before it steamed. It was also cheap. The purchase made sense when I got it because I wasn’t wearing that many shirts and I had tight finances.</p>
<p>My requirements have changed seven years later. I always thought some of my shirts were permanently wrinkled. It turned out I just had a crap iron. This experience reminded me that you should always invest in the best tools you can afford. This advice is even truer for software developers.</p>
<p>I’ve come across places that are reluctant to purchase software licenses for developer tools like <a href="https://www.jetbrains.com/resharper">ReSharper</a>. Instead, the developers scrap together free tools that do sort of the same thing. For example, <a href="http://www.codemaid.net/">CodeMaid</a> is a free Visual Studio plugin that has a subset of ReSharper’s cleanup functions. CodeMaid is pretty good if that’s all you can afford, but most commercial developers who have used ReSharper will loathe to go without.</p>
<p>The fact is, ReSharper may not appear ‘cheap’ at $299 per license per year, but it’s only 5% of a junior developer’s annual salary of $60,000 per year. The productivity increase that a good tool provides will surely offset the license cost. So, invest in the best tools you can afford!</p>
<p>There are a couple of caveats to my advice.</p>
<p>First, you can bring the horse to water but you can’t make it drink. Some developers have a prescribed way of working and no fancy tool is going to change them. In that case, giving them a better tool will just be a waste since it’s not used.</p>
<p>Second, and this is for developers, we have to do a better job in highlighting the ROI of a particular tool. We cannot assume that our managers see the same benefits, since they operate at a macro level, so we have to run our own calculations and forecast the return on investment. A common approach is to measure potential time savings with and without the tool. Time is money, after all.</p>
<p>Photo by <a href="https://visualhunt.com/author/963828">Ravages</a> on <a href="https://visualhunt.com/re/c141cf">Visual Hunt</a> /  <a href="http://creativecommons.org/licenses/by-nc-sa/2.0/">CC BY-NC-SA</a></p>
]]></content></item><item><title>The Open Door Policy Is Not Enough</title><link>https://www.coderfrontline.com/the-open-door-policy-is-not-enough/</link><pubDate>Sun, 01 Oct 2017 13:47:38 +1200</pubDate><guid>https://www.coderfrontline.com/the-open-door-policy-is-not-enough/</guid><description>I remember hearing the term open door policy when I joined my first company after university. It was touted as a morale-booster because we are free to bring up any concerns we have with our managers, or even managers higher up the food chain. I remember being impressed by the concept when it was explained to me, but I&amp;rsquo;m beginning to question if the open door policy is doing more harm than good.</description><content type="html"><![CDATA[<p>I remember hearing the term open door policy when I joined my first company after university. It was touted as a morale-booster because we are free to bring up any concerns we have with our managers, or even managers higher up the food chain. I remember being impressed by the concept when it was explained to me, but I&rsquo;m beginning to question if the open door policy is doing more harm than good.</p>
<p>Let&rsquo;s quickly recap what the open door policy is. One <a href="https://en.wikipedia.org/wiki/Open_door_policy_(business)">common explanation</a> is a communication policy where “employees are encouraged to stop by whenever they feel the need to meet and ask questions, discuss suggestions, and address problems or concerns with management”. It&rsquo;s “intended to foster an environment of collaboration, high performance, and mutual respect between upper management and employees”.</p>
<p>I think the main issue with having the open-door policy is some managers think that it is sufficient to encourage employees to come to them with their issues. My experience over the past 10 years in the industry have taught me otherwise. People are well aware of the policy, but few would actually take the leap to bring a real issue up until it&rsquo;s critical. And we as managers want to resolve issues before they become serious.</p>
<p>I believe a few of the common reasons why most team members don&rsquo;t speak up without being asked might include:</p>
<ul>
<li>Fear that the open door policy is just lip service, and that they will be ‘punished' for bringing it up.</li>
<li>There&rsquo;s an internalised message that managers do not want to hear about problems unless it&rsquo;s accompanied by a solution. Some problems, by nature, need a manager&rsquo;s help to solve.</li>
<li>Unintended consequences of other communication policies like anonymous suggestion boxes and ombudsman processes give the impression that feedback should not be brought up in person, but should be kept hush-hush.</li>
</ul>
<p>Therefore, an open door policy is insufficient by itself because it is a passive system. It must be accompanied by active systems such as regular one-on-ones where the supervisor is able to create a safe space for the employee to discuss their job satisfaction and air any grievances they have.</p>
<p>Related articles:</p>
<ul>
<li><a href="https://www.cbsnews.com/news/is-your-open-door-policy-silencing-your-staff/">Is Your ‘Open Door' Policy Silencing Your Staff?</a></li>
<li><a href="https://www.thebalance.com/open-door-policy-1918203">Open Door Policy</a></li>
</ul>
<p>Photo credit: <a href="https://www.flickr.com/photos/boskizzi/1787626/">boskizzi</a> via <a href="https://visualhunt.com/re/eee892">Visualhunt.com</a> /  <a href="http://creativecommons.org/licenses/by-nc/2.0/">CC BY-NC</a></p>
]]></content></item><item><title>The Chess Master and The Gardener</title><link>https://www.coderfrontline.com/the-chess-master-and-the-gardener/</link><pubDate>Sun, 27 Aug 2017 21:32:57 +1200</pubDate><guid>https://www.coderfrontline.com/the-chess-master-and-the-gardener/</guid><description>&lt;p>I love listening to podcasts to entertain my commute. I&amp;rsquo;ll at least learn something if I&amp;rsquo;m going to be stuck in traffic 200 hours a year. One of my subscriptions is the &lt;a href="https://itunes.apple.com/us/podcast/the-tony-robbins-podcast/id1098413063?mt=2">Tony Robbins Podcast&lt;/a>, featuring the motivational guru interviewing a myriad of successful individuals. A recent episode that really resonated with me is a chat with General Stanley McChrystal and Chris Fussell, titled “&lt;a href="https://www.tonyrobbins.com/podcasts/becoming-extraordinary-leader/">Becoming an extraordinary leader&lt;/a>“. The interviewees served in the U.S. military for decades and have gained some insights into great leadership. An analogy the General used to describe leadership was the chess master and the gardener.&lt;/p></description><content type="html"><![CDATA[<p>I love listening to podcasts to entertain my commute. I&rsquo;ll at least learn something if I&rsquo;m going to be stuck in traffic 200 hours a year. One of my subscriptions is the <a href="https://itunes.apple.com/us/podcast/the-tony-robbins-podcast/id1098413063?mt=2">Tony Robbins Podcast</a>, featuring the motivational guru interviewing a myriad of successful individuals. A recent episode that really resonated with me is a chat with General Stanley McChrystal and Chris Fussell, titled “<a href="https://www.tonyrobbins.com/podcasts/becoming-extraordinary-leader/">Becoming an extraordinary leader</a>“. The interviewees served in the U.S. military for decades and have gained some insights into great leadership. An analogy the General used to describe leadership was the chess master and the gardener.</p>
<p>I&rsquo;ve always had the impression of military leaders as tough, disciplined warriors who would snap your neck if you even harboured a sense of disagreement. General McChrystal&rsquo;s early career hinted at that power structure. Note: numbers in [square brackets] indicate the minutes and seconds into the podcast that the transcript begins.</p>
<blockquote>
<p class="p1">
  [08:45] I thought that leaders were a command-and-control function. You got information from across your organisation, you use your experience and what intellect you had and aided maybe by (<em>unclear</em>). You made decisions and then you directed those decisions down into the organisation to comply. And if you were a better strategist than your opponent, you would win.
</p>
</blockquote>
<p>That&rsquo;s certainly my assumption about the military. I&rsquo;ve met similar leaders in my IT career. The General understands the temptation.</p>
<blockquote>
<p class="p1">
  [14:15] There’s also a human side to it as well. When someone’s put in charge of an organisation, as a leader they think that they’re the best qualified person to make decisions. They’re going to be held responsible for the outcomes so there’s a tendency to want to make the decisions that determine it.
</p>
</blockquote>
<p>This is where the analogy of the chess master and the gardener comes in. It was mentioned in his book and he summarises it in the podcast:</p>
<blockquote>
<p class="p1">
  [47:00] For years I thought that chess master was the best analogy to a successful leader because a chess master controls 16 chess pieces and moves them. And if he or she is a good strategist, they win. And they’re micro-managing each of those chess pieces.
</p>
<p class="p1">
  When I got into Iraq I started that way, and then I found that out my opposition Al-Qaeda in Iraq was not a chess master controlling pieces - it was a set of chess pieces that all connected and had relative autonomy. So as a consequence there’s no way one person can defeat a multiple group like that that’s constantly adapting.
</p>
<p class="p1">
  So slowly … I realised that gardener is a better analogy for it. Because if you think what a gardener does, a gardener doesn’t grow anything. Only plants can grow things. But the gardener is critical, because the gardener creates the environment. The gardener prepares the ground, the gardener plants, waters, feeds, weeds, protects, and at the appropriate time, harvests. If the gardener does it right, all those plants can do that concurrently, and so suddenly you can scale.
</p>
<p class="p1">
  The gardener is completely busy. It’s not a case of empower your subordinates, go home, and let me know how it works. You’re constantly protecting the garden so the garden’s plants are able to do it. And so I believe it’s a less ego-centric way of leading. It takes a little bit of courage to do it because you are allowing your entities to execute. There’s always a chance it’s not going to come out and you’re going to be held responsible. But it’s in my view the only way that will operate in an environment that is changing fast. And it also has the added benefit that people who are doing it with you feel like they are part of us. They don’t feel like they’re employees of the leader.
</p>
</blockquote>
<p>The gardener analogy really struck me as something profoundly straightforward but also difficult to practice. I definitely didn&rsquo;t expect that leadership style from a four-star general! One example that illustrates his ‘gardener' approach was:</p>
<blockquote>
<p class="p1">
  [23:00] My requirement was to be a connector. My requirement was to move around the organisation, orchestrate conversations, [and] create connections. Much like Steve Wynn did, we did a daily teleconference across the entire command and I was sort of the ringleader for it. I didn’t make a lot of decisions or give guidance but I would make sure that people across the organisation who didn’t know each other and think they had shared equities were connecting because we’re trying to defeat a networked enemy.
</p>
</blockquote>
<p>The almost 90-minute long interview goes into a lot more detail and I would recommend listening to it in chunks. That is because the interviewing style gets a bit dry without fancy sound editing to avoid audio monotony. It has lots of great content that becomes food for thought.</p>
<p>So: are you a chess master or a gardener?</p>]]></content></item><item><title>The Little Things Matter</title><link>https://www.coderfrontline.com/the-little-things-matter/</link><pubDate>Mon, 07 Aug 2017 16:28:09 +1200</pubDate><guid>https://www.coderfrontline.com/the-little-things-matter/</guid><description>&lt;p>I had a day off today after a stressful month. So I decided to treat myself to a massage to work out those tense shoulders I&amp;rsquo;ve been carrying around. But I saw something before the massage even started that reaffirmed my belief that the little things matter more than we appreciate.&lt;/p></description><content type="html"><![CDATA[<p>I had a day off today after a stressful month. So I decided to treat myself to a massage to work out those tense shoulders I&rsquo;ve been carrying around. But I saw something before the massage even started that reaffirmed my belief that the little things matter more than we appreciate.</p>
<p>The massage place (which shall remain unnamed) was in an aging office building. It shared the space with other health and beauty businesses, and the massage room had three cubicles separated by curtains. After signing it at reception I was brought to my massage bed and asked to strip to my underwear. The therapist then left me to undress. I then looked up to see an old heat pump unit that was very clogged with dust. I didn&rsquo;t take a photo but it was only slightly better than this:<figure id="attachment_366" style="width: 448px" class="wp-caption aligncenter"></p>
<p><a href="/wp-content/uploads/sites/2/2017/08/Clogged-Air-Conditioning-Filter.jpeg"><img class="wp-image-366 size-full" src="/wp-content/uploads/sites/2/2017/08/Clogged-Air-Conditioning-Filter.jpeg" alt="" width="448" height="336" srcset="/wp-content/uploads/sites/2/2017/08/Clogged-Air-Conditioning-Filter.jpeg 448w, /wp-content/uploads/sites/2/2017/08/Clogged-Air-Conditioning-Filter-300x225.jpeg 300w" sizes="(max-width: 448px) 100vw, 448px" /></a><figcaption class="wp-caption-text">Clogged filter (from <a href="http://easycleantips.info/your-ac-can-be-source-of-air-pollution/">Easy Cleaning Tips</a>)</figcaption></figure></p>
<p>I was honestly shocked at how dirty it was. I proceeded with the massage but I kept thinking about it while the skilled masseur kneaded and stretched my muscles. There&rsquo;s not much else one can do but think while lying on a massage table!</p>
<p>The next natural thought was, “What other corners are they cutting if they can&rsquo;t find 5 minutes to give the heat pump a wipe down?” That&rsquo;s quite a valid concern when you&rsquo;re half-naked and potentially in contact with what the previous client left behind. This is quite a shame considering the masseur was very talented! But, the little things matter. The simple omission of wiping down the filter regularly has cost them a potential regular customer.</p>
<p>I think back to the world of software development and reflected upon times when the little things mattered. Simple acts like writing code comments, ensuring variables have good names, and writing unit tests do not take much effort but pay huge dividends down the line when someone else debugs your code.</p>
<p>Photo credit: <a href="https://www.flickr.com/photos/mompl/4434932432/">mompl</a> via <a href="https://visualhunt.com/re/00c098">Visual Hunt</a> /  <a href="http://creativecommons.org/licenses/by-nc-nd/2.0/">CC BY-NC-ND</a></p>]]></content></item><item><title>Humidity Monitor - Winter of Xamarin 2017</title><link>https://www.coderfrontline.com/humidity-monitor-winter-of-xamarin-2017/</link><pubDate>Wed, 28 Jun 2017 23:42:47 +1200</pubDate><guid>https://www.coderfrontline.com/humidity-monitor-winter-of-xamarin-2017/</guid><description>I&amp;rsquo;m delighted to announce that I won Microsoft&amp;rsquo;s Winter of Xamarin competition this year with my Humidity Monitor App. Here&amp;rsquo;s my submission video:
The sanitised source code (with the keys and connection strings removed) is on my GitHub repo. Here&amp;rsquo;s a rough guide on how you can replicate the project and some ideas to extend it further:
Pre-requisites A Raspberry Pi 3 running Windows 10 IoT Sense HAT module Recommended: 40-pin GPIO ribbon cable to keep some distance between the Pi and the Sense HAT because the Pi&amp;rsquo;s hot running temperature will affect Sense HAT readings (Optional) A Belkin WeMo Smart Switch or alternative smart switch that can connect to IFTTT (Optional) A dehumidifier that can be turned on from the switch (i.</description><content type="html"><![CDATA[<p>I&rsquo;m delighted to announce that I won Microsoft&rsquo;s Winter of Xamarin competition this year with my Humidity Monitor App. Here&rsquo;s my submission video:</p>
<p>The sanitised source code (with the keys and connection strings removed) is on <a href="https://github.com/zemien/HumidityMonitor">my GitHub repo</a>. Here&rsquo;s a rough guide on how you can replicate the project and some ideas to extend it further:</p>
<h1 id="pre-requisites">Pre-requisites</h1>
<ul>
<li>A <a href="https://pishop.nz/RPI3-COMBO-1/">Raspberry Pi 3</a> running <a href="https://developer.microsoft.com/en-us/windows/iot/downloads">Windows 10 IoT</a></li>
<li><a href="https://www.pbtech.co.nz/product/SEVRBP0073/Raspberry-Pi-Official-Sense-HAT-with-Orientation-P">Sense HAT</a> module</li>
<li>Recommended: <a href="https://pishop.nz/RPI-DUPONT/">40-pin GPIO ribbon cable</a> to keep some distance between the Pi and the Sense HAT because the Pi&rsquo;s hot running temperature will affect Sense HAT readings</li>
<li>(Optional) A Belkin WeMo Smart Switch or alternative smart switch that can connect to IFTTT</li>
<li>(Optional) A dehumidifier that can be turned on from the switch (i.e. does not require additional button presses on the device)</li>
<li>(Optional) A free If This Then That (<a href="https://ifttt.com">IFTTT</a>) account</li>
<li>Windows 10 PC or laptop is required to build Universal Windows Platform (UWP) apps, which is the platform Windows 10 IoT uses. A Mac OS computer can be used for all other development tasks in this project.</li>
<li><a href="https://www.visualstudio.com/downloads/">Visual Studio 2017</a> (Windows or Mac) Community Edition and above. Make sure to choose UWP Development and Mobile Development options when installing.</li>
<li><a href="https://www.syncfusion.com/products/xamarin">Syncfusion Essential Studio for Xamarin</a>: Syncfusion generously offers free <a href="https://www.syncfusion.com/products/communitylicense">community licenses</a> for individual developers and small organisations.</li>
<li>An <a href="https://azure.microsoft.com/en-us/">Azure</a> subscription. I stick to free tiers where possible. The only thing I am paying for is Azure Table Storage and it costs about $0.01 a month even after my sensor has been uploading data for a month.
<ul>
<li>Join the <a href="https://www.visualstudio.com/dev-essentials/">Visual Studio Dev Essentials</a> program if you don&rsquo;t have an existing Azure subscription because it provides free Azure credits over 12 months, along with other great benefits.</li>
</ul>
</li>
<li>Git clone the Humidity Monitor App <a href="https://github.com/zemien/HumidityMonitor">source code from GitHub</a>. Make sure it builds successfully on Visual Studio 2017 before proceeding further. This helps validate you have all the required components.</li>
</ul>
<h1 id="humidity-logger-uwp">Humidity Logger (UWP)</h1>
<p>The Humidity Logger is a simple Windows 10 Universal Windows Platform app that reads the relative humidity sensor on the Sense HAT and uploads aggregated data to Azure Table Storage. This app can only run successfully on a Pi with Sense HAT even though you could launch it in any Windows 10 device.</p>
<h2 id="azure-table-storage">Azure Table Storage</h2>
<p>We first need to create an Azure Table Storage table to load readings in. We will specify three pieces of information - the location of the sensor (e.g. “Lounge”) as the Partition Key, the UTC date time it was inserted as the Row Key, and the relative humidity reading as an integer.</p>
<p>The Row Key is inserted as the number of ticks before DateTime.Max. This results in a decrementing number that I call Reverse Ticks in the code. This was done because Azure Table Storage is a simple NoSQL storage solution that doesn&rsquo;t have advanced querying or indexing capabilities. It automatically orders records by Partition Key and Row Key in ascending order, which means the record with the smallest Row Key (i.e. the most recently inserted record) is at the top. This makes it trivial to select the latest reading as I just need to read the first record.</p>
<p>Here&rsquo;s the basic steps to get the Azure Table Storage up and running for the logger:</p>
<p>Log in to the <a href="https://portal.azure.com">Azure Portal</a> and click on the Add button to go to the Marketplace. Choose Storage account and specify options. I have gone with the cheapest options where possible, including Locally-redundant storage (LRS).</p>
<p><img class="alignnone wp-image-354 size-large" src="/wp-content/uploads/sites/2/2017/06/01-create-azure-table-storage.png" alt="Create storage account in Azure Portal" width="640" height="403" srcset="/wp-content/uploads/sites/2/2017/06/01-create-azure-table-storage.png 1024w, /wp-content/uploads/sites/2/2017/06/01-create-azure-table-storage.png 300w, /wp-content/uploads/sites/2/2017/06/01-create-azure-table-storage.png 768w" sizes="(max-width: 640px) 100vw, 640px" /></p>
<p>Next, go to Access keys and copy one of the connection strings. We will use this in two places in our code.</p>
<p><img class="alignnone wp-image-355 size-large" src="/wp-content/uploads/sites/2/2017/06/02-access-key.png" alt="Obtain connection string" width="640" height="373" srcset="/wp-content/uploads/sites/2/2017/06/02-access-key.png 1024w, /wp-content/uploads/sites/2/2017/06/02-access-key.png 300w, /wp-content/uploads/sites/2/2017/06/02-access-key.png 768w" sizes="(max-width: 640px) 100vw, 640px" /></p>
<h2 id="add-connection-strings">Add Connection Strings</h2>
<p>The first place to add that Azure Table Storage connection string is in HumidityLogger\MainPage.xaml.cs in the SetUpAndLaunch() method:</p>
<div class="highlight"><pre class="chroma"><code class="language-csharp" data-lang="csharp"><span class="n">actions</span><span class="p">.</span><span class="n">Add</span><span class="p">(</span><span class="k">new</span> <span class="n">AverageHumidityAction</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="k">new</span> <span class="n">TableStorageHumidityLogger</span><span class="p">(</span><span class="s">&#34;TODO - Location code&#34;</span><span class="p">,</span>
    <span class="s">&#34;TODO - Azure table storage connection string&#34;</span><span class="p">,</span> <span class="s">&#34;HumidityLog&#34;</span><span class="p">)));</span>
</code></pre></div><p>Also note the need for a Location code. This is used as the Partition Key in the table storage so keep it succinct, e.g. “Lounge”.</p>
<h2 id="deploy-to-raspberry-pi">Deploy to Raspberry Pi</h2>
<p>I find debugging the application is the easiest way to deploy UWP apps onto the Pi. Once that&rsquo;s done, go into the Pi&rsquo;s <a href="https://developer.microsoft.com/en-us/windows/iot/docs/deviceportal">Windows Device Portal</a> and make it the default app to run on startup.</p>
<h1 id="humidity-monitor-api">Humidity Monitor API</h1>
<p>I&rsquo;ve decided to create a .Net Core Web API from scratch, as opposed to using the Xamarin project template&rsquo;s option to generate a Web API backend. I&rsquo;ve kept the API very simple with only a few supported actions. The main logic revolves around converting DateTime requests to and from the ReverseTicks structure used as the Row Key. Unit tests validate the conversion logic.</p>
<h2 id="add-connection-strings-1">Add Connection Strings</h2>
<p>Paste the Azure Table Storage connection string from earlier into the HumidityController&rsquo;s constructor:</p>
<div class="highlight"><pre class="chroma"><code class="language-csharp" data-lang="csharp"><span class="k">public</span> <span class="n">HumidityController</span><span class="p">()</span>
<span class="p">{</span>
    <span class="kt">var</span> <span class="n">storageAccount</span> <span class="p">=</span> <span class="n">CloudStorageAccount</span><span class="p">.</span><span class="n">Parse</span><span class="p">(</span><span class="s">&#34;TODO - Cloud table connection string&#34;</span><span class="p">);</span>
    <span class="n">_client</span> <span class="p">=</span> <span class="n">storageAccount</span><span class="p">.</span><span class="n">CreateCloudTableClient</span><span class="p">();</span>
    <span class="n">_tableName</span> <span class="p">=</span> <span class="s">&#34;HumidityLog&#34;</span><span class="p">;</span>
    <span class="n">_table</span> <span class="p">=</span> <span class="n">_client</span><span class="p">.</span><span class="n">GetTableReference</span><span class="p">(</span><span class="n">_tableName</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div><h2 id="publish-to-azure-app-service">Publish to Azure App Service</h2>
<p>Go back to the Azure Portal and add a new App Service. Make sure to pick the Web App option, and not the Web App + SQL option.</p>
<p><img class="alignnone wp-image-358 size-large" src="/wp-content/uploads/sites/2/2017/06/05-add-app-service.png" alt="Add a new Azure Portal App Service" width="640" height="380" srcset="/wp-content/uploads/sites/2/2017/06/05-add-app-service.png 1024w, /wp-content/uploads/sites/2/2017/06/05-add-app-service.png 300w, /wp-content/uploads/sites/2/2017/06/05-add-app-service.png 768w, /wp-content/uploads/sites/2/2017/06/05-add-app-service.png 800w, /wp-content/uploads/sites/2/2017/06/05-add-app-service.png 1338w" sizes="(max-width: 640px) 100vw, 640px" /></p>
<p>Specify the App Service options. You may need to create new resource groups and app service plans here. Make sure to create a free App Service Plan to keep costs low. Turn on Application Insights.</p>
<p>Note the App name forms the URL of the API, e.g. humidity-monitor.azurewebsite.net for the example below:</p>
<p><img class="alignnone size-large wp-image-359" src="/wp-content/uploads/sites/2/2017/06/06-app-service-options.png" alt="Specify app service options" width="640" height="421" srcset="/wp-content/uploads/sites/2/2017/06/06-app-service-options.png 1024w, /wp-content/uploads/sites/2/2017/06/06-app-service-options.png 300w, /wp-content/uploads/sites/2/2017/06/06-app-service-options.png 768w" sizes="(max-width: 640px) 100vw, 640px" /></p>
<p>Head back to Visual Studio and use the Publish to Azure option. The UI looks a bit different in Windows but the general flow remains the same.</p>
<p><img class="alignnone size-medium wp-image-356" src="/wp-content/uploads/sites/2/2017/06/03-publish-to-azure-failure.png" alt="Right-click project and go to Publish > Publish to Azure" width="300" height="129" srcset="/wp-content/uploads/sites/2/2017/06/03-publish-to-azure-failure.png 300w, /wp-content/uploads/sites/2/2017/06/03-publish-to-azure-failure.png 768w, /wp-content/uploads/sites/2/2017/06/03-publish-to-azure-failure.png 898w" sizes="(max-width: 300px) 100vw, 300px" /><img class="alignnone size-large wp-image-360" src="/wp-content/uploads/sites/2/2017/06/07-publish-to-azure.png" alt="Publish to Azure App Service" width="640" height="431" srcset="/wp-content/uploads/sites/2/2017/06/07-publish-to-azure.png 1024w, /wp-content/uploads/sites/2/2017/06/07-publish-to-azure.png 300w, /wp-content/uploads/sites/2/2017/06/07-publish-to-azure.png 768w, /wp-content/uploads/sites/2/2017/06/07-publish-to-azure.png 1398w" sizes="(max-width: 640px) 100vw, 640px" /></p>
<p>Visual Studio 2017 has a <a href="https://developercommunity.visualstudio.com/content/problem/29118/visual-studio-2017-does-not-show-azure-subscriptio.html">known bug</a> where it doesn&rsquo;t detect your subscription. Please try the workarounds in that link if you encounter it.</p>
<h1 id="humidity-monitor-app">Humidity Monitor App</h1>
<p>The mobile app is built on Xamarin.Forms cross-platform framework using MVVM pattern. I&rsquo;ve tried to keep everything within the Forms project and avoid platform-specific customisations where possible. I created the project on my Mac, which doesn&rsquo;t create a UWP variant. However there is no reason why it can&rsquo;t run on Windows 10 devices as well.</p>
<p>Anyone can create self-signed Android apps for self-distribution, but iOS apps require a developer account to generate valid certificates.</p>
<h2 id="configure-the-app">Configure the App</h2>
<p>The HumidityMonitorAppViewModel is the main view model driving the mobile app. It has a few important configurations to add in the class fields:</p>
<ul>
<li>_location: The location code (i.e. Partition Key)</li>
<li>TIMEZONE: The <a href="https://gist.github.com/jrolstad/5ca7d78dbfe182d7c1be">IANA time zone code according to NodaTime</a></li>
<li>_dal: Requires the base URL of the Humidity Monitor API deployed onto the App Service, e.g. <a href="http://humidity-monitor.azurewebsites.net">http://humidity-monitor.azurewebsites.net</a></li>
<li>(Optional) _switchDal: The IFTTT Maker Webhook key that you obtain from your IFTTT account</li>
</ul>
<div class="highlight"><pre class="chroma"><code class="language-csharp" data-lang="csharp"><span class="k">public</span> <span class="k">class</span> <span class="nc">HumidityMonitorAppViewModel</span> <span class="p">:</span> <span class="n">ViewModelBase</span>
<span class="p">{</span>
    <span class="kt">string</span> <span class="n">_location</span> <span class="p">=</span> <span class="s">&#34;TODO - Location&#34;</span><span class="p">;</span>
    <span class="k">private</span> <span class="k">const</span> <span class="kt">string</span> <span class="n">TIMEZONE</span> <span class="p">=</span> <span class="s">&#34;TODO - IANA time zone code&#34;</span><span class="p">;</span>
    <span class="n">HumidityViewModel</span> <span class="n">_latestHumidity</span><span class="p">;</span>
    <span class="n">ObservableCollection</span><span class="p">&lt;</span><span class="n">HumidityViewModel</span><span class="p">&gt;</span> <span class="n">_detailedHumidityCollection</span><span class="p">;</span>
    <span class="n">ObservableCollection</span><span class="p">&lt;</span><span class="n">HumiditySummaryViewModel</span><span class="p">&gt;</span> <span class="n">_humiditySummaryCollection</span><span class="p">;</span>
    <span class="n">DateTime</span> <span class="n">_detailedHumidityDate</span><span class="p">;</span>
    <span class="n">DateTime</span> <span class="n">_humiditySummaryStartDate</span><span class="p">;</span>
    <span class="n">DateTime</span> <span class="n">_humiditySummaryEndDate</span><span class="p">;</span>
    <span class="kt">bool</span> <span class="n">_canGetLatestHumidity</span><span class="p">;</span>
    <span class="kt">bool</span> <span class="n">_isLoading</span><span class="p">;</span>
    <span class="kt">bool</span> <span class="n">_viewSwitch</span><span class="p">;</span>
    <span class="n">ViewEnum</span> <span class="n">_currentView</span><span class="p">;</span>
    <span class="k">readonly</span> <span class="n">HumidityMonitorDAL</span> <span class="n">_dal</span> <span class="p">=</span> <span class="k">new</span> <span class="n">HumidityMonitorDAL</span><span class="p">(</span><span class="s">&#34;TODO - Backend API base URI&#34;</span><span class="p">);</span>
    <span class="k">readonly</span> <span class="n">IftttDehumidifierSwitchDAL</span> <span class="n">_switchDal</span> <span class="p">=</span> <span class="k">new</span> <span class="n">IftttDehumidifierSwitchDAL</span><span class="p">(</span><span class="s">&#34;TODO - IFTTT Maker Webhook Key&#34;</span><span class="p">);</span>
    <span class="c1">//... more code here ...
</span><span class="c1"></span><span class="p">}</span>
</code></pre></div><h2 id="create-android-signing-certificate">Create Android Signing Certificate</h2>
<p>Follow <a href="https://developer.xamarin.com/guides/android/deployment,_testing,_and_metrics/publishing_an_application/part_2_-_signing_the_android_application_package/">Xamarin&rsquo;s guide to generate a self-signed Android certificate</a>. This is mandatory for the next step.</p>
<h2 id="cicd-with-azure-mobile-center">CI/CD with Azure Mobile Center</h2>
<p>This is an optional step but one that made my testing life easier because it automatically builds and distributes my Android app on every Git push. The <a href="https://mobile.azure.com">Azure Mobile Center</a> is currently in preview and is free to use. It hooks into your Azure account so make sure to sign in with your existing Azure credentials. There are many guides out there on how to configure CI/CD pipeline with the Mobile Center.</p>
<h1 id="next-steps-for-improvement">Next Steps for Improvement</h1>
<p>Here are some suggested improvements that you can try yourself:</p>
<ul>
<li>The Sense HAT has more sensors. Incorporate readings from different sensors, e.g. temperature and pressure, to derive further insights.</li>
<li>Improve security of the API because you wouldn&rsquo;t want everyone to be able to see your humidity readings.</li>
<li>Incorporate the IANA time zone code into the Table Storage so it doesn&rsquo;t need to be specified on every API call.</li>
<li>Make the location code configurable in the Humidity Logger UI and Xamarin app so that it can easily support different locations without changing hardcoded strings. The Xamarin app can then be extended to view records from different locations from a drop-down.</li>
<li>Create configurable notifications that will alert you if the humidity breaches a threshold. This will require building a background service that polls the API at specific intervals. A fancier solution is to do the monitoring on the backend (Azure Functions, maybe?) and send a push notification to the user.</li>
</ul>
<h1 id="conclusion">Conclusion</h1>
<p>The Humidity Monitor App has many components but I&rsquo;ve done most of the hard work. All you need is to configure some Azure resources and you&rsquo;re done. I&rsquo;ve also left enough gaps in the mobile app for you want to take this further. Enjoy!</p>
]]></content></item><item><title>Taking Shortcuts Make Us Look Stupid</title><link>https://www.coderfrontline.com/taking-shortcuts-make-us-look-stupid/</link><pubDate>Sat, 10 Jun 2017 22:24:11 +1200</pubDate><guid>https://www.coderfrontline.com/taking-shortcuts-make-us-look-stupid/</guid><description>I came across this error message when I was setting up a new Visual Studio Team Services build and found it quite funny. A valid ASP .Net Core project does not need a web.config file when it&amp;rsquo;s not hosted in IIS, and it definitely doesn&amp;rsquo;t need a wwwroot folder if it&amp;rsquo;s an API that does not serve static files.Error when running dotnet publish command
It made me reflect on my past choices when designing software solutions.</description><content type="html"><![CDATA[<p>I came across this error message when I was setting up a new Visual Studio Team Services build and found it quite funny. A valid ASP .Net Core project does not need a web.config file when it&rsquo;s not hosted in IIS, and it definitely doesn&rsquo;t need a wwwroot folder if it&rsquo;s an API that does not serve static files.<figure id="attachment_341" style="width: 640px" class="wp-caption aligncenter"></p>
<p><a href="https://www.coderfrontline.com/wp-content/uploads/sites/2/2017/06/dotnet-core-build.png"><img class="wp-image-341 size-large" src="https://www.coderfrontline.com/wp-content/uploads/sites/2/2017/06/dotnet-core-build.png" alt="" width="640" height="143" srcset="/wp-content/uploads/sites/2/2017/06/dotnet-core-build.png 1024w, /wp-content/uploads/sites/2/2017/06/dotnet-core-build.png 300w, /wp-content/uploads/sites/2/2017/06/dotnet-core-build.png 768w" sizes="(max-width: 640px) 100vw, 640px" /></a><figcaption class="wp-caption-text">Error when running dotnet publish command</figcaption></figure></p>
<p>It made me reflect on my past choices when designing software solutions. We sometimes take shortcuts, whether due to time constraints or insufficient business analysis. It usually makes us look stupid, sooner or later. No profound lessons in this post. It&rsquo;s just something to remind me that I should look where I can put in that extra 5%.</p>
<p>Featured photo credit: <a href="https://www.flickr.com/photos/eilonwy77/6847865750/">eilonwy77</a> via <a href="https://visualhunt.com/re/17524f">Visual Hunt</a> /  <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC BY-SA</a></p>
]]></content></item><item><title>Impact the World with impactNPO</title><link>https://www.coderfrontline.com/impact-the-world-with-impactnpo/</link><pubDate>Sun, 14 May 2017 22:10:19 +1200</pubDate><guid>https://www.coderfrontline.com/impact-the-world-with-impactnpo/</guid><description>&lt;p>I like doing charitable work. I feel that most of us live privileged lives, whether through circumstance or hard work. It’s always made sense to me that we have a moral imperative to help those who are less fortunate. I finally found a non-profit where I can apply my IT experience to help charitable organisations do just that and positively impact the world.&lt;/p></description><content type="html"><![CDATA[<p>I like doing charitable work. I feel that most of us live privileged lives, whether through circumstance or hard work. It’s always made sense to me that we have a moral imperative to help those who are less fortunate. I finally found a non-profit where I can apply my IT experience to help charitable organisations do just that and positively impact the world.</p>
<p>I was involved in different charities over the years and most of them need boots on the ground – the actual people to carry out the good work. While that is useful, I believe I can do 10x the good if I contribute to their IT systems. Helping the helper, if you will. So, I was extremely chuffed to come across <a href="http://impactnpo.org/">impactNPO</a> who organizes weekend hackathons that bring together IT professionals and deserving non-profits. I finally joined my first impactNPO hackathon last month and want to summarize my experience.</p>
<p>Here’s how the hackathon works – it starts at 6pm on a Friday for charity introductions and networking. Everyone there is a volunteer and most of them meet as strangers. We sign in and get a name tag. We write some acronyms to indicate our area our expertise, such as developer, graphic design, content writer, or project manager. After a quick introduction, we do a ‘speed dating’ session where we spend 10 minutes with each charity understanding their IT needs. We then decide which charity we would like to work with over the weekend, and self-organise into teams. The evening finishes sharp at 8pm because we have early starts for the next two days.</p>
<p>Saturday and Sunday are the main hackathon days, where we work in our teams to build something that will give value to the non-profit we represent. It is essentially a two-day sprint, with a quick review at the start and end of each day, plus a final presentation at 4pm Sunday. I admit that it was both exhausting and exhilarating to try and achieve tangible outcomes for the organisation in just two days with a bunch of strangers I’ve never worked with. I’ve never experienced all <a href="https://www.mindtools.com/pages/article/newLDR_86.htm">five stages of team formation</a> in less than 20 hours – forming, storming, norming, performing, and adjourning!</p>
<p>We had a great product owner in the form of Ina Michaels from <a href="https://www.onecoop.co.nz/">The oneCOOPERATIVE</a>. He and the rest of the family of <a href="https://www.facebook.com/cidanzakl/">CIDANZ</a> are working hard to create positive outcomes for the Cook Islands community in New Zealand. Through our discovery session on Friday and Saturday morning we pinpointed e-commerce as a main gap in their ability to showcase their craft-makers to the public. We produced a basic but functional <a href="http://shop.onecoop.co.nz/">oneCOOP online shopping site</a> on VendHQ by Sunday evening.</p>
<p>As for myself, I went in hoping to contribute my development skills but naturally steered myself into a project lead position. I started off with a decomposition and discovery session and the team members had confidence to keep me in that role for the weekend. I had a super time guiding the team towards self-management with Kanban swimlanes, making sure everyone had a chance to contribute, adjudicating conflicts, and clearing out roadblocks. I really felt I made an impact to the world and will not hesitate to participate next time.</p>
<p>impactNPO started right here in Auckland but they are gearing for expansion to other cities in New Zealand, and eventually the world. Check out <a href="https://www.facebook.com/impactnpo/">impactNPO’s Facebook</a> page for all the photos from the weekend and news of upcoming hackathons.<figure id="attachment_333" style="width: 640px" class="wp-caption aligncenter"></p>
<p><img class="size-large wp-image-333" src="https://www.coderfrontline.com/wp-content/uploads/sites/2/2017/05/onecoop.jpg" alt="" width="640" height="554" srcset="/wp-content/uploads/sites/2/2017/05/onecoop.jpg 1024w, /wp-content/uploads/sites/2/2017/05/onecoop.jpg 300w, /wp-content/uploads/sites/2/2017/05/onecoop.jpg 768w" sizes="(max-width: 640px) 100vw, 640px" /><figcaption class="wp-caption-text">The onecoop team showing off their work at the impactNPO showcase (photo from <a href="https://www.facebook.com/impactnpo/">impactNPO</a>)</figcaption></figure></p>
<p>Top photo credit: Palm trees on Aitutaki by <a href="https://www.flickr.com/photos/chris1h1/430754282/">chris1h1</a> via <a href="https://visualhunt.com/re/5aebd6">Visual Hunt</a> /  <a href="http://creativecommons.org/licenses/by-nc-sa/2.0/">CC BY-NC-SA</a></p>]]></content></item><item><title>Should I Start Using Dotnet Core?</title><link>https://www.coderfrontline.com/should-i-start-using-dotnet-core/</link><pubDate>Sat, 08 Apr 2017 12:35:36 +1200</pubDate><guid>https://www.coderfrontline.com/should-i-start-using-dotnet-core/</guid><description>&lt;p>I wrote about my &lt;a href="https://www.coderfrontline.com/cutting-edge-technology-cuts/">negative experiences with ASP .Net Core&lt;/a> almost a year ago. I&amp;rsquo;m ready to reverse my opinion and think that ASP .Net Core is ready for primetime. I recently completed a multi-month project at work that primarily used ASP .Net Core and I had a positive experience. I share some thoughts and tips if you want to start using Dotnet Core (as it is sometimes called) beyond Hello World. These suggestions come from the perspective of a corporate software developer who is familiar with the full .Net framework and Visual Studio.&lt;/p></description><content type="html"><![CDATA[<p>I wrote about my <a href="/cutting-edge-technology-cuts/">negative experiences with ASP .Net Core</a> almost a year ago. I&rsquo;m ready to reverse my opinion and think that ASP .Net Core is ready for primetime. I recently completed a multi-month project at work that primarily used ASP .Net Core and I had a positive experience. I share some thoughts and tips if you want to start using Dotnet Core (as it is sometimes called) beyond Hello World. These suggestions come from the perspective of a corporate software developer who is familiar with the full .Net framework and Visual Studio.</p>
<p>Let&rsquo;s get the obvious out of the way: <strong>Don&rsquo;t upgrade existing solutions</strong> to ASP .Net Core if there is no need to. It is not worth the trouble as my initial post details. The full .Net framework is very stable, well supported by third-party extensions, and will be in use for years to come. .Net Core as a whole sits on a different trajectory - it was rebuilt from the ground up to support .Net on non-Windows platforms. Even if you wanted to take advantage of that fact to make your existing product cross-platform, I would still suggest taking a long look at your design and architecture. It may be better to start fresh than to upgrade the solution.</p>
<p>Next, start using <strong>Visual Studio 2017</strong>, now available for both <a href="https://www.visualstudio.com/vs/visual-studio-mac/">Mac</a> and <a href="https://www.visualstudio.com/free-developer-offers/">Windows</a>. You can develop apps on VS Code, but Visual Studio&rsquo;s extension ecosystem has some great plugins. Most things from <a href="https://github.com/madskristensen">Mads Kristensen</a> are good, namely <a href="https://marketplace.visualstudio.com/items?itemName=MadsKristensen.bundlerminifier">Bundler &amp; Minifier</a> and <a href="https://marketplace.visualstudio.com/items?itemName=MadsKristensen.WebCompiler">Web Compiler</a>. Bundler &amp; Minifier creates a bundleconfig.json that lets you bundle and minify CSS and JavaScript files, while Web Compiler does the same for Less and SASS files. Both work similar to Gulp/Grunt without having to install node or npm on your machine.</p>
<p>The other reason I encourage using VS2017 is it finally uses <strong>.csproj instead of .xproj/project.json</strong> for project files. I found configuring project.json to be finicky at times. Plus the .csproj format has full MSBuild support, which is great news for CI/CD environments. Microsoft has good documentation covering the differences between <a href="https://docs.microsoft.com/en-us/dotnet/articles/core/tools/project-json-to-csproj">.csproj and project.json</a>.</p>
<p>Do you use a <strong>logging framework</strong> such as Log4Net? dotnet core has a generic logging layer that can interface with any other logging framework. However, check that your logging framework can support the appenders that you want to use. As of today, Log4Net doesn&rsquo;t <a href="https://logging.apache.org/log4net/release/framework-support.html">support AdoNetAppender and SmtpAppender</a>, which are pretty common outputs for logs. Thankfully, Log4Net is open-source so we could use most of their appender implementation but pointing to dotnet core-compatible libraries (native SqlClient for AdoNetAppender and <a href="https://github.com/jstedfast/MailKit">MailKit</a> for SmtpAppender).</p>
<p>Lastly, think about your solution&rsquo;s <strong>external dependencies</strong>. Most projects need inputs from the outside world at some stage. You&rsquo;ll have to think if this will be affected by moving to .Net Core. For example, while I could use Windows Authentication for my intranet web application, I was not able to look up Active Directory details for the given user, such as their full name. Active Directory is a Windows feature and has not been ported over to dot net core. The same concern arises for any old databases you need to connect to - we still have SQL Server 2000 and old IBM DB/2 databases in production. All of these roadblocks can be solved by building your own shim or using a NuGet package, but they represent unexpected roadblocks that will slow .Net Core adoption.</p>
<p>I hope the above points have helped you prepare for most eventualities. Tell me your experience when you start using DotNet Core!</p>]]></content></item><item><title>Developer Pride</title><link>https://www.coderfrontline.com/developer-pride/</link><pubDate>Sat, 25 Mar 2017 04:48:12 +1200</pubDate><guid>https://www.coderfrontline.com/developer-pride/</guid><description>&lt;p>My development manager recently asked us for input on building an engineering culture at work. I semi-coined a new term: developer pride. The term has gotten &lt;a class="external-link" href="http://codesqueeze.com/do-managers-prey-on-developer-pride/" rel="nofollow">bad rep&lt;/a> in the past, but I want to reclaim it in the same way the LGBT rights movement transformed the word &lt;em>pride&lt;/em> from the negative connotations of being a &lt;a href="https://en.wikipedia.org/wiki/Seven_deadly_sins#Pride">deadly sin&lt;/a> to the &lt;a href="http://www.theallusionist.org/allusionist/pride">antidote to shame&lt;/a>. So what does developer pride mean to me?&lt;/p></description><content type="html"><![CDATA[<p>My development manager recently asked us for input on building an engineering culture at work. I semi-coined a new term: developer pride. The term has gotten <a class="external-link" href="http://codesqueeze.com/do-managers-prey-on-developer-pride/" rel="nofollow">bad rep</a> in the past, but I want to reclaim it in the same way the LGBT rights movement transformed the word <em>pride</em> from the negative connotations of being a <a href="https://en.wikipedia.org/wiki/Seven_deadly_sins#Pride">deadly sin</a> to the <a href="http://www.theallusionist.org/allusionist/pride">antidote to shame</a>. So what does developer pride mean to me?</p>
<p>Developer pride manifests itself through three beliefs:</p>
<ul>
<li>I recognize the importance of my work because software underpins the backbone of the organisation.</li>
<li>I take pride in delivering the best solution I can to realize business value.</li>
<li>I appreciate my fellow developers as the best technical resource I have. I succeed when they succeed.</li>
</ul>
<p>How does developer pride translate into practices?</p>
<ul>
<li>I take time to ensure my work is correct. “<em>It compiles on my machine</em>” is no longer good enough.
<ul>
<li>Are there automated tests? (xUnit, Postman, Selenium)</li>
<li>Did I manual test it if there are no integration tests?</li>
<li>Written in a way that other devs can understand? (following code standards)</li>
<li>Is it documented? (descriptive commit message, Confluence entries, useful comments)</li>
</ul>
</li>
<li>I put <em>developer ego</em> aside in order to deliver business value.
<ul>
<li>I recognize that “good enough”<sup>1</sup> code is sufficient as long as it doesn&rsquo;t create technical debt. There&rsquo;s no need for an over-architected solution or spending 4 hours reducing a 10-line method down to a one-line statement just so I can demonstrate my <a class="external-link" href="http://codefu.mk/" rel="nofollow">code-fu</a>.</li>
<li>Humans make mistakes. Let&rsquo;s get on with fixing the problem instead of trying to find someone to blame.</li>
</ul>
</li>
<li>I am happy to have my code reviewed by my peers, and I will happily do the same for them.
<ul>
<li>Code reviews let me see my code from a different viewpoint. I welcome challenges as it may expose a blind spot.</li>
<li>I do code reviews because I want to learn how other developers approach problems. It is not a fault-finding exercise!</li>
<li>We review code, not the coder.</li>
</ul>
</li>
<li>I devote time for continuous personal growth.
<ul>
<li>I explore new toolsets and technologies because even the best knives need sharpening.</li>
<li>I take the chance to observe how the business runs because it provides a level of visibility that Kanban/Scrum backlog stories do not. This helps me deliver better business value.</li>
</ul>
</li>
<li>I communicate with my colleagues with respect<sup>2</sup> because I recognize them as the best in the industry. This is especially pertinent during disagreements, which is common when many smart minds work on the same problem.</li>
</ul>
<p>1: “good enough” will be defined by agreed design patterns and coding standards. We can fit an entire program into a single procedural Main() method which works but is probably not good enough by our standards.</p>
<p>2: A fantastic model for verbal communication can be found in <a class="external-link" href="https://www.amazon.com/Crucial-Conversations-Talking-Stakes-Second/dp/0071771328/ref=mt_paperback?_encoding=UTF8&me=" rel="nofollow">Crucial Conversations</a>, which I will blog about soon.</p>
<p>I don&rsquo;t know if the term developer pride will be adopted by the team, but that is how I intend to carry myself. Do you have pride?</p>]]></content></item><item><title>Mob Programming: Is It Just a Fad?</title><link>https://www.coderfrontline.com/mob-programming-is-it-just-a-fad/</link><pubDate>Sun, 05 Mar 2017 15:00:14 +1200</pubDate><guid>https://www.coderfrontline.com/mob-programming-is-it-just-a-fad/</guid><description>I first heard the term Mob Programming on a Hanselminutes podcast. I then got a closer look at it through Mark Pearl’s talk on the subject at an Agile Auckland Meetup. He even wrote a Leanpub book about Mob Programming. Mark is an Engineering Lead at MYOB and it’s great to hear him share his first-hand experience with running a mob team locally. I like the potential of Mob Programming but I&amp;rsquo;ve been pondering for the past week: Is it just a fad?</description><content type="html"><![CDATA[<p>I first heard the term Mob Programming on a <a href="http://hanselminutes.com/553/mob-programming-with-woody-zuill">Hanselminutes podcast</a>. I then got a closer look at it through <a href="http://blog.markpearl.co.za/">Mark Pearl</a>’s talk on the subject at an <a href="https://www.meetup.com/Agile-Auckland/events/237711745/">Agile Auckland Meetup</a>. He even wrote a <a href="https://leanpub.com/GettingStartedWithMobProgramming">Leanpub book</a> about Mob Programming. Mark is an Engineering Lead at MYOB and it’s great to hear him share his first-hand experience with running a mob team locally. I like the potential of Mob Programming but I&rsquo;ve been pondering for the past week: Is it just a fad?</p>
<p>While I have not tried Mob Programming, I experienced Pair Programming at a Code Retreat and finally understood the appeal of collaborative coding. I have subsequently failed to get more people at my workplace to adopt it. Everyone agrees with the concept as if it&rsquo;s a utopian ideal that ‘good' teams subscribe to, but is impractical in the ‘real world'. I believe those same reasons will prevent mass adoption of Mob Programming.</p>
<p>Realistically, only a small subset of development teams will be able to pull this off. Hence, I&rsquo;ve started thinking about the attributes that mob members must possess. I don&rsquo;t see this as a checklist. Rather, each attribute is on a scale and the likelihood of success increases when more members sit on the mature end of the range.</p>
<p>Consider this list the ramblings of an uninformed man. They have not been empirically validated and I invite you to challenge me in the comments section. I may update this list as I grow and read more:</p>
<ul>
<li>Relatively young team: I am referring to the age of the team as opposed to individual team members (although that will have a factor as well). Younger teams are more open to new practices, while older teams are more set in their ways. I am not immune – I have caught myself getting defensive when a colleague suggests a different way of doing something. Changing practices that have worked well is a tough ask.</li>
<li>Crave feedback: Some people are ‘open to feedback' - they will receive your comments but then vigorously defend their own ideas. I am describing a more extreme version where you actively invite and enjoy constructive feedback. This is such an important quality to possess as mob programming is feedback-centric. It&rsquo;s not going to succeed if members are stressed out and defensive going into a mob. I wished I could say I craved feedback, but I&rsquo;m working on minimising my ego when I get code reviewed.</li>
<li>Empathic communicator: Closely related to craving feedback is the ability to give them. Good communication requires many sub-skills and the one I&rsquo;ve chosen to highlight is empathy. When you have 3 or 4 chefs in the kitchen and only one cook, it&rsquo;s important that each chef is given the opportunity to infuse the dish with their magic ingredient. I have worked with people who sit somewhere on the <a href="https://en.wikipedia.org/wiki/Autism_spectrum">autism spectrum</a> and they sometimes miss social cues. They railroad the discussion and it escalates into an us vs. them battle, as opposed to compromising. They may need to be actively managed so that they don&rsquo;t dominate the conversation, or conversely, feel that they are not being heard.</li>
</ul>
<p>Those are just some of the soft skills I think a good mob programming team requires. I have not mentioned a single technical skill or process as they are just the icing on a cake made up of those foundational abilities. However, a couple of questions came up during Mark&rsquo;s talk that he concedes are common questions. They were:</p>
<ol>
<li>How do you convince management that 4 programmers working on 1 problem at a time is better/cheaper/faster than 4 people working on 4 different problems?</li>
<li>How is individual performance appraised when work is completed collectively?</li>
</ol>
<p>Unfortunately, I don&rsquo;t think his answers are convincing enough to allay management&rsquo;s fears about adopting mob programming. A good advice I learnt from <a href="http://amzn.to/2lLEPkN">Tim Ferriss' The 4-Hour Workweek</a> is that it is easier to ask for forgiveness than ask for permission. This may be one of those times where a development team just needs to sneak in mob programming and demonstrate the results at the end.</p>
<p>I will attempt to answer my own question: I think Mob Programming is a long-lived fad. It&rsquo;s going to be around for a long time just like Pair Programming has: Well-acknowledged but poorly-adopted. Which is quite a shame.</p>
<p>Photo credit: <a href="https://www.flickr.com/photos/archeon/10388600663/">hans s</a> via <a href="https://visualhunt.com/re/97081a">VisualHunt.com</a> /  <a href="http://creativecommons.org/licenses/by-nd/2.0/">CC BY-ND</a></p>
]]></content></item><item><title>Are We Becoming Blue-Collared Workers?</title><link>https://www.coderfrontline.com/are-we-becoming-blue-collared-workers/</link><pubDate>Sun, 12 Feb 2017 13:03:37 +1200</pubDate><guid>https://www.coderfrontline.com/are-we-becoming-blue-collared-workers/</guid><description>&lt;p>Are coders the next blue-collared job? This is the hypothesis Clive Thompson puts forward in his thought-provoking Wired piece &lt;a href="https://www.wired.com/2017/02/programming-is-the-new-blue-collar-job">The Next Big Blue-Collar Job Is Coding&lt;/a>. A knee-jerk reaction from IT professionals (read their &lt;a href="https://www.wired.com/2017/02/programming-is-the-new-blue-collar-job/#article-comments">comments&lt;/a>) is to deny any possibility of that happening due to the years of training needed to get to their level. I certainly shared that first impression, partly because the term ‘blue-collared’ has negative connotations of being decidedly middle-class. I started thinking about this a bit more deeply when Clive wrote:&lt;/p></description><content type="html"><![CDATA[<p>Are coders the next blue-collared job? This is the hypothesis Clive Thompson puts forward in his thought-provoking Wired piece <a href="https://www.wired.com/2017/02/programming-is-the-new-blue-collar-job">The Next Big Blue-Collar Job Is Coding</a>. A knee-jerk reaction from IT professionals (read their <a href="https://www.wired.com/2017/02/programming-is-the-new-blue-collar-job/#article-comments">comments</a>) is to deny any possibility of that happening due to the years of training needed to get to their level. I certainly shared that first impression, partly because the term ‘blue-collared’ has negative connotations of being decidedly middle-class. I started thinking about this a bit more deeply when Clive wrote:</p>
<blockquote>
<p>‘In Kentucky, mining veteran Rusty Justice decided that code could replace coal. He cofounded <a href="http://bitsourceky.com/">Bit Source</a>, a code shop that builds its workforce by retraining coal miners as programmers. Enthusiasm is sky high: Justice got 950 applications for his first 11 positions. Miners, it turns out, are accustomed to deep focus, team play, and working with complex engineering tech. “Coal miners are really technology workers who get dirty,” Justice says.’</p>
</blockquote>
<p>I associate coal miners as blue-collared workers, so is the gap between coal mining and code writing that wide? I used to think so, but barriers to entry are always getting lower. I know a few friends who have created iOS apps and SEO-friendly WordPress sites without four-year Computer Science degrees. Sure, they do not write the most ‘technically beautiful’ code or employ some best practices, but their software works! The ability to automate best practices by default will come sooner rather than later, e.g. Visual Studio’s F5 debug puts your app in a Docker container by default.</p>
<p>I agree with Clive’s long-term prediction that programmers are the next blue-collared job industry. We just need to look at trends such as <a href="https://blog.engineyard.com/2014/pets-vs-cattle">treating servers as cattle</a> instead of pets, and how the sharing/on-demand economy (_Uber_nisation, as one friend calls it) is disrupting many entrenched industries.</p>
<p>The question we must each answer is: Am I going to keep my head in the sand or am I going to elevate my skills beyond simple coding?</p>
<p>Photo credit: <a href="https://www.flickr.com/photos/katefisher/12669003945/">kate.fisher</a> via <a href="https://visualhunt.com">Visual hunt</a> /  <a href="http://creativecommons.org/licenses/by/2.0/">CC BY</a></p>]]></content></item><item><title>Faking Extroversion: An Introvert's Guide</title><link>https://www.coderfrontline.com/faking-extroversion-an-introverts-guide/</link><pubDate>Sun, 29 Jan 2017 14:40:01 +1200</pubDate><guid>https://www.coderfrontline.com/faking-extroversion-an-introverts-guide/</guid><description>&lt;p>I was having a drink with a friend I haven&amp;rsquo;t seen in years when he confided that he&amp;rsquo;s having trouble making friends in a new city. He had moved there to be close to his partner, which meant that his social circle was limited to his partner&amp;rsquo;s social circle. This posed a problem for my friend whenever he had relationship issues, as he did not have nearby friends of his own. His main roadblock, he insisted, was his introversion. I can certainly relate to that as I am an introvert myself. However, I recognize the value of having a strong social support network, which inherently requires some extroversion to build. I faced the same issue when I moved to New Zealand alone and had to make a concerted effort to fake extroversion. I decided to share some of my techniques with this friend and it inspired me to write this post.&lt;/p></description><content type="html"><![CDATA[<p>I was having a drink with a friend I haven&rsquo;t seen in years when he confided that he&rsquo;s having trouble making friends in a new city. He had moved there to be close to his partner, which meant that his social circle was limited to his partner&rsquo;s social circle. This posed a problem for my friend whenever he had relationship issues, as he did not have nearby friends of his own. His main roadblock, he insisted, was his introversion. I can certainly relate to that as I am an introvert myself. However, I recognize the value of having a strong social support network, which inherently requires some extroversion to build. I faced the same issue when I moved to New Zealand alone and had to make a concerted effort to fake extroversion. I decided to share some of my techniques with this friend and it inspired me to write this post.</p>
<p>A couple of clarifications up-front. Introversion and extroversion exist on two extremes of a scale, as a <a href="https://www.fastcompany.com/3016031/leadership-now/are-you-an-introvert-or-an-extrovert-and-what-it-means-for-your-career">Fast Company article on this topic</a> cleverly summarizes. The same article also gives a comprehensive definition of introversion beyond the stereotypical “introverts are shy”. It is dangerous to pigeon-hole ourselves into one of two boxes, because they simply do not exist. Hence we all have some degree of introversion or extroversion we can exploit.</p>
<p>Secondly, this means there&rsquo;s no “faking it”, as such. We should always strive to be the most authentic versions of ourselves, and pretending to be someone else just gets exhausting. Authenticity is also required because friendship is a two-way street, and it&rsquo;s easier to be a friend to others if they can trust the quality of friendship you are providing. In short, these techniques may help introverts amplify whatever minor extroversion qualities they already have.</p>
<p>Making friendships is like making fire. We need kindling to create that initial flame, then add logs to create a strong fire, and renew the logs occasionally to keep the fire going.</p>
<h2 id="meeting-new-people">Meeting New People</h2>
<p>This initial step is always the hardest for introverts. Because true friendships are built through frequent interaction and shared experiences, I recommend two pathways to meet people:</p>
<ol>
<li>Work or school place</li>
<li>Hobby or interest social groups</li>
</ol>
<p>Making friends in school is a no-brainer, but many introverts seem to categorize the office as a different social playground when in fact the usual cliques and hierarchy are present. Although our colleagues are of varied ages and backgrounds, we still share interactions and experiences, two important pieces of kindling. Instead of merely keeping a professional distance, I will look for suitable conversation openings. The ‘fire starters' I tend to use as an opening include:</p>
<ul>
<li>Water cooler chat around a topic I know something about, e.g. TV shows, travel destinations I&rsquo;m passionate for, or the weather (yes, really).</li>
<li>Genuine compliments about someone&rsquo;s new look, haircut, or clothes.</li>
</ul>
<p>Another great pathway is to join social groups as there is the added benefit of already having a mutual interest. In this regards I have to heavily recommend <a href="http://www.meetup.com">Meetup.com</a> as it revolves around real-life meetups as opposed to interacting behind computer screens. I have joined many Meetups in Auckland mainly for the learning opportunities. I have since realized they are also great for meeting new people outside my normal circles. I don&rsquo;t need to look for conversation fire starters as they are there by design, regardless if it&rsquo;s a C# meetup, dog walking meetup, or pasta making meetup.</p>
<h2 id="conversations">Conversations</h2>
<p>Once the kindling has been lit, we need to start building a fire by placing larger and larger logs. This will happen naturally via continuous interactions, but a key component of these interactions is having conversations. I find this part to be the most mentally draining as an introvert, so I have come up with an arsenal of tools to get me by.</p>
<ul>
<li>Mentally prepare a list of questions before the interaction: This is highly effective for very small groups of 2 to 4 people and especially if it&rsquo;s someone I have met before. I treat them as convenient questions to restart a conversation if we hit a lull, rather than a list of interview questions I must go through.</li>
<li>Conversation lulls are OK too:  The best friendships are where silence isn&rsquo;t awkward. Daytime talk shows are the porn equivalent of creating unrealistic expectations of how conversations flow. It&rsquo;s completely normal to hit the end of a conversation thread with no where to go but start a new one. On the other hand, hitting too many conversation lulls can be a sign that I have nothing in common with this person.</li>
<li>In a similar vein, I always keep the perspective that good conversations need good speakers and good listeners. I am happy to take a backseat and let other parties speak, instead of worrying about what to say next. I take that opportunity to analyse their words and build a rich profile of the individual in my head. I find that aids the next conversation we have especially if I can recall a particular anecdote.</li>
<li>Recognise the audience: I tailor my conversations to the relative introversion or extroversion of the group. I prefer to have more personal sessions with my fellow introverts as that is the most comfortable setting for the both of us. On the flipside, I tend to bring in another extrovert when talking to one, as they can feed off each other&rsquo;s energy and I don&rsquo;t have to work as hard to keep the conversation flowing.</li>
</ul>
<h2 id="maintaining-friendships">Maintaining Friendships</h2>
<p>This is usually the easiest step. Once a fire is going, one just needs to place fresh logs once in a while to keep it burning. Sure, there may be rain that threatens to wash out the fire, but that&rsquo;s a different topic. Some friendships are more resilient than others - another friend of mine calls it a ‘cactus friendship' as it doesn&rsquo;t need much watering to survive. I constantly try to build and sustain such friendships by making sure I make time for them, even in time-poor situations like my current holiday in my birth country of Malaysia.</p>
<h2 id="faking-extroversion---summary">Faking Extroversion - Summary</h2>
<ol>
<li>It is necessary to use our extroversion skills to nurture friendships.</li>
<li>The best places to make new friends is at the place we spend most of our waking hours and at social meetups.</li>
<li>There are some easy conversation starters and techniques to keep conversations flowing. But, don&rsquo;t be afraid of lulls either.</li>
<li>Friendships need to be maintained. Spending that time together is nourishing, even if it may feel tiring in the short term.</li>
<li>Be the most authentic version of yourself and you will attract the right kind of friends. That makes the whole exercise easier.</li>
</ol>
<p>Photo credit: <a href="https://www.flickr.com/photos/stuckincustoms/27431194423/">Stuck in Customs</a> via <a href="https://visualhunt.com/">Visualhunt</a> /  <a href="http://creativecommons.org/licenses/by-nc-sa/2.0/">CC BY-NC-SA</a></p>]]></content></item><item><title>Retrospective 2016</title><link>https://www.coderfrontline.com/retrospective-2016/</link><pubDate>Sun, 18 Dec 2016 19:25:00 +1200</pubDate><guid>https://www.coderfrontline.com/retrospective-2016/</guid><description>&lt;p>This post is a retrospective for my entire 2016 year. While the practice of retrospectives is commonplace in Agile projects, the act itself can be found in many areas in our lives. Counting our blessings, gratitude journals, and even some forms of meditation are based on past reflections so that we can prepare for the future.&lt;/p></description><content type="html"><![CDATA[<p>This post is a retrospective for my entire 2016 year. While the practice of retrospectives is commonplace in Agile projects, the act itself can be found in many areas in our lives. Counting our blessings, gratitude journals, and even some forms of meditation are based on past reflections so that we can prepare for the future.</p>
<p>Some of my highlights this year include:</p>
<h2 id="starting-this-coder-on-the-frontline-blog">Starting this Coder on the Frontline blog</h2>
<p>I used to maintain a personal blog in my late teens that fizzled out when I started working. I find writing to be quite therapeutic and so decided to start Coder on the Frontline this year. I am normally introverted and this blog has helped me establish my identity as a software engineer and information worker.</p>
<h2 id="completing-my-graduate-diploma-in-strategic-management">Completing my Graduate Diploma in Strategic Management</h2>
<p>I started a part-time course via The Open Polytechnic of New Zealand in late 2014, and completed my sixth and final paper in October. It’s been a rollercoaster of emotions getting to this point because I had to make concrete sacrifices (free time with loved ones) for fuzzy benefits (career advancement). Those benefits have not come around, but I learned useful skills that I’m putting to good use. Just like my studies, I will build a solid wall brick-by-brick and get there in the end.</p>
<h2 id="starting-a-new-job">Starting a new job</h2>
<p>I started a new job in November which I quite enjoy because I get to learn a new industry and be exposed to some modern tech stacks. Why did I leave my last job? It was a difficult decision to quit as I enjoyed everything I worked on. While I dislike giving credence to stereotypes about Millennials, it is true that I will change jobs if I’m not getting the same value as I provide to the employer. It should be a two-way street in terms of helping each other grow. I believe the middle-class in many developed countries are shrinking, and so I need to be proactive to drive my own growth because there are many more talented people out there who are just as hungry.</p>
<h2 id="wrapping-up-for-this-year">Wrapping up for this year</h2>
<p>I wish you, dear reader, a wonderful break over the New Year. May you be well and happy. Coder of the Frontline will be taking a well-deserved break until 2017.</p>
<p>Photo credit: <a href="https://www.flickr.com/photos/rolfnoe/8429418701/">flickrolf</a> via <a href="https://visualhunt.com">VisualHunt.com</a> / <a href="http://creativecommons.org/licenses/by-nc-sa/2.0/">CC BY-NC-SA</a></p>]]></content></item><item><title>Good Interview Questions #26</title><link>https://www.coderfrontline.com/good-interview-questions-#26/</link><pubDate>Sun, 11 Dec 2016 20:45:24 +1200</pubDate><guid>https://www.coderfrontline.com/good-interview-questions-#26/</guid><description>&lt;p>I’ve encountered all sorts of interview questions, mostly on the receiving end but some as part of the interviewing team myself. I will elaborate on some good and bad interview questions, at least in my humble opinion. The numbers are random fun – I don’t have 25 other examples on this blog (yet).&lt;/p></description><content type="html"><![CDATA[<p>I’ve encountered all sorts of interview questions, mostly on the receiving end but some as part of the interviewing team myself. I will elaborate on some good and bad interview questions, at least in my humble opinion. The numbers are random fun – I don’t have 25 other examples on this blog (yet).</p>
<p>I learned this one from my previous manager and made a few modifications below. He would ask the candidate to describe his or her favourite project that they have worked on. He will then request for a high-level domain model or class diagram. Follow-up questions are asked depending on the project and the candidate’s level of involvement.</p>
<p>Here are the things that we can learn about the candidate through this single line of questioning:</p>
<ul>
<li>Their interest in software development: Some might call it <a href="/theory-success-fail-and-still-win-big/">‘passion’ but I wouldn’t go that far</a>. However, one would still need to show a bit of interest especially at the interview stage. It is hard to show excitement when you’re describing a hypothetical architecture. It’s so much easier to do that when talking about a pet project.</li>
<li>Tests their ability to explain architecture visually: I find this skill to get more crucial as one progresses in seniority. It’s important to be able to convey your thoughts in a team environment especially if others are doing the implementation.</li>
<li>Reveals their actual level of involvement in the project: A candidate may be able to wax lyrical about the project, but follow-up questions should aim to uncover their contribution. There are two main forks this conversation can take:
<ul>
<li>“I was responsible for the whole project”: Questions can revolve around how they ensured the quality and who else worked on it. The aim is to know if the candidate is an experienced solo-flyer, a person who prefers to work alone, or worst of all, someone who wings it because they have been working unchecked.</li>
<li>“I was responsible for component X”: Questions can revolve around who decided on this architecture and how it integrated with the other modules. This answer can sometimes show that despite their elaborate explanations, they were only responsible for a small portion of the system.</li>
</ul>
</li>
</ul>
<p>Interviewing is a tricky art as we are trying to ascertain if a candidate will fit an organisation’s needs in only a few sessions between 30 to 60 minutes. The right interview questions can help illuminate multiple aspects of the candidate without directly asking about it. Let me know of any good interview questions you have come across in the comments below!</p>]]></content></item><item><title>Book Excerpt: Impossible to Ignore</title><link>https://www.coderfrontline.com/book-excerpt-impossible-to-ignore/</link><pubDate>Sun, 04 Dec 2016 21:22:03 +1200</pubDate><guid>https://www.coderfrontline.com/book-excerpt-impossible-to-ignore/</guid><description>Is your presentation impossible to ignore? I’ve sat through many presentations in my lifetime, and I expect to sit through quite a few more before I die. It’s astonishing how many technical presentations are treated as information dumps, with no intention to persuade or get audiences to improve their ways. People get bored, and I frequently see smartphones whipped out in conference rooms. I have been guilty of giving such presentations before.</description><content type="html"><![CDATA[<p>Is your presentation impossible to ignore? I’ve sat through many presentations in my lifetime, and I expect to sit through quite a few more before I die. It’s astonishing how many technical presentations are treated as information dumps, with no intention to persuade or get audiences to improve their ways. People get bored, and I frequently see smartphones whipped out in conference rooms. I have been guilty of giving such presentations before. But I think I found some valuable guidance in the book <a href="http://amzn.to/2gC4iO7">Impossible to Ignore</a> on how to craft presentations that bring changes, and I’m sharing an excerpt below.</p>
<p>Start off by seeing her techniques in practice: <a href="http://www.slideshare.net/reximedia/5-reasons-we-forget-presentations-27617869?qid=daa9c551-40ce-40dd-9ec8-751dad1c8d9c&amp;v=&amp;b=&amp;from_search=1">5 Reasons We Forget Presentations</a>, then come back here to read an excerpt from the book. It’s from an early chapter and lays the groundwork for the techniques to follow.</p>
<h2 id="a-modern-approach-to-memory-the-prospective-model">A Modern Approach to Memory: The Prospective Model</h2>
<p>What are the three most important memory problems you experienced last week? This is a question scientists often ask people when they investigate memory issues more deeply. A series of research studies have found that 60 to 80% of our memory problems are related to forgetting to execute on a future intention. Yesterday you may have intended to give someone a call, send a specific e-mail, or stop by the store to buy milk, and only remembered these today. Some unfulfilled intentions linger for a longer time. How many books have you promised yourself you will reward on your next vacation… for the past five years? We have good intentions but forget to execute on them, or if we remember them, the reward is not compelling enough to get us to act. Our audiences are no different. They listen to us, and they may agree that what we say is helpful. When they leave, they might still remember something from what we had said but don’t do anything about it. We can address that by changing our approach to how we view memory.</p>
<p>Instead of viewing memory as merely recollecting things from the past, let’s look at memory from the lens of the future. This shift is useful for three reasons. First, our audiences’ brains are on fast-forward anyway; as they listen to us now, they are by default anticipating the future. The brain has evolved to be a predictive engine because survival is more likely when one can accurately predict what happens next. We can see evidence of our inclination to anticipate the future in many activities: completing other people’s sentences, salivating before taking the first bite, or laughing just <em>before</em> someone is about to tickle us.</p>
<p>Second, we constantly look to the future to <em>extract value</em> for our present actions. Yale psychologists George Newman and T. Andrew Poehlman have studied the human brain’s tendency to look to the future and identify value for the present. <em>(truncated for brevity)</em></p>
<p>The third reason it is useful to approach memory with the future in mind comes from communicators sharing content with audiences now, hoping they remember and <em>act on it</em> later. Imagine that we share content at Point A, and we hope people remember and act on it sometime in the future, at Point B. This “future” can be as close as two minutes from now, two days, two weeks, or longer. So, it is pragmatic to ask, what is happening in people’s lives, and what do they intend to do at Point B? If we know this already at Point A, we can prepare for Point B so we can become part of people’s memories and intentions.</p>
<p><a href="http://amzn.to/2gC43lX"><img class="size-full wp-image-287" src="/wp-content/uploads/sites/2/2016/12/impossible-to-ignore-timeline.png" alt="Impossible to Ignore graphic" width="828" height="204" srcset="/wp-content/uploads/sites/2/2016/12/impossible-to-ignore-timeline.png 828w, /wp-content/uploads/sites/2/2016/12/impossible-to-ignore-timeline.png 300w, /wp-content/uploads/sites/2/2016/12/impossible-to-ignore-timeline.png 768w" sizes="(max-width: 828px) 100vw, 828px" /></a></p>
<p>Getting people to act on what they remember always starts with an intention – an intention they already have or one you wish to place in their minds. Everyone intends to do something next. Our intentions range from trivial to serious and from automatic to goal oriented. We intend to eat, send e-mails, check Facebook, create documents, revamp a software platform, attend meetings.</p>
<h2 id="tldr">TL:DR</h2>
<p>The image above is a pretty good summary of this section. We must always be aware of our audience’s intentions. We are sharing the knowledge now but they only need it in the future. How will you make it easy for them to recall your message at Point B? Do check out <a href="http://amzn.to/2gC4iO7">Impossible to Ignore by Dr. Carmen Simon</a> and make your next public speaking engagement unforgettable!</p>
<div>
  <a href="https://www.amazon.com/Impossible-Ignore-Memorable-Influence-Decisions/dp/1259584135/ref=as_li_ss_il?s=books&ie=UTF8&qid=1480843455&sr=1-1&keywords=impossible+to+ignore&linkCode=li2&tag=zemisscra-20&linkId=ae79a893c1afcbdb830ad6a0950299b0" target="_blank"><img class="aligncenter" src="//ws-na.amazon-adsystem.com/widgets/q?_encoding=UTF8&ASIN=1259584135&Format=_SL160_&ID=AsinImage&MarketPlace=US&ServiceVersion=20070822&WS=1&tag=zemisscra-20" border="0" /></a><img style="border: none !important; margin: 0px !important;" src="https://ir-na.amazon-adsystem.com/e/ir?t=zemisscra-20&l=li2&o=1&a=1259584135" alt="" width="1" height="1" border="0" />
</div>]]></content></item><item><title>Deliberate On-Boarding for Early Success</title><link>https://www.coderfrontline.com/deliberate-on-boarding-for-early-success/</link><pubDate>Sun, 27 Nov 2016 10:03:00 +1200</pubDate><guid>https://www.coderfrontline.com/deliberate-on-boarding-for-early-success/</guid><description>&lt;p>On-boarding programmes, also known as induction programmes, are the set of activities designed to get a new hire up and running in the organisation as soon as possible. I discussed a few types of &lt;a href="https://www.coderfrontline.com/induction-programmes-new-hires/">induction programmes&lt;/a> last week. I will share my own experiences with on-boarding below, including the elements that go into making an effective plan.&lt;/p></description><content type="html"><![CDATA[<p>On-boarding programmes, also known as induction programmes, are the set of activities designed to get a new hire up and running in the organisation as soon as possible. I discussed a few types of <a href="/induction-programmes-new-hires/">induction programmes</a> last week. I will share my own experiences with on-boarding below, including the elements that go into making an effective plan.</p>
<p>My first job was with an American multi-national manufacturer. They used a buddy system. All new hires are paired with a buddy on the team who is responsible for showing the new person the “ropes”. This includes where the break room is, how to use the intranet to apply for annual leave, and other such small matters. I was a buddy once and no formal agenda was provided, so it was a case of sharing first-hand knowledge. It was deliberate on-boarding, but not necessarily well-planned.</p>
<p>My next job had an on-boarding plan but I don’t think it achieved its goal of preparing me well. I can’t remember every detail but I recall spending a week just pairing with a senior developer. This pairing was more of watching him code and him explaining why he did certain things, rather than getting to code myself. It was quite tough for the first couple of months until I got a better grasp of the codebase.</p>
<p>A new software development manager came in halfway through my time at this company. He instituted a more formal on-boarding programme that I think ticked all the right boxes. Those boxes are:</p>
<ul>
<li>Sessions with individual team members to give them some time with the new employee. This also helps spread the on-boarding responsibility around.</li>
<li>Spending several days, up to a week, with other teams. In this case, the new developer would spend time with the testing and customer support teams. This gives them exposure to how other parts of the business operate.</li>
<li>Planned sessions with product owners or business analysts to get a comprehensive tour of the software applications. This helps them understand the product they will be working on from the user’s perspective.</li>
<li>Regular one-on-ones with the manager to ensure the on-boarding plan is working for them.</li>
<li>Time and space to do their own reading of company resources.</li>
</ul>
<p>A plan like the one below is drawn up for each new starter:</p>
<table>
  <tr>
    <td width="90">
      <strong>When</strong>
    </td>
<pre><code>&lt;td width=&quot;267&quot;&gt;
  &lt;strong&gt;What&lt;/strong&gt;
&lt;/td&gt;

&lt;td width=&quot;94&quot;&gt;
  &lt;strong&gt;Who&lt;/strong&gt;
&lt;/td&gt;
</code></pre>
  </tr>
  <tr>
    <td width="90">
      28 Nov
    </td>
<pre><code>&lt;td width=&quot;267&quot;&gt;
  &amp;nbsp;
&lt;/td&gt;

&lt;td width=&quot;94&quot;&gt;
  &amp;nbsp;
&lt;/td&gt;
</code></pre>
  </tr>
  <tr>
    <td width="90">
      9am
    </td>
<pre><code>&lt;td width=&quot;267&quot;&gt;
  Company premises tour
&lt;/td&gt;

&lt;td width=&quot;94&quot;&gt;
  Frank
&lt;/td&gt;
</code></pre>
  </tr>
  <tr>
    <td width="90">
      11am
    </td>
<pre><code>&lt;td width=&quot;267&quot;&gt;
  Software architecture and layout
&lt;/td&gt;

&lt;td width=&quot;94&quot;&gt;
  Beth
&lt;/td&gt;
</code></pre>
  </tr>
  <tr>
    <td width="90">
      &nbsp;
    </td>
<pre><code>&lt;td width=&quot;267&quot;&gt;
  Rest of the day: Self-explore the knowledge base
&lt;/td&gt;

&lt;td width=&quot;94&quot;&gt;
  &amp;nbsp;
&lt;/td&gt;
</code></pre>
  </tr>
  <tr>
    <td width="90">
      &nbsp;
    </td>
<pre><code>&lt;td width=&quot;267&quot;&gt;
  &amp;nbsp;
&lt;/td&gt;

&lt;td width=&quot;94&quot;&gt;
  &amp;nbsp;
&lt;/td&gt;
</code></pre>
  </tr>
  <tr>
    <td width="90">
      29 Nov
    </td>
<pre><code>&lt;td width=&quot;267&quot;&gt;
  &amp;nbsp;
&lt;/td&gt;

&lt;td width=&quot;94&quot;&gt;
  &amp;nbsp;
&lt;/td&gt;
</code></pre>
  </tr>
  <tr>
    <td width="90">
      Morning
    </td>
<pre><code>&lt;td width=&quot;267&quot;&gt;
  Source control practices
&lt;/td&gt;

&lt;td width=&quot;94&quot;&gt;
  Jerome
&lt;/td&gt;
</code></pre>
  </tr>
  <tr>
    <td width="90">
      10am
    </td>
<pre><code>&lt;td width=&quot;267&quot;&gt;
  Intro to company applications
&lt;/td&gt;

&lt;td width=&quot;94&quot;&gt;
  Mike
&lt;/td&gt;
</code></pre>
  </tr>
  <tr>
    <td width="90">
      2pm
    </td>
<pre><code>&lt;td width=&quot;267&quot;&gt;
  Software release management practices
&lt;/td&gt;

&lt;td width=&quot;94&quot;&gt;
  Sun
&lt;/td&gt;
</code></pre>
  </tr>
  <tr>
    <td width="90">
      &nbsp;
    </td>
<pre><code>&lt;td width=&quot;267&quot;&gt;
  Rest of the day: Self-explore the knowledge base
&lt;/td&gt;

&lt;td width=&quot;94&quot;&gt;
  &amp;nbsp;
&lt;/td&gt;
</code></pre>
  </tr>
  <tr>
    <td width="90">
      &nbsp;
    </td>
<pre><code>&lt;td width=&quot;267&quot;&gt;
  &amp;nbsp;
&lt;/td&gt;

&lt;td width=&quot;94&quot;&gt;
  &amp;nbsp;
&lt;/td&gt;
</code></pre>
  </tr>
  <tr>
    <td width="90">
      &nbsp;
    </td>
<pre><code>&lt;td width=&quot;267&quot;&gt;
  (a few more days’ plans)
&lt;/td&gt;

&lt;td width=&quot;94&quot;&gt;
  &amp;nbsp;
&lt;/td&gt;
</code></pre>
  </tr>
  <tr>
    <td width="90">
      &nbsp;
    </td>
<pre><code>&lt;td width=&quot;267&quot;&gt;
  &amp;nbsp;
&lt;/td&gt;

&lt;td width=&quot;94&quot;&gt;
  &amp;nbsp;
&lt;/td&gt;
</code></pre>
  </tr>
  <tr>
    <td width="90">
      5 Dec – 6 Dec
    </td>
<pre><code>&lt;td width=&quot;267&quot;&gt;
  Spend a few hours each day with Customer Support
&lt;/td&gt;

&lt;td width=&quot;94&quot;&gt;
  Kamil
&lt;/td&gt;
</code></pre>
  </tr>
  <tr>
    <td width="90">
      &nbsp;
    </td>
<pre><code>&lt;td width=&quot;267&quot;&gt;
  First simple task is assigned
&lt;/td&gt;

&lt;td width=&quot;94&quot;&gt;
  &amp;nbsp;
&lt;/td&gt;
</code></pre>
  </tr>
  <tr>
    <td width="90">
      &nbsp;
    </td>
<pre><code>&lt;td width=&quot;267&quot;&gt;
  &amp;nbsp;
&lt;/td&gt;

&lt;td width=&quot;94&quot;&gt;
  &amp;nbsp;
&lt;/td&gt;
</code></pre>
  </tr>
  <tr>
    <td width="90">
      7 Dec – 9 Dec
    </td>
<pre><code>&lt;td width=&quot;267&quot;&gt;
  Work with the testing team
&lt;/td&gt;

&lt;td width=&quot;94&quot;&gt;
  Gretchen
&lt;/td&gt;
</code></pre>
  </tr>
  <tr>
    <td width="90">
      &nbsp;
    </td>
<pre><code>&lt;td width=&quot;267&quot;&gt;
  One-on-one to review the first 2 weeks
&lt;/td&gt;

&lt;td width=&quot;94&quot;&gt;
  &amp;nbsp;
&lt;/td&gt;
</code></pre>
  </tr>
</table>
<p>The main advantage of the on-boarding plan is how deliberate everything is. The expectations are set up-front for both the incoming team member and the wider company that they each have a part to play. This is highly crucial because the effectiveness of a team stems from how well they work together. A deliberate on-boarding plan such as the one above maximises the contact surface for the new team member. I truly believe this helps generate early wins for everyone.</p>
<p>I’ve been thinking about induction programmes because I have recently started a new job that did not have the clearest of plans. Consequently, I had to take matters into my own hand and approach team members and other departments directly. I sometimes felt like I was being intrusive because other people did not have an obligation to brief me and they may be caught unawares.</p>
<p>It is to my new co-workers’ credit that they were very welcoming and obliging to my requests. It has been almost 4 weeks since I started and I feel quite prepared and integrated into the team. But that is also thanks to my previous exposure to effective on-boarding programmes and my Strategic Management course. I realised that the best way to assimilate is to talk to people and leverage their strengths.</p>
<p>However, that may not be the case for other new starters, especially if they have just graduated or come from a very different organisation. Hence, having a deliberate on-boarding plan can accelerate their transition from resource consumer to value creator. What is YOUR company doing now to on-board new hires? How can that be improved?</p>
<p>Photo credit: <a href="https://www.flickr.com/photos/115026014@N05/13983083088/">Spongehoe</a> via <a href="https://visualhunt.com">VisualHunt</a> / <a href="http://creativecommons.org/licenses/by-nc/2.0/">CC BY-NC</a></p>]]></content></item><item><title>Induction Programmes for New Hires</title><link>https://www.coderfrontline.com/induction-programmes-for-new-hires/</link><pubDate>Sun, 20 Nov 2016 10:23:27 +1200</pubDate><guid>https://www.coderfrontline.com/induction-programmes-for-new-hires/</guid><description>&lt;p>Few tech companies give much thought to formal induction programmes for new employees. It does not seem to give much benefit at first glance, since it happens irregularly. I have experienced both well-structured and informal induction programmes, and I can wholeheartedly say I prefer the former.&lt;/p></description><content type="html"><![CDATA[<p>Few tech companies give much thought to formal induction programmes for new employees. It does not seem to give much benefit at first glance, since it happens irregularly. I have experienced both well-structured and informal induction programmes, and I can wholeheartedly say I prefer the former.</p>
<p>What are the benefits of formal induction programmes? I think the most obvious advantage is its ability to quickly integrate the new hire into the company culture. A common misunderstanding is that people are merely hired for their skills. Why do we need to induct them since they already have those skills? I have previously mentioned that it’s hard to <a href="/cultural-web/">diagnose your own</a> corporate <a href="/culture-re-introduction/">culture</a>, especially once you’ve been in an organisation for a long time. We tend to forget that, yes, there are other ways of doing everyday things like managing source code, conducting team meetings, and handling disagreements. The new team member will bring his or her own culture, and it is our responsibility to bring them up to speed as soon as possible.</p>
<p>This is even more important in the age of the <a href="http://www.cab.org.nz/vat/eb/ea/Pages/Trialperiods.aspx">90-day trial period</a> in New Zealand. Similar probationary systems exist in other countries. It is to both parties’ benefit that new employees can quickly integrate into the organisation. It does no one any favours if the new person flounders about for three months and the organisation cannot get a good assessment if that person is a good fit for the role. A related great book around this is <a href="http://amzn.to/2fffrDz">The First 90 Days</a> wherein the author stresses that new managers have only 90 days to prove their value to the new company. I share that view, and I think that formal induction programmes can help accelerate that.</p>
<p>I was reminded of this topic recently at an <a href="https://www.meetup.com/Agile-Auckland/">Agile Auckland Meetup</a> unconference. A small group of us were interested in how to bring new team members into an Agile team. A couple of answers stuck with me. One manager said he does the bare minimum, rarely taking more than 2 hours, and then lets the new employee loose in the team. His position is that he wants people who are unafraid to speak up and ask for help. I believe he also said that people learn quickest from mistakes. I call that the “throwing them in the deep end” technique. I disagree with him that it is an effective approach, but I understand the logic behind it. I doubt there are many induction programmes that are based around that. I would love to hear more if your team throws new people in the deep end.</p>
<p>Another response was also interesting. The team turns the induction process into a User Story, with the Acceptance Criteria being that the new member commits some production-ready code by the end of the sprint. The User Story is owned by all team members, who then have a stake in helping the newbie learn the ropes. I like the fact that putting it in a story fits into the overall Agile methodology, but more importantly makes clear that induction programmes are a team effort. I still feel it is overly focused on the development process and might unintentionally exclude other crucial elements.</p>
<p>I will write more about my own experiences with induction programmes next week, including one approach that I think ticks all the right boxes. Please comment on other induction programmes you have come across in your line of work.</p>
<div class="subsection subsection-embed">
  Photo credit: <a href="https://www.flickr.com/photos/7-how-7/1609904448/">7-how-7</a> via <a href="https://visualhunt.com/photos/sky/">VisualHunt</a> / <a href="http://creativecommons.org/licenses/by-nc-nd/2.0/">CC BY-NC-ND</a>
</div>]]></content></item><item><title>Web API Practices: Controller Unit Tests</title><link>https://www.coderfrontline.com/web-api-practices-controller-unit-tests/</link><pubDate>Sun, 13 Nov 2016 20:58:37 +1200</pubDate><guid>https://www.coderfrontline.com/web-api-practices-controller-unit-tests/</guid><description>&lt;p>I&amp;rsquo;m sharing some of the best practices that I used in a recent ASP .Net Web API and MVC project. I recently gave a presentation to my team on the Top 5 Web API &lt;span style="text-decoration: line-through;">Best&lt;/span> Practices, and I continue the series by discussing controller unit tests. I struck out the word ‘Best' intentionally. There are so many best practices out there. These practices happened to work very well for this project, but your mileage may vary. However, I think most people understand the value of unit testing, and I’m here to show you some tips in regards to writing controller unit tests.&lt;/p></description><content type="html"><![CDATA[<p>I&rsquo;m sharing some of the best practices that I used in a recent ASP .Net Web API and MVC project. I recently gave a presentation to my team on the Top 5 Web API <span style="text-decoration: line-through;">Best</span> Practices, and I continue the series by discussing controller unit tests. I struck out the word ‘Best' intentionally. There are so many best practices out there. These practices happened to work very well for this project, but your mileage may vary. However, I think most people understand the value of unit testing, and I’m here to show you some tips in regards to writing controller unit tests.</p>
<p>If you’ve followed the series thus far, you will find writing controller unit tests to be a cinch because you have <a href="/web-api-practices-use-dependency-injection/">dependency injection</a> on your ASP .Net controllers. This means the controller itself does not instantiate any of its dependencies such as repositories or business layers. Instead you can use a mocking/stubbing framework such as RhinoMock or Moq to simulate the other layers. I won’t go into detail today as there are great tutorials out there, plus I am starting another series on unit test patterns in the new year.</p>
<p>I will focus instead on how to mock certain bits of ASP .Net ‘magic’ that happens behind the scene. I will give two examples: first for mocking the UrlHelper object and another for mocking the logged in user. Those two scenarios come up quite regularly when crafting controller unit tests.</p>
<h2 id="urlhelper">UrlHelper</h2>
<p>There’s a nifty Url helper in ASP .Net Web API controllers whereby you can generate a hyperlink based off the controller action name and any parameters that you give it. This is handy if you’re making <a href="/hypermedia-api-responses/">Hypermedia APIs</a> as I discussed last week. Imagine you have a POST method and you wish to respond with the link to the newly created user account. This will generate a working link for the action “GetAccountById” with the new ID specified in the route.</p>
<div class="highlight"><pre class="chroma"><code class="language-csharp" data-lang="csharp"><span class="c1">//Returns something like http://mybank:8085/api/account/15
</span><span class="c1"></span><span class="n">Url</span><span class="p">.</span><span class="n">Link</span><span class="p">(</span><span class="s">&#34;GetAccountById&#34;</span><span class="p">,</span> <span class="n">newAccountId</span><span class="p">)</span>
</code></pre></div><p>Here is an example method you can call from controller unit tests that set up the UrlHelper object so it has a route table to reference when running your tests:</p>
<div class="highlight"><pre class="chroma"><code class="language-csharp" data-lang="csharp"><span class="c1">/// &lt;summary&gt;
</span><span class="c1">/// Setups the controller for tests, mainly to create a UrlHelper class and register action names.
</span><span class="c1">/// &lt;/summary&gt;
</span><span class="c1">/// &lt;param name=&#34;controller&#34;&gt;The controller.&lt;/param&gt;
</span><span class="c1"></span><span class="k">private</span> <span class="k">void</span> <span class="n">SetupControllerForTests</span><span class="p">(</span><span class="n">ApiController</span> <span class="n">controller</span><span class="p">)</span>
<span class="p">{</span>
    <span class="kt">var</span> <span class="n">config</span> <span class="p">=</span> <span class="k">new</span> <span class="n">HttpConfiguration</span><span class="p">();</span>
    <span class="kt">var</span> <span class="n">request</span> <span class="p">=</span> <span class="k">new</span> <span class="n">HttpRequestMessage</span><span class="p">(</span><span class="n">HttpMethod</span><span class="p">.</span><span class="n">Post</span><span class="p">,</span> <span class="s">&#34;http://mybank/api/&#34;</span><span class="p">);</span>
    <span class="kt">var</span> <span class="n">route</span> <span class="p">=</span> <span class="n">config</span><span class="p">.</span><span class="n">Routes</span><span class="p">.</span><span class="n">MapHttpRoute</span><span class="p">(</span><span class="s">&#34;GetAccountById&#34;</span><span class="p">,</span> <span class="s">&#34;account/{id}&#34;</span><span class="p">);</span>
    <span class="kt">var</span> <span class="n">routeData</span> <span class="p">=</span> <span class="k">new</span> <span class="n">HttpRouteData</span><span class="p">(</span><span class="n">route</span><span class="p">,</span> <span class="k">new</span> <span class="n">HttpRouteValueDictionary</span>
    <span class="p">{</span>
        <span class="p">{</span><span class="s">&#34;id&#34;</span><span class="p">,</span> <span class="m">15</span><span class="p">}</span>
    <span class="p">});</span>
    <span class="n">controller</span><span class="p">.</span><span class="n">ControllerContext</span> <span class="p">=</span> <span class="k">new</span> <span class="n">HttpControllerContext</span><span class="p">(</span><span class="n">config</span><span class="p">,</span> <span class="n">routeData</span><span class="p">,</span> <span class="n">request</span><span class="p">);</span>
    <span class="n">UrlHelper</span> <span class="n">urlHelper</span> <span class="p">=</span> <span class="k">new</span> <span class="n">UrlHelper</span><span class="p">(</span><span class="n">request</span><span class="p">);</span>
    <span class="n">controller</span><span class="p">.</span><span class="n">Request</span> <span class="p">=</span> <span class="n">request</span><span class="p">;</span>
    <span class="n">controller</span><span class="p">.</span><span class="n">Request</span><span class="p">.</span><span class="n">Properties</span><span class="p">[</span><span class="n">HttpPropertyKeys</span><span class="p">.</span><span class="n">HttpConfigurationKey</span><span class="p">]</span> <span class="p">=</span> <span class="n">config</span><span class="p">;</span>
    <span class="n">controller</span><span class="p">.</span><span class="n">Request</span><span class="p">.</span><span class="n">Properties</span><span class="p">[</span><span class="n">HttpPropertyKeys</span><span class="p">.</span><span class="n">HttpRouteDataKey</span><span class="p">]</span> <span class="p">=</span> <span class="n">routeData</span><span class="p">;</span>

    <span class="n">controller</span><span class="p">.</span><span class="n">Url</span> <span class="p">=</span> <span class="n">urlHelper</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div><p> </p>
<h2 id="logged-in-user">Logged-in User</h2>
<p>The logged-in user is an IPrincipal object as part of the HttpContext in every controller. Here’s one way to mock it, according to a <a href="https://stackoverflow.com/a/17236476/824036">StackOverflow answer</a>:</p>
<div class="highlight"><pre class="chroma"><code class="language-csharp" data-lang="csharp"><span class="c1">// create mock principal
</span><span class="c1"></span><span class="kt">var</span> <span class="n">mocks</span> <span class="p">=</span> <span class="k">new</span> <span class="n">MockRepository</span><span class="p">(</span><span class="n">MockBehavior</span><span class="p">.</span><span class="n">Default</span><span class="p">);</span>
<span class="n">Mock</span><span class="p">&lt;</span><span class="n">IPrincipal</span><span class="p">&gt;</span> <span class="n">mockPrincipal</span> <span class="p">=</span> <span class="n">mocks</span><span class="p">.</span><span class="n">Create</span><span class="p">&lt;</span><span class="n">IPrincipal</span><span class="p">&gt;();</span>
<span class="n">mockPrincipal</span><span class="p">.</span><span class="n">SetupGet</span><span class="p">(</span><span class="n">p</span> <span class="p">=&gt;</span> <span class="n">p</span><span class="p">.</span><span class="n">Identity</span><span class="p">.</span><span class="n">Name</span><span class="p">).</span><span class="n">Returns</span><span class="p">(</span><span class="n">userName</span><span class="p">);</span>
<span class="n">mockPrincipal</span><span class="p">.</span><span class="n">Setup</span><span class="p">(</span><span class="n">p</span> <span class="p">=&gt;</span> <span class="n">p</span><span class="p">.</span><span class="n">IsInRole</span><span class="p">(</span><span class="s">&#34;User&#34;</span><span class="p">)).</span><span class="n">Returns</span><span class="p">(</span><span class="k">true</span><span class="p">);</span>

<span class="c1">// create mock controller context
</span><span class="c1"></span><span class="kt">var</span> <span class="n">mockContext</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Mock</span><span class="p">&lt;</span><span class="n">ControllerContext</span><span class="p">&gt;();</span>
<span class="n">mockContext</span><span class="p">.</span><span class="n">SetupGet</span><span class="p">(</span><span class="n">p</span> <span class="p">=&gt;</span> <span class="n">p</span><span class="p">.</span><span class="n">HttpContext</span><span class="p">.</span><span class="n">User</span><span class="p">).</span><span class="n">Returns</span><span class="p">(</span><span class="n">mockPrincipal</span><span class="p">.</span><span class="n">Object</span><span class="p">);</span>
<span class="n">mockContext</span><span class="p">.</span><span class="n">SetupGet</span><span class="p">(</span><span class="n">p</span> <span class="p">=&gt;</span> <span class="n">p</span><span class="p">.</span><span class="n">HttpContext</span><span class="p">.</span><span class="n">Request</span><span class="p">.</span><span class="n">IsAuthenticated</span><span class="p">).</span><span class="n">Returns</span><span class="p">(</span><span class="k">true</span><span class="p">);</span>

<span class="c1">// create controller
</span><span class="c1"></span><span class="kt">var</span> <span class="n">controller</span> <span class="p">=</span> <span class="k">new</span> <span class="n">MvcController</span><span class="p">()</span> <span class="p">{</span> <span class="n">ControllerContext</span> <span class="p">=</span> <span class="n">mock</span><span class="p">.</span><span class="n">Object</span> <span class="p">};</span>
</code></pre></div><p>However, Scott Hanselman has mentioned another way to inject the IPrincipal object into individual methods instead. This would avoid having to mock the HttpContext as well. His blog post talks about <a href="http://www.hanselman.com/blog/IPrincipalUserModelBinderInASPNETMVCForEasierTesting.aspx">passing IPrincipal objects into MVC controllers</a> but I see no problems getting this to work with Web APIs.</p>
<h2 id="summary">Summary</h2>
<p>It is certainly quite easy to write controller unit tests if you begin with that end in mind. There are other things in the ASP .Net pipeline model that aren’t as easily tested, but it is my opinion that they are part of the framework. Hence it is the responsibility of the framework provider (Microsoft) to test those, not us developers.</p>]]></content></item><item><title>Web API Practices: Hypermedia API Responses</title><link>https://www.coderfrontline.com/web-api-practices-hypermedia-api-responses/</link><pubDate>Sun, 06 Nov 2016 17:44:36 +1200</pubDate><guid>https://www.coderfrontline.com/web-api-practices-hypermedia-api-responses/</guid><description>&lt;p>I&amp;rsquo;m sharing some of the best practices that I used in a recent ASP .Net Web API and MVC project. I recently gave a presentation to my team on the Top 5 Web API &lt;span style="text-decoration: line-through;">Best&lt;/span> Practices, and I continue the series by discussing Hypermedia API responses. I struck out the word ‘Best' intentionally. There are so many best practices out there but not all of them will suit your unique circumstance, especially in regards to Hypermedia API design. These practices happened to work very well for this project, but your mileage may vary.&lt;/p></description><content type="html"><![CDATA[<p>I&rsquo;m sharing some of the best practices that I used in a recent ASP .Net Web API and MVC project. I recently gave a presentation to my team on the Top 5 Web API <span style="text-decoration: line-through;">Best</span> Practices, and I continue the series by discussing Hypermedia API responses. I struck out the word ‘Best' intentionally. There are so many best practices out there but not all of them will suit your unique circumstance, especially in regards to Hypermedia API design. These practices happened to work very well for this project, but your mileage may vary.</p>
<p>I first came across the term ‘Hypermedia API’ at a job interview when they asked me if I had any knowledge of Hypermedia API. I was honest and replied in the negative. I later looked it up and a more formal acronym is HATEOAS (Hypermedia as The Engine of Application State). A good introductory article is on <a href="https://en.wikipedia.org/wiki/HATEOAS">Wikipedia’s HATEOAS</a> page and I will be paraphrasing from it.</p>
<p>A Hypermedia API is a RESTful API design principle. In essence, it relies on an APIs responses to define and guide the user’s next actions. This is in contrast to using API docs such as those generated by <a href="http://swagger.io/">Swagger</a>. A Hypermedia API will return rich media responses, most likely hyperlinks, that more-or-less self-documents.</p>
<p>A good example from the Wiki page is the response when a caller GETs the bank balance of account 12345:</p>
<div class="highlight"><pre class="chroma"><code class="language-xml" data-lang="xml"><span class="cp">&lt;?xml version=&#34;1.0&#34;?&gt;</span>
<span class="nt">&lt;account&gt;</span>
  <span class="nt">&lt;account_number&gt;</span>12345<span class="nt">&lt;/account_number&gt;</span>
  <span class="nt">&lt;balance</span> <span class="na">currency=</span><span class="s">&#34;usd&#34;</span><span class="nt">&gt;</span>100.00<span class="nt">&lt;/balance&gt;</span>
  <span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">&#34;deposit&#34;</span> <span class="na">href=</span><span class="s">&#34;https://somebank.org/account/12345/deposit&#34;</span> <span class="nt">/&gt;</span>
  <span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">&#34;withdraw&#34;</span> <span class="na">href=</span><span class="s">&#34;https://somebank.org/account/12345/withdraw&#34;</span> <span class="nt">/&gt;</span> 
  <span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">&#34;transfer&#34;</span> <span class="na">href=</span><span class="s">&#34;https://somebank.org/account/12345/transfer&#34;</span> <span class="nt">/&gt;</span>
  <span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">&#34;close&#34;</span> <span class="na">href=</span><span class="s">&#34;https://somebank.org/account/12345/close&#34;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/account&gt;</span>
</code></pre></div><p>Most APIs will be designed to return just the amount, e.g. 100.00. In comparison, a Hypermedia API returns a list of URLs (the hypermedia) for all the possible actions moving forwards – such as depositing more money or closing the account. There is no need to read an API doc (though they are still helpful as a reference) or formulate a working URL to transfer money as it’s right there in the response.</p>
<p>It should be obvious that it takes a bit of effort and pre-planning to make your APIs HATEOAS-compliant. However, it’s not an all-or-nothing approach. You can still sprinkle some Hypermedia API sugar all over your existing APIs. One place that I used this approach is with any POST or PUT calls. Instead of simply returning the ID of a newly created record, I will return a fully-formed URI to the created/updated resource, like this:</p>
<div class="highlight"><pre class="chroma"><code class="language-js" data-lang="js"><span class="p">{</span>
    <span class="s2">&#34;Message&#34;</span><span class="o">:</span> <span class="s2">&#34;The user was created successfully&#34;</span><span class="p">,</span>
    <span class="s2">&#34;MessageDetail&#34;</span><span class="o">:</span> <span class="s2">&#34;/api/15&#34;</span>
<span class="p">}</span>
</code></pre></div><p>Also note how I used the same detailed message response when I wrote about <a href="/consistent-response-format/">Consistent Response Formats</a>.</p>
<p>Granted, this is nowhere near HATEOAS-compliant but it’s a great start and it’s been really helpful for the testers to write automated API tests because they do not need to keep track of IDs formulate URLs because the resource link is provided right there.</p>
<p>If I had to summarise Hypermedia APIs it is all about understanding how your users interact with your RESTful API and to use that knowledge to create a more pleasant experience. User experience design can still benefit APIs even though it has no graphical user interface.</p>
<p>Photo credit: <a href="https://www.flickr.com/photos/abstractmachine/14321480869/">Abstract Machine</a> via <a href="https://visualhunt.com/">Visualhunt</a> / <a href="http://creativecommons.org/licenses/by-nc-sa/2.0/">CC BY-NC-SA</a></p>]]></content></item><item><title>Web API Practices: Consistent Response Format</title><link>https://www.coderfrontline.com/web-api-practices-consistent-response-format/</link><pubDate>Mon, 31 Oct 2016 09:43:56 +1200</pubDate><guid>https://www.coderfrontline.com/web-api-practices-consistent-response-format/</guid><description>&lt;p>I&amp;rsquo;m sharing some of the best practices that I used in a recent ASP .Net Web API and MVC project. I recently gave a presentation to my team on the Top 5 Web API &lt;span style="text-decoration: line-through;">Best&lt;/span> Practices, and I continue the series by discussing AutoMapper this week. I struck out the word ‘Best' intentionally. There are so many best practices out there but not all of them will suit your unique circumstance. These practices happened to work very well for this project, but your mileage may vary. Consistent response formats, however, are pretty much universal and something that all of us should be doing already.&lt;/p></description><content type="html"><![CDATA[<p>I&rsquo;m sharing some of the best practices that I used in a recent ASP .Net Web API and MVC project. I recently gave a presentation to my team on the Top 5 Web API <span style="text-decoration: line-through;">Best</span> Practices, and I continue the series by discussing AutoMapper this week. I struck out the word ‘Best' intentionally. There are so many best practices out there but not all of them will suit your unique circumstance. These practices happened to work very well for this project, but your mileage may vary. Consistent response formats, however, are pretty much universal and something that all of us should be doing already.</p>
<p>RESTful APIs are meant for external consumption although it does not have a traditional user interface as such. This means it should cater for various user levels, some of whom may not be familiar with the inner workings of the API. Hence, it is important to return useful and clear messages especially when an error occurs. I think this is pretty clear to most developers.</p>
<p>It is more difficult to ensure consistent response formats when there are multiple programmers building a single API. It is also rare for error message phrasings to be specified up-front in this increasingly Agile world. What I have experienced is each coder coming up with his or her own approach to showing error messages. Common formats include:</p>
<ul>
<li>Just returning HTTP status codes: I am not a fan of this as it can be open to misinterpretation, especially when it comes to input validation errors (e.g. POST-ing an email address with invalid characters).</li>
<li>Including a message with the appropriate HTTP status code: This is better, and I suspect is the approach taken by most APIs. This is even provided in the standard <a href="https://msdn.microsoft.com/en-us/library/system.web.http.results.aspx">HTTP Results types</a>.</li>
<li>Including a message and detailed message with the appropriate HTTP status code: This is the approach I went for, and the response is a JSON object that looks something like:</li>
</ul>
<div class="highlight"><pre class="chroma"><code class="language-js" data-lang="js"><span class="p">{</span>
    <span class="s2">&#34;Message&#34;</span><span class="o">:</span> <span class="s2">&#34;Input validation errors&#34;</span><span class="p">,</span>
    <span class="s2">&#34;MessageDetail&#34;</span><span class="o">:</span> <span class="s2">&#34;Please fix the following issues: The email address contains invalid characters and the zip code is missing&#34;</span>
<span class="p">}</span>
</code></pre></div><p>I went with this approach to provide two layers of error messages that can be used to drive a visual error dialog. The Message can be used as the dialog box title, while the MessageDetail forms the dialog box content itself.</p>
<p>Alternatively, I could just display the MessageDetail in a Bootstrap status message at the top of the screen. I effectively open up the options for my API consumers to understand the results and consequently display it to their users in the most appropriate manner.</p>
<p>The next step after deciding on a return format that works, is to make it easy for all developers to use it. The most basic way to do this is to create a POCO that has both fields:</p>
<div class="highlight"><pre class="chroma"><code class="language-csharp" data-lang="csharp"><span class="k">public</span> <span class="k">struct</span> <span class="nc">ReturnMessage</span> <span class="p">{</span>
    <span class="k">public</span> <span class="kt">string</span> <span class="n">Message</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
    <span class="k">public</span> <span class="kt">string</span> <span class="n">MessageDetail</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
<span class="p">}</span>
</code></pre></div><p>Developers can then instantiate a ReturnMessage when a success or error message is desired. This is of course just a starting point. A further extension is to create helper types similar to the IHttpActionResult implementations defined in the <a href="https://msdn.microsoft.com/en-us/library/system.web.http.results.aspx">System.Web.Http.Results namespace</a> for the most commonly used HTTP codes in your application.</p>
<p>The main takeaway is to make it easy for team members to return consistent response messages. This helps your users and their users down the line. It doesn’t have to be using a ReturnMessage type as I had, but consistent messages go a long way in making a user-friendly Web API.</p>
<p>Photo via <a href="https://visualhunt.com/">Visual Hunt</a></p>]]></content></item><item><title>Another Hiatus</title><link>https://www.coderfrontline.com/another-hiatus/</link><pubDate>Sat, 24 Sep 2016 22:48:42 +1200</pubDate><guid>https://www.coderfrontline.com/another-hiatus/</guid><description>I am stepping away from the frontline again to finish up my second assignment. I will be back sometime in October to finish my series on Web API practices.</description><content type="html">&lt;p>I am stepping away from the frontline again to finish up my second assignment. I will be back sometime in October to finish my series on Web API practices.&lt;/p></content></item><item><title>Revisited: Why Care About Culture?</title><link>https://www.coderfrontline.com/revisited-why-care-about-culture/</link><pubDate>Sat, 17 Sep 2016 11:41:21 +1200</pubDate><guid>https://www.coderfrontline.com/revisited-why-care-about-culture/</guid><description>This coder is stepping away from the front line for another week while he takes a well-deserved holiday on the Indonesian destination of Bali. Instead, I will link to an article from the archives and add some new thoughts on it.
This week I revisit my post on why we should care about culture. I put forward my argument that we should pay close attention to culture as it affects more than just whether people have work drinks on a Friday afternoon.</description><content type="html"><![CDATA[<p>This coder is stepping away from the front line for another week while he takes a well-deserved holiday on the Indonesian destination of Bali. Instead, I will link to an article from the archives and add some new thoughts on it.</p>
<p>This week I revisit my post on <a href="/why-care-about-culture/">why we should care about culture</a>. I put forward my argument that we should pay close attention to culture as it affects more than just whether people have work drinks on a Friday afternoon. This was especially relevant to me as I recently interviewed for some new jobs, and the top question of my mind is always, “Will I fit into their culture?” I was also conscious about portraying myself as fitting into the organisation&rsquo;s culture, by highlighting relevant past experiences. It is something that I look for when I interview candidates, and so I try to make sure they see that when I am on the other side of the table.</p>
<p>Photo credit: <a href="https://www.flickr.com/photos/kailehmann/19892370205/">Kai Lehmann</a> via <a href="https://visualhunt.com/photos/nature-images/">Visualhunt</a> / <a href="http://creativecommons.org/licenses/by/2.0/">CC BY</a></p>
]]></content></item><item><title>Revisited: Cutting-Edge Technology Cuts</title><link>https://www.coderfrontline.com/revisited-cutting-edge-technology-cuts/</link><pubDate>Sun, 11 Sep 2016 11:25:28 +1200</pubDate><guid>https://www.coderfrontline.com/revisited-cutting-edge-technology-cuts/</guid><description>This coder is stepping away from the front line for two weeks while he takes a well-deserved holiday on the Indonesian destination of Bali. Instead, I will link to an article from the archives and add some new thoughts on it.
This week I revisit my post Cutting-Edge Technology Cuts, where I lambasted ASP .Net Core RC1 for its weak tooling support and how I rolled back to ASP .Net 4.</description><content type="html"><![CDATA[<p>This coder is stepping away from the front line for two weeks while he takes a well-deserved holiday on the Indonesian destination of Bali. Instead, I will link to an article from the archives and add some new thoughts on it.</p>
<p>This week I revisit my post <a href="/cutting-edge-technology-cuts/">Cutting-Edge Technology Cuts</a>, where I lambasted ASP .Net Core RC1 for its weak tooling support and how I rolled back to ASP .Net 4.5 with my tail between my legs. It&rsquo;s now five months since that post and things have only marginally improved with the official 1.0 release. The <a href="https://blogs.msdn.microsoft.com/dotnet/2016/07/15/net-core-roadmap/">issue thread on GitHub is still fairly active</a> but it seems it has been noted by the development team in the <a href="https://blogs.msdn.microsoft.com/dotnet/2016/07/15/net-core-roadmap/">.Net Core product roadmap</a>. My opinion is now shifting towards using Core 1.0 for experiments to see what it&rsquo;s all about, but to refrain from full-on production level work until brave pioneers have surfaced other niggly issues with it.</p>
<p>Photo credit: <a href="https://www.flickr.com/photos/chrisjunker/5184447518/">Christian Junker | Photography</a> via <a href="https://visualhunt.com/">Visual Hunt</a> / <a href="http://creativecommons.org/licenses/by-nc-nd/2.0/">CC BY-NC-ND</a></p>
]]></content></item><item><title>Web API Practices: AutoMapper for Object-Object Mapping</title><link>https://www.coderfrontline.com/web-api-practices-automapper-for-object-object-mapping/</link><pubDate>Sun, 04 Sep 2016 14:51:18 +1200</pubDate><guid>https://www.coderfrontline.com/web-api-practices-automapper-for-object-object-mapping/</guid><description>&lt;p>I&amp;rsquo;m sharing some of the best practices that I used in a recent ASP .Net Web API and MVC project. I recently gave a presentation to my team on the Top 5 Web API &lt;span style="text-decoration: line-through;">Best&lt;/span> Practices, and I continue the series by discussing AutoMapper this week. I struck out the word ‘Best' intentionally. There are so many best practices out there but not all of them will suit your unique circumstance. These practices happened to work very well for this project, but your mileage may vary.&lt;/p></description><content type="html"><![CDATA[<p>I&rsquo;m sharing some of the best practices that I used in a recent ASP .Net Web API and MVC project. I recently gave a presentation to my team on the Top 5 Web API <span style="text-decoration: line-through;">Best</span> Practices, and I continue the series by discussing AutoMapper this week. I struck out the word ‘Best' intentionally. There are so many best practices out there but not all of them will suit your unique circumstance. These practices happened to work very well for this project, but your mileage may vary.</p>
<p>Most projects of a decent complexity will usually need to deal with object to object mapping. This is when an object needs to be converted to another type. Some common scenarios include translating a model to a view-model and flattening a complex object into simple fields for database persistence. This task is traditionally done using a simple mapping method, for example:</p>
<div class="highlight"><pre class="chroma"><code class="language-csharp" data-lang="csharp"><span class="k">public</span> <span class="k">static</span> <span class="n">SimpleDatabaseObject</span> <span class="n">Flatten</span><span class="p">(</span><span class="n">BusinessLayerObject</span> <span class="n">blo</span><span class="p">)</span>
<span class="p">{</span>
    <span class="k">return</span> <span class="k">new</span> <span class="n">SimpleDatabaseObject</span> <span class="p">{</span>
        <span class="n">Id</span> <span class="p">=</span> <span class="n">blo</span><span class="p">.</span><span class="n">Id</span><span class="p">;</span>
        <span class="n">Title</span> <span class="p">=</span> <span class="n">blo</span><span class="p">.</span><span class="n">Title</span><span class="p">;</span>
        <span class="n">CategoryId</span> <span class="p">=</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span> <span class="n">blo</span><span class="p">.</span><span class="n">CategoryEnum</span><span class="p">;</span>
    <span class="p">};</span>
<span class="p">}</span>
</code></pre></div><p>While this works well, note that the code is pretty simple – all it does is assign some property as-is or cast an enum to an int. A similar method would also be needed if you wanted to convert it back the other way. A disadvantage is apparent once new properties are added – the developer would need to remember to update both methods if it is meant to be mapped back and forth.</p>
<p>Alternatively, convention-based object to object mappers like AutoMapper take the frustration out of this common scenario with simple code like this:</p>
<div class="highlight"><pre class="chroma"><code class="language-csharp" data-lang="csharp"><span class="kt">var</span> <span class="n">flattenedDto</span> <span class="p">=</span> <span class="n">Mapper</span><span class="p">.</span><span class="n">Map</span><span class="p">&lt;</span><span class="n">SimpleDatabaseObject</span><span class="p">&gt;(</span><span class="n">someBusinessLayerObjectHere</span><span class="p">);</span>
</code></pre></div><p>This is possible once AutoMapper is configured before the application starts. Registering maps is dead simple if it follows common conventions, but it is also fairly easy to customize mapping. Here is an example for the BusinessLayerObject to SimpleDatabaseObject mapping:</p>
<div class="highlight"><pre class="chroma"><code class="language-csharp" data-lang="csharp"><span class="n">Mapper</span><span class="p">.</span><span class="n">CreateMap</span><span class="p">&lt;</span><span class="n">BusinessLayerObject</span><span class="p">,</span> <span class="n">SimpleDatabaseObject</span><span class="p">&gt;()</span>
<span class="p">.</span><span class="n">ForMember</span><span class="p">(</span><span class="n">d</span> <span class="p">=&gt;</span> <span class="n">d</span><span class="p">.</span> <span class="n">CategoryId</span><span class="p">,</span> <span class="n">o</span> <span class="p">=&gt;</span> <span class="n">o</span><span class="p">.</span><span class="n">MapFrom</span><span class="p">(</span><span class="n">y</span> <span class="p">=&gt;</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span> <span class="n">y</span><span class="p">.</span><span class="n">CategoryEnum</span><span class="p">));</span>
</code></pre></div><p>Properties that have the same name and compatible types are mapped automatically, such as Id and Title strings. Those that follow conventions happen automagically too, e.g. BookAuthorLastName can be resolved by Book.Author.LastName. Properties that have a different name or special conversion rules will need a bit of help as I’ve shown above.</p>
<p>Using AutoMapper has greatly simplified our Web API development. It is normal for us to expose only a subset of the model through the RESTful interface. There are also rules around how to return certain data types. True, we still need to make sure new properties are added on both the source and destination types, but we only need to configure all the mapping rules in one place.</p>
<p>A practical disadvantage we have encountered is around combining multiple objects into one. I am sure there are ways to configure AutoMapper to do so, but we have found it easier to specify manual mapping methods if we need to construct an object using multiple source objects. The lesson here is to recognise the boundaries of any framework, so we can break away when we need to.</p>]]></content></item><item><title>Web API Practices: Use Dependency Injection</title><link>https://www.coderfrontline.com/web-api-practices-use-dependency-injection/</link><pubDate>Sun, 28 Aug 2016 10:18:20 +1200</pubDate><guid>https://www.coderfrontline.com/web-api-practices-use-dependency-injection/</guid><description>&lt;p>I&amp;rsquo;ve been working on a web project for the past year that used both ASP .Net (4.5.2) Web API and MVC. The Web API provides a foundation for flexible data access, while MVC uses it to power a rich web application. I recently gave a presentation to my team on the Top 5 Web API &lt;del>Best&lt;/del> Practices, and I will reproduce portions of it over the next five entries. I struck out the word ‘Best' intentionally. There are so many best practices out there but not all of them will suit your unique circumstance. These practices happened to work very well for this project, and we&amp;rsquo;ll start with a popular one - dependency injection.&lt;/p></description><content type="html"><![CDATA[<p>I&rsquo;ve been working on a web project for the past year that used both ASP .Net (4.5.2) Web API and MVC. The Web API provides a foundation for flexible data access, while MVC uses it to power a rich web application. I recently gave a presentation to my team on the Top 5 Web API <del>Best</del> Practices, and I will reproduce portions of it over the next five entries. I struck out the word ‘Best' intentionally. There are so many best practices out there but not all of them will suit your unique circumstance. These practices happened to work very well for this project, and we&rsquo;ll start with a popular one - dependency injection.</p>
<p>Dependency injection is one particular pattern that implements the Inversion-of-Control principle. To paraphrase <a href="https://en.wikipedia.org/wiki/Dependency_injection">Wikipedia</a>‘s excellent page on it, a class should have all its dependencies provided rather than create them itself. For example, you are provided a complete object to use instead of instantiating a business layer object yourself:</p>
<div class="highlight"><pre class="chroma"><code class="language-csharp" data-lang="csharp"><span class="k">public</span> <span class="k">class</span> <span class="nc">AwesomeController</span> <span class="p">:</span> <span class="n">ApiController</span> <span class="p">{</span>
    <span class="k">private</span> <span class="n">IBusinessLayer</span> <span class="n">mBusinessLayer</span><span class="p">;</span>

    <span class="k">public</span> <span class="n">AwesomeController</span> <span class="p">(</span><span class="n">IBusinessLayer</span> <span class="n">businessLayer</span><span class="p">){</span>
        <span class="n">mBusinessLayer</span><span class="p">=</span> <span class="n">businessLayer</span><span class="p">;</span>
    <span class="p">}</span>

<span class="c1">//Logic code that uses mBusinessLayer
</span><span class="c1"></span><span class="p">}</span>
</code></pre></div><p>In this case, your dependency on a business layer object is injected into the controller. Your controller can go on with its life completely oblivious to the exact implementation as long as it matches the IBusinessLayer contract.</p>
<p>The concept of dependency injection is pretty simple. Actually linking it to Web API and MVC is slightly more complicated, however. There are many dependency injection libraries in the market - I personally use StructureMap, but others like NInject work in a similar manner. Because they are platform-agnostic, you still need to hook it up to the overall Web API lifecycle. The general steps are:</p>
<ol>
<li>Configure dependency injection container</li>
<li>Configure Web API/MVC/other system components to use the container</li>
<li>Use it in your code</li>
</ol>
<p>I usually struggle with Step 2. The number of custom NuGet packages and blog tutorials out there tell me I&rsquo;m not the only one. I won&rsquo;t add to the cacophony as I find each project to be slightly different. This project is using Web API + MVC, while another project used MVC + SignalR. The key thing to keep in mind is that those technologies have built-in support for dependency injection, and it is a matter of finding the right combination of switches. This is what I used in my project to link the same StructureMap container to both MVC and Web API:</p>
<div class="highlight"><pre class="chroma"><code class="language-csharp" data-lang="csharp"><span class="k">public</span> <span class="k">static</span> <span class="k">void</span> <span class="n">Initialize</span><span class="p">()</span>
<span class="p">{</span>
    <span class="n">SetupService</span><span class="p">();</span> <span class="c1">//Setup StructureMap mappings
</span><span class="c1"></span>    <span class="n">Resolver</span> <span class="p">=</span> <span class="k">new</span> <span class="n">StructureMapDependencyResolver</span><span class="p">(</span><span class="n">Container</span><span class="p">);</span> <span class="c1">//Implements both versions of IDependencyResolver
</span><span class="c1"></span>    <span class="n">DependencyResolver</span><span class="p">.</span><span class="n">SetResolver</span><span class="p">(</span><span class="n">Resolver</span><span class="p">);</span> <span class="c1">//For MVC Controllers
</span><span class="c1"></span>    <span class="n">GlobalConfiguration</span><span class="p">.</span><span class="n">Configuration</span><span class="p">.</span><span class="n">DependencyResolver</span> <span class="p">=</span> <span class="n">Resolver</span><span class="p">;</span> <span class="c1">//For Web API Controllers
</span><span class="c1"></span><span class="p">}</span>
</code></pre></div><p>It&rsquo;s very smooth sailing once the plumbing is hooked up! I add new dependencies in the container and have confidence it gets used correctly anywhere in my web project. My code is now decoupled from my dependencies. (A valid criticism is that I am now dependent on dependency injection, but it&rsquo;s gotta start somewhere right?)</p>
<p>ASP .Net Core takes this one step further and implements its own simple dependency injection system. This will greatly increase adoption as the difficult Step 2 is more or less removed. However, I am still waiting with bated breath for a stable production version after my <a href="/cutting-edge-technology-cuts/">last run-in with ASP .Net Core</a>.</p>
<p>Photo credit: <a href="https://www.flickr.com/photos/slipstreamjc/2060643626/">SlipStreamJC</a> via <a href="https://visualhunt.com/">Visual Hunt</a> / <a href="http://creativecommons.org/licenses/by-nc/2.0/">CC BY-NC</a></p>]]></content></item><item><title>Smart Date Picker: Unit Tests</title><link>https://www.coderfrontline.com/smart-date-picker-unit-tests/</link><pubDate>Sat, 20 Aug 2016 22:13:02 +1200</pubDate><guid>https://www.coderfrontline.com/smart-date-picker-unit-tests/</guid><description>&lt;p>I finally add some unit tests for my date range bumper logic. I based it on my earlier blog &lt;a href="https://www.coderfrontline.com/smart-date-picker-requirements/">post on test cases&lt;/a> with some additions. I subsequently found bugs that I wouldn’t have found otherwise. I also added FRP code to differentiate between start and end date selection, which I’ll briefly talk about later. But first, a community service message regarding unit tests.&lt;/p></description><content type="html"><![CDATA[<p>I finally add some unit tests for my date range bumper logic. I based it on my earlier blog <a href="/smart-date-picker-requirements/">post on test cases</a> with some additions. I subsequently found bugs that I wouldn’t have found otherwise. I also added FRP code to differentiate between start and end date selection, which I’ll briefly talk about later. But first, a community service message regarding unit tests.</p>
<p>I’ll admit it – I don’t write unit tests as much as I would like to. I’ve only worked at companies with a lot of legacy code that use various levels of automated unit tests. Test-Driven Development (TDD) emphasises writing tests to guide the implementation. Many people consider that as working backwards. I used to be a doubter until I actually tried it for myself. The big advantage of TDD is that it creates testable code up front. A lot of legacy code works fine, but was designed with lots of internal dependencies that make it hard to mock and stub without contorting oneself. This leads to people giving up writing and maintaining unit tests, as the cost becomes too high. Most people mean well – but if the right <a href="/why-care-about-culture/">culture</a> and code conditions are not present unit testing becomes difficult to practice.</p>
<p>I now make it a point to write unit tests where I can. This little FRP project is no different. FRP helped me to unify the logic into one public method which I could unit test vigorously. This is now up on the <a href="https://github.com/zemien/smart-date-picker">GitHub project under the 03 – Unit Tests</a> folder. Just a note that I’m using NUnit 3.x, which may require updated test suite runners on your environment.</p>
<p>I also modified the SWidget DateField to expose a Stream<DateTime> property in addition to the existing Cell<DateTime>. I’m not sure if I did it correctly, but I needed a Stream for when the date changes in order to merge() them into a single Stream denoting which date to prioritise. There is slightly different bumping behaviour depending on which date picker the user picked.</p>
<p>The next and final step is to loop the resultant DateRange back into the DateField control. This is one part I’m not sure how to implement. I will need to read the advanced chapters of the book, which I don’t have the time for until I’m done with my Marketing Management course. This is a wrap on FRP for now!</p>
<p><em>This is part of an ongoing series where I review the book</em><a href="https://www.manning.com/books/functional-reactive-programming"> <em>Functional Reactive Programming by Stephen Blackheath and Anthony Jones</em></a><em>. Kindly note that anything I write here may be incorrect and not indicative of the author’s intent. After all, making mistakes is the mother of learning and this book review is meant to be a truthful reflection of my own experiences grasping a new concept. The review copy I received was version 11 in their Manning’s Early Access Program, so the book’s contents may differ at the time of publication.</em></p>]]></content></item><item><title>Two Week Posting Hiatus</title><link>https://www.coderfrontline.com/two-week-posting-hiatus/</link><pubDate>Fri, 29 Jul 2016 21:11:22 +1200</pubDate><guid>https://www.coderfrontline.com/two-week-posting-hiatus/</guid><description>I am taking a two week hiatus from blogging as I need to finish my first Marketing Management assignment. I am doing a marketing study on 1Above the flight drink company. The study of product marketing is a new subject for me, and so I have quite a bit to catch up on.
Photo credit: Pierre J. via VisualHunt / CC BY-NC-SA</description><content type="html"><![CDATA[<p>I am taking a two week hiatus from blogging as I need to finish my first Marketing Management assignment. I am doing a marketing study on 1Above the flight drink company. The study of product marketing is a new subject for me, and so I have quite a bit to catch up on.</p>
<p>Photo credit: <a href="https://www.flickr.com/photos/7969902@N07/476909988/">Pierre J.</a> via <a href="https://visualhunt.com">VisualHunt</a> / <a href="http://creativecommons.org/licenses/by-nc-sa/2.0/">CC BY-NC-SA</a></p>
]]></content></item><item><title>Smart Date Picker: Selecting and bumping dates</title><link>https://www.coderfrontline.com/smart-date-picker-selecting-and-bumping-dates/</link><pubDate>Sun, 24 Jul 2016 13:18:33 +1200</pubDate><guid>https://www.coderfrontline.com/smart-date-picker-selecting-and-bumping-dates/</guid><description>&lt;p>This is a direct continuation of the &lt;a href="https://www.coderfrontline.com/smart-date-picker-period-type-frp-primitives/">last post on using FRP primitives&lt;/a> to model changing the period type. I will jump straight into the next part of adding more smart date picker functionality. You might want to review the &lt;a href="https://www.coderfrontline.com/?s=smart+date+picker">entire series&lt;/a> on making a smart date picker if this is your first visit.&lt;/p></description><content type="html"><![CDATA[<p>This is a direct continuation of the <a href="/smart-date-picker-period-type-frp-primitives/">last post on using FRP primitives</a> to model changing the period type. I will jump straight into the next part of adding more smart date picker functionality. You might want to review the <a href="/?s=smart+date+picker">entire series</a> on making a smart date picker if this is your first visit.</p>
<h2 id="code-on-github">Code on GitHub</h2>
<p>This week’s fully-functional code is up on the <a href="https://github.com/zemien/smart-date-picker">GitHub project</a>, under the 02 – Date Range Picker folder. Each folder corresponds to a week’s post and is self-contained. You will need a .Net 4.6.1 compiler to be able to build and run the project.</p>
<h2 id="data-availability-dates">Data Availability Dates</h2>
<p>One of the control’s external data source is the dates that the system has data for. I am modelling it in a simple way in this exercise by way of a service class. This DataAvailabilityService exposes a Cell of a DateRange. A DateRange is an immutable struct that contains a start and end DateTime. Immutability is an important concept in functional programming, and a good practice to consider in general.</p>
<p>I use a CellSink in this class. A CellSink and StreamSink are the primary ways to sending data into FRP logic. They extend a Cell or Stream with a send() method that pushes data into FRP-land. There is no other way to instantiate a Cell or a Stream without going through the sinks.</p>
<p>In my simple service I have initialised the CellSink with a default value, but I’ve also added a method that simulates fetching new dates from the external world. I am not using this bit yet so we can ignore this for now.</p>
<div class="highlight"><pre class="chroma"><code class="language-csharp" data-lang="csharp"><span class="k">public</span> <span class="k">class</span> <span class="nc">DataAvailabilityService</span>
<span class="p">{</span>
    <span class="k">private</span> <span class="k">readonly</span> <span class="n">CellSink</span><span class="p">&lt;</span><span class="n">DateRange</span><span class="p">&gt;</span> <span class="n">mDataAvailabilitySink</span><span class="p">;</span>

    <span class="c1">/// &lt;summary&gt;
</span><span class="c1"></span>    <span class="c1">/// Initializes a Data Availability Service
</span><span class="c1"></span>    <span class="c1">/// &lt;/summary&gt;
</span><span class="c1"></span>    <span class="k">public</span> <span class="n">DataAvailabilityService</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="n">mDataAvailabilitySink</span> <span class="p">=</span> <span class="k">new</span> <span class="n">CellSink</span><span class="p">&lt;</span><span class="n">DateRange</span><span class="p">&gt;(</span><span class="k">new</span> <span class="n">DateRange</span><span class="p">(</span><span class="k">new</span> <span class="n">DateTime</span><span class="p">(</span><span class="m">2014</span><span class="p">,</span> <span class="m">1</span><span class="p">,</span> <span class="m">1</span><span class="p">),</span> <span class="k">new</span> <span class="n">DateTime</span><span class="p">(</span><span class="m">2016</span><span class="p">,</span> <span class="m">07</span><span class="p">,</span> <span class="m">31</span><span class="p">)));</span>
    <span class="p">}</span>

    <span class="c1">/// &lt;summary&gt;
</span><span class="c1"></span>    <span class="c1">/// Dates that we can run reports for
</span><span class="c1"></span>    <span class="c1">/// &lt;/summary&gt;
</span><span class="c1"></span>    <span class="k">public</span> <span class="n">Cell</span><span class="p">&lt;</span><span class="n">DateRange</span><span class="p">&gt;</span> <span class="n">DataAvailability</span>
    <span class="p">{</span>
        <span class="k">get</span>
        <span class="p">{</span>
            <span class="k">return</span> <span class="n">mDataAvailabilitySink</span><span class="p">;</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div><h2 id="adding-date-pickers">Adding date pickers</h2>
<p>Once again I am using the SWidget library from the <a href="https://github.com/SodiumFRP/sodium">Sodium FRP library</a> book examples. It includes a rudimentary date picker control that consists of three combo boxes, instead of a fancy calendar picker. It exposes a SelectedDate Cell property, which contains the user-selected date.</p>
<h2 id="lift-frp-primitive">lift() FRP primitive</h2>
<p>lift() is another FRP primitive that works like map() and merge() for multiple cells – you provide a function that combines multiple cells into one. It is called ‘lift’ “because we are ‘lifting’ a function that operates on values into the world of cells.” It is a general functional programming concept that I am still not familiar with.</p>
<h2 id="the-bump-dates-function">The bump dates function</h2>
<p>Alright – let’s bring all those Cells together and make a smart date picker, shall we? We now have the following Cells:</p>
<ul>
<li>StartDate</li>
<li>EndDate</li>
<li>DataAvailability</li>
<li>PeriodType</li>
</ul>
<p>As mentioned, we will use the lift() function to combine all those cells and output a DateRange.</p>
<div class="highlight"><pre class="chroma"><code class="language-csharp" data-lang="csharp"><span class="c1">//Combine the different cells into one DateRange using a Lift() call to BumpDates()
</span><span class="c1"></span><span class="n">Cell</span><span class="p">&lt;</span><span class="n">DateRange</span><span class="p">&gt;</span> <span class="n">cDateRange</span> <span class="p">=</span> <span class="n">startDateField</span><span class="p">.</span><span class="n">SelectedDate</span><span class="p">.</span><span class="n">Lift</span><span class="p">(</span>
    <span class="n">endDateField</span><span class="p">.</span><span class="n">SelectedDate</span><span class="p">,</span> <span class="n">dataAvailabilityService</span><span class="p">.</span><span class="n">DataAvailability</span><span class="p">,</span> 
    <span class="n">cPeriodTypeCell</span><span class="p">,</span> <span class="n">ReportDateRangeBumper</span><span class="p">.</span><span class="n">BumpDates</span><span class="p">);</span>
</code></pre></div><p>The last method argument is a method I’ve defined in a separate helper class.</p>
<h2 id="date-bumping-helper-function">Date bumping helper function</h2>
<p>ReportDateRangeBumper is a helper class that is the logical ham in this FRP sandwich. I won’t go into details as it’s pretty simple once you read it. What’s important is how simple it is – it doesn’t maintain state or have external dependencies. This retains referential transparency and also makes it easy to unit test. In other words, it will always return the same result with the same input parameters.</p>
<p>This is a massive improvement over the non-FRP way of doing things. Previously, I had logic scattered in various event handlers that made it impractical to unit test. I also could not guarantee the order of the events.</p>
<h2 id="displaying-the-bumped-dates">Displaying the bumped dates</h2>
<p>Finally, I display the bumped dates by using another map() call to convert the DateRange to a string representation. I add this to a SLabel control on the screen.</p>
<div class="highlight"><pre class="chroma"><code class="language-csharp" data-lang="csharp"><span class="n">SLabel</span> <span class="n">selectedDate</span> <span class="p">=</span> <span class="k">new</span> <span class="n">SLabel</span><span class="p">(</span><span class="n">cDateRange</span><span class="p">.</span><span class="n">Map</span><span class="p">(</span><span class="n">dr</span> <span class="p">=&gt;</span> <span class="n">dr</span><span class="p">.</span><span class="n">ToString</span><span class="p">()));</span>

<span class="c1">//Some other code
</span><span class="c1"></span>
<span class="n">ResultsContainer</span><span class="p">.</span><span class="n">Children</span><span class="p">.</span><span class="n">Add</span><span class="p">(</span><span class="n">selectedDate</span><span class="p">);</span>
</code></pre></div><h2 id="next-steps">Next steps</h2>
<p>There are a few important things I still need to figure out. I’ve added TODO notes throughout the code.</p>
<ul>
<li>Differentiate between changing the start date vs. the end date picker.</li>
<li>Update the SDateField once I’ve bumped the selected dates.</li>
<li>Simulate changing data availabilities while the program is running.</li>
</ul>
<p>Comments on how to achieve those will be much appreciated!</p>
<p><em>This is part of an ongoing series where I review the book</em><a href="https://www.manning.com/books/functional-reactive-programming"> <em>Functional Reactive Programming by Stephen Blackheath and Anthony Jones</em></a><em>. Kindly note that anything I write here may be incorrect and not indicative of the author’s intent. After all, making mistakes is the mother of learning and this book review is meant to be a truthful reflection of my own experiences grasping a new concept. The review copy I received was version 11 in their Manning’s Early Access Program, so the book’s contents may differ at the time of publication.</em></p>]]></content></item><item><title>Smart Date Picker: Changing the period type using FRP Primitives</title><link>https://www.coderfrontline.com/smart-date-picker-changing-the-period-type-using-frp-primitives/</link><pubDate>Sun, 17 Jul 2016 15:05:55 +1200</pubDate><guid>https://www.coderfrontline.com/smart-date-picker-changing-the-period-type-using-frp-primitives/</guid><description>&lt;p>I’ve faffed about at the fringes of functional reactive programming (FRP) for a while now, but I think it’s time to take a cold plunge into actually using some Sodium FRP primitives. FRP primitives are the fundamental operations (methods or functions) that make up the core of FRP. What makes them primitive is that they cannot be expressed using any other combination of operations.&lt;/p>
&lt;p>My objective over the next few weeks is to reimagine the smart date picker’s data flow/dependency diagram by using FRP primitives. &lt;a href="https://github.com/SodiumFRP/sodium">Sodium&lt;/a>, the library I am using for this lesson, has ten FRP primitives. There isn’t enough space here to explain each one in detail (I recommend the book &lt;a href="https://www.manning.com/books/functional-reactive-programming">Functional Reactive Programming&lt;/a> for this purpose), but I will briefly introduce them as I go along.&lt;/p>
&lt;p>Today I start implementing the changes to the period type.&lt;/p></description><content type="html"><![CDATA[<p>I’ve faffed about at the fringes of functional reactive programming (FRP) for a while now, but I think it’s time to take a cold plunge into actually using some Sodium FRP primitives. FRP primitives are the fundamental operations (methods or functions) that make up the core of FRP. What makes them primitive is that they cannot be expressed using any other combination of operations.</p>
<p>My objective over the next few weeks is to reimagine the smart date picker’s data flow/dependency diagram by using FRP primitives. <a href="https://github.com/SodiumFRP/sodium">Sodium</a>, the library I am using for this lesson, has ten FRP primitives. There isn’t enough space here to explain each one in detail (I recommend the book <a href="https://www.manning.com/books/functional-reactive-programming">Functional Reactive Programming</a> for this purpose), but I will briefly introduce them as I go along.</p>
<p>Today I start implementing the changes to the period type.</p>
<h2 id="changing-the-period-type">Changing the Period Type</h2>
<p>This portion of the logic is concerned with how selecting one of the three period types (Weeks/Months/Quarters) registers a change in the Period Type cell, which then flows on to other parts of the program. You may wish to refer to the <a href="/smart-date-picker-requirements/">DFD</a> and <a href="/smart-date-picker-cells-and-streams/">cells/streams</a> breakdown covered in previous weeks.</p>
<p>First, we’ll have an <code>enum</code> called <code>PeriodType</code> which has three values: Weeks, Months, and Quarters. Each radio button, when clicked, will output its corresponding enum type. Because the click event is a stream, what we want to do is <strong>convert</strong> the stream of one type (a click event) to another (PeriodType). This is the basis of the <code>map()</code> primitive. For C# developers who have used LINQ, this is quite similar to the <a href="https://msdn.microsoft.com/en-us/library/bb384087.aspx"><code>select</code> clause</a>.</p>
<p>We then want to <strong>merge</strong> the three separate streams into a single stream that will update the cell <strong>holding</strong> the selected PeriodType. We do this using two aptly-named primitives <code>merge()</code> and <code>hold()</code>.</p>
<p><code>merge()</code> and its close sibling <code>orElse()</code> takes in as many streams as you need but outputs one stream. You provide a function to <code>merge()</code> that combines two streams in some way, whereas <code>orElse()</code> just takes the first stream that occurs. In our case, <code>orElse()</code> would do the job as users will only pick one of the three PeriodType options at a time.</p>
<p>Next, we use a <code>hold()</code> function to store the value passing through the stream as a cell. In this case, we are holding the selected PeriodType. This cell can then be used by other parts of the program such as generating a sales report.</p>
<h2 id="putting-it-together">Putting it together</h2>
<p>I’ve created a <a href="https://github.com/zemien/smart-date-picker">smart-date-picker repository on GitHub</a> for this exercise. They are organised in self-contained folders for each week and I invite you to do a checkout and run it for yourself. I have based it on the SWidgets custom controls that power the book samples, as they have added the necessary FRP hooks to the outside world. This leaves me free to focus on writing the FRP logic.</p>
<p>Check out the folder 01 - Period Type in GitHub. The relevant code bits I added in to a new WPF window are:</p>
<div class="highlight"><pre class="chroma"><code class="language-csharp" data-lang="csharp"><span class="k">public</span> <span class="n">MainWindow</span><span class="p">()</span>
<span class="p">{</span>
    <span class="n">InitializeComponent</span><span class="p">();</span>

    <span class="c1">//Wrap FRP initialisation code in a transaction
</span><span class="c1"></span>    <span class="n">Transaction</span><span class="p">.</span><span class="n">RunVoid</span><span class="p">(()</span> <span class="p">=&gt;</span>
    <span class="p">{</span>
        <span class="c1">//Create selection controls
</span><span class="c1"></span>        <span class="n">SButton</span> <span class="n">weeks</span> <span class="p">=</span> <span class="k">new</span> <span class="n">SButton</span> <span class="p">{</span> <span class="n">Content</span> <span class="p">=</span> <span class="s">&#34;Weeks&#34;</span><span class="p">,</span> <span class="n">Width</span> <span class="p">=</span> <span class="m">75</span> <span class="p">};</span>
        <span class="n">SButton</span> <span class="n">months</span> <span class="p">=</span> <span class="k">new</span> <span class="n">SButton</span> <span class="p">{</span> <span class="n">Content</span> <span class="p">=</span> <span class="s">&#34;Months&#34;</span><span class="p">,</span> <span class="n">Width</span> <span class="p">=</span> <span class="m">75</span><span class="p">,</span> <span class="n">Margin</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Thickness</span><span class="p">(</span><span class="m">5</span><span class="p">,</span> <span class="m">0</span><span class="p">,</span> <span class="m">0</span><span class="p">,</span> <span class="m">0</span><span class="p">)</span> <span class="p">};</span>
        <span class="n">SButton</span> <span class="n">quarters</span> <span class="p">=</span> <span class="k">new</span> <span class="n">SButton</span> <span class="p">{</span> <span class="n">Content</span> <span class="p">=</span> <span class="s">&#34;Quarters&#34;</span><span class="p">,</span> <span class="n">Width</span> <span class="p">=</span> <span class="m">75</span><span class="p">,</span> <span class="n">Margin</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Thickness</span><span class="p">(</span><span class="m">5</span><span class="p">,</span> <span class="m">0</span><span class="p">,</span> <span class="m">0</span><span class="p">,</span> <span class="m">0</span><span class="p">)</span> <span class="p">};</span>

        <span class="c1">//Convert click event streams into PeriodType streams
</span><span class="c1"></span>        <span class="n">Stream</span><span class="p">&lt;</span><span class="n">PeriodType</span><span class="p">&gt;</span> <span class="n">sWeeks</span> <span class="p">=</span> <span class="n">weeks</span><span class="p">.</span><span class="n">SClicked</span><span class="p">.</span><span class="n">Map</span><span class="p">(</span><span class="n">_</span> <span class="p">=&gt;</span> <span class="n">PeriodType</span><span class="p">.</span><span class="n">Weeks</span><span class="p">);</span>
        <span class="n">Stream</span><span class="p">&lt;</span><span class="n">PeriodType</span><span class="p">&gt;</span> <span class="n">sMonths</span> <span class="p">=</span> <span class="n">months</span><span class="p">.</span><span class="n">SClicked</span><span class="p">.</span><span class="n">Map</span><span class="p">(</span><span class="n">_</span> <span class="p">=&gt;</span> <span class="n">PeriodType</span><span class="p">.</span><span class="n">Months</span><span class="p">);</span>
        <span class="n">Stream</span><span class="p">&lt;</span><span class="n">PeriodType</span><span class="p">&gt;</span> <span class="n">sQuarters</span> <span class="p">=</span> <span class="n">quarters</span><span class="p">.</span><span class="n">SClicked</span><span class="p">.</span><span class="n">Map</span><span class="p">(</span><span class="n">_</span> <span class="p">=&gt;</span> <span class="n">PeriodType</span><span class="p">.</span><span class="n">Quarters</span><span class="p">);</span>

        <span class="c1">//Merge the streams into a single stream with orElse
</span><span class="c1"></span>        <span class="n">Stream</span><span class="p">&lt;</span><span class="n">PeriodType</span><span class="p">&gt;</span> <span class="n">sPeriodType</span> <span class="p">=</span> <span class="n">sWeeks</span><span class="p">.</span><span class="n">OrElse</span><span class="p">(</span><span class="n">sMonths</span><span class="p">).</span><span class="n">OrElse</span><span class="p">(</span><span class="n">sQuarters</span><span class="p">);</span>

        <span class="c1">//Hold a value of the stream in a cell, and also specifies Weeks as the default value
</span><span class="c1"></span>        <span class="n">Cell</span><span class="p">&lt;</span><span class="n">PeriodType</span><span class="p">&gt;</span> <span class="n">cPeriodTypeCell</span> <span class="p">=</span> <span class="n">sPeriodType</span><span class="p">.</span><span class="n">Hold</span><span class="p">(</span><span class="n">PeriodType</span><span class="p">.</span><span class="n">Weeks</span><span class="p">);</span>

        <span class="c1">//Display the contents of the cell by mapping it to a string that SLabel can display
</span><span class="c1"></span>        <span class="n">Cell</span><span class="p">&lt;</span><span class="kt">string</span><span class="p">&gt;</span> <span class="n">cPeriodTypeString</span> <span class="p">=</span> <span class="n">cPeriodTypeCell</span><span class="p">.</span><span class="n">Map</span><span class="p">(</span><span class="n">p</span> <span class="p">=&gt;</span> <span class="n">p</span><span class="p">.</span><span class="n">ToString</span><span class="p">());</span>
        <span class="n">SLabel</span> <span class="n">lbl</span> <span class="p">=</span> <span class="k">new</span> <span class="n">SLabel</span><span class="p">(</span><span class="n">cPeriodTypeString</span><span class="p">)</span> <span class="p">{</span> <span class="n">Width</span> <span class="p">=</span> <span class="m">75</span><span class="p">,</span> <span class="n">Margin</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Thickness</span><span class="p">(</span><span class="m">5</span><span class="p">,</span> <span class="m">0</span><span class="p">,</span> <span class="m">0</span><span class="p">,</span> <span class="m">0</span><span class="p">)</span> <span class="p">};</span>

        <span class="c1">//Add controls to WPF StackPanel container
</span><span class="c1"></span>        <span class="n">Container</span><span class="p">.</span><span class="n">Children</span><span class="p">.</span><span class="n">Add</span><span class="p">(</span><span class="n">weeks</span><span class="p">);</span>
        <span class="n">Container</span><span class="p">.</span><span class="n">Children</span><span class="p">.</span><span class="n">Add</span><span class="p">(</span><span class="n">months</span><span class="p">);</span>
        <span class="n">Container</span><span class="p">.</span><span class="n">Children</span><span class="p">.</span><span class="n">Add</span><span class="p">(</span><span class="n">quarters</span><span class="p">);</span>
        <span class="n">Container</span><span class="p">.</span><span class="n">Children</span><span class="p">.</span><span class="n">Add</span><span class="p">(</span><span class="n">lbl</span><span class="p">);</span>
    <span class="p">});</span>
<span class="p">}</span>
</code></pre></div><p>I relied heavily on the book’s RedGreen sample project and SWidgets library to build this. You should note that I have used the provided SButton component instead of implementing my own Sodium-enabled radio button because I want to keep my code simple for now. Nevertheless, they operate the same despite some visual differences.</p>
<p>It looks very different from the usual OOP code one would normally write. I have to say that it does read quite logically from top to bottom when laid out using FRP primitives. The best part? No mutable PeriodType property that can get accidentally overridden without our explicit permission.</p>
<h2 id="next-week">Next Week</h2>
<p>I will go through a similar exercise with expressing the date pickers and data availability dates using FRP primitives, before combining them together in the following weeks. Comments, questions, and corrections are always welcome.</p>
<p><em>This is part of an ongoing series where I review the book</em><a href="https://www.manning.com/books/functional-reactive-programming"> <em>Functional Reactive Programming by Stephen Blackheath and Anthony Jones</em></a><em>. Kindly note that anything I write here may be incorrect and not indicative of the author’s intent. After all, making mistakes is the mother of learning and this book review is meant to be a truthful reflection of my own experiences grasping a new concept. The review copy I received was version 11 in their Manning’s Early Access Program, so the book’s contents may differ at the time of publication.</em></p>]]></content></item><item><title>Smart Date Picker: Cells and Streams</title><link>https://www.coderfrontline.com/smart-date-picker-cells-and-streams/</link><pubDate>Sun, 10 Jul 2016 13:43:58 +1200</pubDate><guid>https://www.coderfrontline.com/smart-date-picker-cells-and-streams/</guid><description>&lt;p>I covered the &lt;a href="https://www.coderfrontline.com/smart-date-picker-requirements/">requirements of the smart date picker&lt;/a> in my last post, which ended with a data flow diagram. Today I aim to translate that conceptual view to primitives within &lt;a href="https://github.com/SodiumFRP/sodium">Sodium, a functional reactive programming (FRP) library&lt;/a> supported on multiple languages. The only types in Sodium are Cells and Streams. I will attempt to provide a brief explanation.&lt;/p></description><content type="html"><![CDATA[<p>I covered the <a href="/smart-date-picker-requirements/">requirements of the smart date picker</a> in my last post, which ended with a data flow diagram. Today I aim to translate that conceptual view to primitives within <a href="https://github.com/SodiumFRP/sodium">Sodium, a functional reactive programming (FRP) library</a> supported on multiple languages. The only types in Sodium are Cells and Streams. I will attempt to provide a brief explanation.</p>
<h2 id="cells">Cells</h2>
<p>In essence, a Cell is a value that changes over time. Specifically, it is a generic type Cell<T> that can contain almost any type you specify. Other FRP systems might call it a Behavior, Property or a Signal.</p>
<p>The reason Sodium calls it a Cell is because it is conceptually similar to a cell in a spreadsheet. Individual cells in a spreadsheet contain a value but they are not constant. They can change over time, especially in response to changes in other parts of the workbook. Let me illustrate that with Excel’s personal budget template:</p>
<p><img class="alignnone wp-image-187 size-large" src="/wp-content/uploads/sites/2/2016/07/personal-budget-template-1.png" alt="personal-budget-template-1" width="640" height="439" srcset="/wp-content/uploads/sites/2/2016/07/personal-budget-template-1.png 1024w, /wp-content/uploads/sites/2/2016/07/personal-budget-template-1.png 300w, /wp-content/uploads/sites/2/2016/07/personal-budget-template-1.png 768w" sizes="(max-width: 640px) 100vw, 640px" /></p>
<p>This is a simple template where you can put in your income, expenses, and savings. It then shows you a summary for the month with a chart and totals. Let’s trace the precedents and dependents of the Total Monthly Income cell:</p>
<p><img class="alignnone size-large wp-image-188" src="/wp-content/uploads/sites/2/2016/07/personal-budget-template-2.png" alt="personal-budget-template-2" width="640" height="446" srcset="/wp-content/uploads/sites/2/2016/07/personal-budget-template-2.png 1024w, /wp-content/uploads/sites/2/2016/07/personal-budget-template-2.png 300w, /wp-content/uploads/sites/2/2016/07/personal-budget-template-2.png 768w" sizes="(max-width: 640px) 100vw, 640px" /></p>
<p>It is straightforward. Total Monthly Income is a <strong>function</strong> that sums up all income sources, and its result is in turn used by the Cash Balance cell to determine how much extra you have left in your bank account. It is also used by the chart data to construct a delicious pie chart. See what happend when I add a new line of income:</p>
<p><img class="alignnone size-large wp-image-189" src="/wp-content/uploads/sites/2/2016/07/personal-budget-template-3.png" alt="personal-budget-template-3" width="640" height="451" srcset="/wp-content/uploads/sites/2/2016/07/personal-budget-template-3.png 1024w, /wp-content/uploads/sites/2/2016/07/personal-budget-template-3.png 300w, /wp-content/uploads/sites/2/2016/07/personal-budget-template-3.png 768w" sizes="(max-width: 640px) 100vw, 640px" /></p>
<p>When I do that, the Total Monthly Income, Cash Balance, and pie chart are all updated <strong>simultaneously</strong>. There is no need to manually recalculate because Excel knows the <strong>dependency</strong> between the cells and so knows the correct order to update them.</p>
<p>This brings us to the concept of Streams.</p>
<h2 id="streams">Streams</h2>
<p>A Stream<T> in the world of Sodium represents a “stream of events”. A single mouse click on a button is an event, but multiple mouse clicks on the button throughout the program life cycle would be represented by a stream of mouse clicks.</p>
<p>I find it easiest to think of a Stream as an event handler/listener. I’m sure there are differences between them but I view it as a functional event handler that plugs in to the rest of the Sodium framework. Realistically, one would provide a function that executes when the specified stream fires. This is no different from writing an event handler method but with the added ability to work with Cells and other Sodium primitive operations.</p>
<p>I believe it is called a Stream like the body of water that continuously meanders across the earth. Similarly, a Stream<T> event flows through the program and creates a ripple of changes. In the spreadsheet example above it is logical to conceive of my user input as a stream that leads to other cells being updated.</p>
<h2 id="smart-date-picker">Smart Date Picker</h2>
<p>So what are the Cells and Streams of the smart date picker I am trying to implement? I would look at the data flow diagram I created last week and ponder upon what values are being held and what sources of events are present.</p>
<p><img class="size-large wp-image-177" src="/wp-content/uploads/sites/2/2016/07/Smart-Date-Picker-Data-Flow.png" alt="Smart Date Picker Data Flow Diagram" width="640" height="564" srcset="/wp-content/uploads/sites/2/2016/07/Smart-Date-Picker-Data-Flow.png 1024w, /wp-content/uploads/sites/2/2016/07/Smart-Date-Picker-Data-Flow.png 300w, /wp-content/uploads/sites/2/2016/07/Smart-Date-Picker-Data-Flow.png 768w" sizes="(max-width: 640px) 100vw, 640px" /></p>
<p>At a theoretical level, I think they would be:</p>
<p>Cells:</p>
<ul>
<li>Data Availability Dates</li>
<li>Period Type (whether it is Weeks, Months, or Quarters)</li>
<li>Date Range (the selected start and end date for the report)</li>
</ul>
<p>Streams:</p>
<ul>
<li>Select Weeks</li>
<li>Select Months</li>
<li>Select Quarters</li>
<li>Select Start Date</li>
<li>Select End Date</li>
</ul>
<p>You might have noticed a few omissions in my cells and streams. I did not put Start Date and End Date as a Cell because ultimately the date pickers are only sources of events. Whatever the user picks are merely a suggestion. The date bumping logic still needs to decide if it is valid, which then updates the date picker and the Date Range cell with the final outcome.</p>
<p>Changes in Data Availability Dates might resemble a Stream, but I did not model it as one because the changes are initiated from outside the application, i.e. database updates. There is a strict requirement of <strong>referential transparency</strong> in Sodium, which means:</p>
<ul>
<li>you must not perform any I/O;</li>
<li>you must not throw any exceptions unless they are caught and handled within the  function;</li>
<li>you must not read the value of any external variable if its value can change, but  constants are allowed and encouraged;</li>
<li>you must not modify any externally visible state;</li>
<li>you must not keep any state between invocations of the function;</li>
</ul>
<p>(The above list is excerpted from the <a href="https://www.manning.com/books/functional-reactive-programming">book Functional Reactive Programming</a>)</p>
<p>Because checking the Data Availability Dates would require I/O (query the DB), it needs to be done outside of FRP. I know you’re asking: How would one integrate FRP into an application that needs to do I/O and throw exceptions? That is a question I have often asked myself as I read the book but the authors insist on keeping those details under wraps until halfway through the book in Chapter 8. This is done under the guise of keeping the reader’s mind ‘pure’ in FRP-Land before the messy reality of integration hits. I have not formed an opinion regarding this approach yet as I’m still reading the book, but will return to this later.</p>
<p>My list of cells and streams for the smart date picker might change as I start implementing it and discover better ways of looking at the problem. Next week: I will write about some of the operational primitives I may need in Sodium to transform cells and streams from one form to another.</p>
<p><em>This is part of an ongoing series where I review the book</em><a href="https://www.manning.com/books/functional-reactive-programming"> <em>Functional Reactive Programming by Stephen Blackheath and Anthony Jones</em></a><em>. Kindly note that anything I write here may be incorrect and not indicative of the author’s intent. After all, making mistakes is the mother of learning and this book review is meant to be a truthful reflection of my own experiences grasping a new concept. The review copy I received was version 11 in their Manning’s Early Access Program, so the book’s contents may differ at the time of publication.</em></p>]]></content></item><item><title>Smart Date Picker: Requirements and Test Cases</title><link>https://www.coderfrontline.com/smart-date-picker-requirements-and-test-cases/</link><pubDate>Sat, 02 Jul 2016 22:49:16 +1200</pubDate><guid>https://www.coderfrontline.com/smart-date-picker-requirements-and-test-cases/</guid><description>&lt;p>I hinted three weeks ago that I wished to &lt;a href="https://www.coderfrontline.com/events-are-evil/">learn functional reactive programming&lt;/a> by implementing a smart date picker. Since then I shared my &lt;a href="https://www.coderfrontline.com/first-impressions-functional-reactive-programming-sodium/">impressions on the book&lt;/a> but have yet to delve into actually working on the control. I haven&amp;rsquo;t had much time to read the book (curse you, Uncharted 4), and so I am still a bit clueless about where to start. It&amp;rsquo;s time to take the plunge though, and I will outline my stumbles through thinking about business requirements from a data perspective. In this post I flesh out the requirements and test cases a bit more and think about how they rely on each other.&lt;/p></description><content type="html"><![CDATA[<p>I hinted three weeks ago that I wished to <a href="/events-are-evil/">learn functional reactive programming</a> by implementing a smart date picker. Since then I shared my <a href="/first-impressions-functional-reactive-programming-sodium/">impressions on the book</a> but have yet to delve into actually working on the control. I haven&rsquo;t had much time to read the book (curse you, Uncharted 4), and so I am still a bit clueless about where to start. It&rsquo;s time to take the plunge though, and I will outline my stumbles through thinking about business requirements from a data perspective. In this post I flesh out the requirements and test cases a bit more and think about how they rely on each other.</p>
<h2 id="requirements">Requirements</h2>
<p>Let&rsquo;s first revisit the smart date picker itself and explain the requirements a bit more. It looks something like this:<figure id="attachment_148" style="width: 300px" class="wp-caption aligncenter"></p>
<p><img class="size-medium wp-image-148" src="/wp-content/uploads/sites/2/2016/06/Smart-Date-Picker.png" alt="Smart date picker" width="300" height="153" srcset="/wp-content/uploads/sites/2/2016/06/Smart-Date-Picker.png 300w, /wp-content/uploads/sites/2/2016/06/Smart-Date-Picker.png 570w" sizes="(max-width: 300px) 100vw, 300px" /><figcaption class="wp-caption-text">Smart Date Picker</figcaption></figure></p>
<p>This control is used as part of a larger data reporting app. Users select how they wish to view the data – by weeks, months, or calendar quarters. They then pick the dates they wish to run the report for. The start and end dates will automatically adjust (also known as bumping) to ensure a valid report range. Specifically, weeks will always be Sunday to Saturday, months will always go from the first to the end of a month, and quarters will go from the first of a quarter to the end of another quarter.</p>
<h2 id="test-cases">Test Cases</h2>
<p>Here are some test cases (dates in dd/MM/yy):</p>
<ol>
<li>By weeks: Currently showing 12/06/16 (Sunday) to 18/06/16 (Saturday)
<ol>
<li>Change start date to 29/06/16 (Sunday). It now shows 29/05/16 to 18/06/16.</li>
<li>Change start date to 01/06/16 (Wednesday). It now shows 29/05/16 to 18/06/16.</li>
<li>Change start date to 27/06/16 (Monday). It now shows 26/06/16 to 02/07/16 (bumps both date to ensure a valid range).</li>
</ol>
</li>
<li>By months: Currently showing 01/06/16 (first of the month) to 30/06/16 (last of the month).
<ol>
<li>Change end date to 27/06/16. It now shows 01/06/16 to 30/06/16 (no change).</li>
<li>Change end date to 31/07/16. It now shows 01/06/16 to 31/07/16.</li>
<li>Change end date to 28/02/16. It now shows 01/02/16 to 29/02/16.</li>
</ol>
</li>
<li>By quarters: Currently showing 01/01/16 (first day of quarter 1) to 30/06/16 (last day of quarter 2).
<ol>
<li>Change start date to 15/03/16. It now shows 01/01/16 to 30/06/16 (no change).</li>
<li>Change end date to 15/03/16. It now shows 01/01/16 to 31/03/16.</li>
<li>Change start date to 01/10/16. It now shows 01/10/16 to 31/12/16.</li>
</ol>
</li>
</ol>
<p>An additional constraint to the basic rules is the amount of data available. It can only show dates for when data can be reported, and bump dates as necessary. The requirements state that this comes from a SQL query, but for the purposes of this exercise, it will be mocked to only have data for 2016.</p>
<p>Extending the test cases above for data availability 01/01/16 to 31/12/16:</p>
<ol>
<li>By weeks: Currently showing 12/06/16 (Sunday) to 18/06/16 (Saturday) <ol start="4">
 <li>
   Change end date to 15/02/17. It now shows 12/06/16 to 31/12/16 (Saturday).
 </li>
 <li>
   Change start date to 15/02/17. It now shows 25/12/16 (Sunday) to 31/12/16 (Saturday).
 </li>
</li>
</ol>
<pre><code>&lt;/ol&gt;
</code></pre>
<ol start="2">
<li>By months: Currently showing 01/06/16 (first of the month) to 30/06/16 (last of the month). <ol start="4">
 <li>
   Change start date to 15/02/17. It now shows 01/12/16 to 31/12/16.
 </li>
 <li>
   Change end date to 20/12/15. It now shows 01/01/16 to 31/01/16.
 </li>
</li>
</ol>
<pre><code>&lt;/ol&gt;
</code></pre>
<ol start="3">
<li>By quarters: Currently showing 01/01/16 (first day of quarter 1) to 30/06/16 (last day of quarter 2). <ol start="4">
 <li>
   Change end date to 15/05/15. It now shows 01/01/16 to 31/03/16.
 </li>
 <li>
   Change start date to 23/08/17. It now shows 01/10/16 to 31/12/16.
 </li>
</li>
</ol>
<pre><code>&lt;/ol&gt;
</code></pre>
<p>There are cases where there wouldn’t be enough data to create a valid range. In those instances, it stops bumping and selects the minimum or maximum date of the data availability.</p>
<p>Tests might look like this:</p>
<ol start="4">
  <li>
    Control currently set to Weeks and showing 12/06/16 to 18/06/16. Data only available for 05/06/16 to 30/08/16. <ol>
      <li>
        The user changes to Quarterly reporting. It now shows 05/06/16 to 30/06/16 even though it is not a whole quarter because that is the most valid it can get.
      </li>
      <li>
        The user changes to Monthly reporting. It now shows 05/06/16 to 30/06/16.
      </li>
    </ol>
  </li>
</ol>
<h2 id="data-and-dependencies">Data and Dependencies</h2>
<p>Those are the general requirements of the smart date picker. I have implemented this in regular C# WPF MVVM architecture, but it produced hard-to-understand code and I ran into issues with some edge cases. I now want to see how it might look like if I redid it using FRP.</p>
<p>A key difference with functional-style programming is the focus on thinking about the problem in terms of how data depends on each other, and then declaring those relationships in code. This contrasts wildly from traditional imperative-style programming where we tell the computer what we want to do and how to do it.</p>
<p>It’s been hard grasping FRP concepts because it required me to change my paradigm from thinking about the sequence of events to just focusing on how data relates to each other. I still remember trying to learn object-oriented programming in uni. It threw me into a mental loop because I had been happy using Visual Basic and couldn’t understand why coding objects was “better” than coding modules and forms. And one day I just got it. I suspect the same struggle lies ahead.</p>
<p>So the first baby step towards thinking in the “problem space”, as the FRP book authors put it, is to map out the data and how they depend on each other. This exercise is surprisingly rare in modern OOP programming even though it’s a logical next step after you have the requirements. Instead, TDD/BDD practitioners jump straight into crafting unit tests that map to requirements, while others segue into defining a sequence of events.</p>
<p>The data and dependency diagram for the smart date picker might look something like this:<figure id="attachment_177" style="width: 600px" class="wp-caption aligncenter"></p>
<p><img class="size-medium wp-image-177" src="/wp-content/uploads/sites/2/2016/07/Smart-Date-Picker-Data-Flow.png" alt="Smart Date Picker Data Flow Diagram" width="600" height="530" srcset="/wp-content/uploads/sites/2/2016/07/Smart-Date-Picker-Data-Flow.png 300w, /wp-content/uploads/sites/2/2016/07/Smart-Date-Picker-Data-Flow.png 768w, /wp-content/uploads/sites/2/2016/07/Smart-Date-Picker-Data-Flow.png 1024w" sizes="(max-width: 600px) 100vw, 600px" /><figcaption class="wp-caption-text">Smart Date Picker Data Flow Diagram</figcaption></figure></p>
<p>Consider the above a first draft. I might move things around as I understand more FRP.</p>
<p><em>This is part of an ongoing series where I review the book <a href="https://www.manning.com/books/functional-reactive-programming">Functional Reactive Programming by Stephen Blackheath and Anthony Jones</a>. Kindly note that anything I write here may be incorrect and not indicative of the author’s intent. After all, making mistakes is the mother of learning and this book review is meant to be a truthful reflection of my own experiences grasping a new concept. The review copy I received was version 11 in their Manning’s Early Access Program, so the book’s contents may differ at the time of publication.</em></p>
<p>Photo credit: <a href="https://www.flickr.com/photos/henk-sijgers">henk.sijgers (on when I can)</a> via <a href="https://visualhunt.com/photos/city/">VisualHunt</a> / <a href="http://creativecommons.org/licenses/by-nc/2.0/">CC BY-NC</a></p>]]></content></item><item><title>More Impressions Functional Reactive Programming with Sodium</title><link>https://www.coderfrontline.com/more-impressions-functional-reactive-programming-with-sodium/</link><pubDate>Sun, 26 Jun 2016 12:27:09 +1200</pubDate><guid>https://www.coderfrontline.com/more-impressions-functional-reactive-programming-with-sodium/</guid><description>I shared a couple of my first impressions reading the Functional Reactive Programming book, and I am back with more after going a bit further with the book. I am spending this weekend in beautiful Queenstown, New Zealand for the Queenstown Winter Festival so this post is shorter than usual.
Book Organisation This book is not a ‘cookbook’ – it is not a collection of code recipes you can read and then easily apply in your code.</description><content type="html"><![CDATA[<p>I shared a couple of my <a href="/first-impressions-functional-reactive-programming-sodium/">first impressions reading the Functional Reactive Programming</a> book, and I am back with more after going a bit further with the book. I am spending this weekend in beautiful Queenstown, New Zealand for the <a href="http://www.winterfestival.co.nz/">Queenstown Winter Festival</a> so this post is shorter than usual.</p>
<h2 id="book-organisation">Book Organisation</h2>
<p>This book is not a ‘cookbook’ – it is not a collection of code recipes you can read and then easily apply in your code.</p>
<p>This book is not a ‘For Dummies’ or ‘Learn <em>xyz</em> in 24 Hours’ book – it is not partitioned into bite-sized chapters that are equally spaced out.</p>
<p>I would place this book in the intersection between a textbook and a reference book. It is trying to evangelise new concepts and frameworks via large examples, like a textbook. It is also organised in a way that makes it easy to jump back at a later stage to refresh one’s memory, as the core concepts are contained within a single chapter (the previously-mentioned dense Chapter 2).</p>
<p>The chapters themselves interchange between theoretical chapters and coding example chapters. The note in Chapter 4 summarises my thoughts perfectly:</p>
<blockquote>
<p>“This chapter is quite dense, and we think it will repay any effort you spend on it, but there is no reason why you have to study it all closely now. If it fits your learning style, feel free to read parts of it briefly then carry on with the book and come back to it later.”</p>
</blockquote>
<p>I think this note is equally applicable to the entire book. I wish to clarify that this is not necessarily a negative aspect – the big concepts in life sometimes need a few read throughs to be able to grasp. Do I <em>wish</em> that it was easier to learn? Yes.</p>
<p>Pro Tip: A lecturer friend of mine once shared his secret to quickly reading lots of academic papers. He scans the executive summary at the front, then jumps to the conclusion at the back to pick out the main gist of the paper. He then reads the main content if he decides there is something worthwhile about it. This tip is very much relevant here. There have been many times that I found the concepts easier to comprehend once I scanned the summary.</p>
<p>Think of it as a journey: the introduction describes the destination, while the chapter summary describes the journey you were on. Reading these two parts first make the journey itself more enjoyable as your eyes are peeled to spot the landmarks coming up.</p>
<h2 id="writing-style">Writing Style</h2>
<p>Thankfully, this is not a dry text. The writing style is quite conversational at times, as if you are reading a series of blog posts. There is also friendly jabbing between the co-authors, almost like the editor’s notes in newspaper articles. Jokes are strewn sparingly around – some clever and some cringey. It definitely helps lighten the mood.</p>
<p>On the downside, jokes sometimes distract from the learning at hand. Here’s an example from Chapter 2. A note after the explanation of the map primitive said:</p>
<blockquote>
<p>“When my co-author says “more generally” he is invariably trying to trick you into learning functional programming. Don’t fall for it. You can ignore these parts and focus on the examples.”</p>
</blockquote>
<p>Here I was in a serious headspace trying to digest all these new concepts of cells and streams, how streams are like events (but not exactly), how the map primitive transforms streams… and suddenly here’s a jibe about ignoring parts of what I just read. It broke the flow – and I certainly wasn’t laughing. A good joke is as much about timing as it is about the punchline.</p>
<p>Pro Tip: Most of the notes in this book are meta. I would recommend ignoring them on your first read through.</p>
<p><em>This is part of an ongoing series where I review the book <a href="https://www.manning.com/books/functional-reactive-programming">Functional Reactive Programming by Stephen Blackheath and Anthony Jones</a>. Kindly note that anything I write here may be incorrect and not indicative of the author’s intent. After all, making mistakes is the mother of learning and this book review is meant to be a truthful reflection of my own experiences grasping a new concept. The review copy I received was version 11 in their Manning’s Early Access Program, so the book’s contents may differ at the time of publication.</em></p>
<p>Photo credit: <a href="https://www.flickr.com/photos/henk-sijgers/15993053766/">henk.sijgers (on when I can)</a> via <a href="https://visualhunt.com/photos/city/">VisualHunt</a> / <a href="http://creativecommons.org/licenses/by-nc/2.0/">CC BY-NC</a></p>
]]></content></item><item><title>First Impressions Functional Reactive Programming with Sodium</title><link>https://www.coderfrontline.com/first-impressions-functional-reactive-programming-with-sodium/</link><pubDate>Sun, 19 Jun 2016 12:26:07 +1200</pubDate><guid>https://www.coderfrontline.com/first-impressions-functional-reactive-programming-with-sodium/</guid><description>This is part of an ongoing series where I review the book Functional Reactive Programming by Stephen Blackheath and Anthony Jones. Kindly note that anything I write here may be incorrect and not indicative of the author’s intent. After all, making mistakes is the mother of learning and this book review is meant to be a truthful reflection of my own experiences grasping a new concept. The review copy I received was version 11 in their Manning’s Early Access Program, so the book’s contents may differ at the time of publication.</description><content type="html"><![CDATA[<p><em>This is part of an ongoing series where I review the book <a href="https://www.manning.com/books/functional-reactive-programming">Functional Reactive Programming by Stephen Blackheath and Anthony Jones</a>. Kindly note that anything I write here may be incorrect and not indicative of the author’s intent. After all, making mistakes is the mother of learning and this book review is meant to be a truthful reflection of my own experiences grasping a new concept. The review copy I received was version 11 in their Manning’s Early Access Program, so the book’s contents may differ at the time of publication.</em></p>
<p>With that pseudo-disclaimer out of the way, I wanted to share my first impressions of the book’s writing style and organisation. I mentioned last week how I <a href="/events-are-evil/">stumbled upon Functional Reactive Programming (FRP)</a> and wanted to try implementing a “smart date picker”. I’m just on Chapter 4 and am not ready to start working on that yet. Instead here are some quick-fire thoughts of the book so far:</p>
<h2 id="what-is-functional-reactive-programming">What is Functional Reactive Programming?</h2>
<p>This is a comparatively young field and so I appreciate that you, dear reader, may not be familiar with this concept. You’re not alone – neither do I! Instead of trying to come up with a definition that will most certainly be incorrect, I encourage readers to check out the first chapter of this book (<a href="https://www.manning.com/books/functional-reactive-programming">see the sidebar</a>). It is free to read and gives a comprehensive overview of where the book aims to take you.</p>
<h2 id="sodium-frp-and-java">Sodium FRP and Java</h2>
<p>The authors of the book created their own <a href="https://github.com/SodiumFRP/sodium">BSD-licensed FRP library called Sodium</a>, which is implemented in several languages including Java and .Net. The book itself uses Sodium and Java as the main instructional vehicles, even though the concepts should be applicable to other languages and similar FRP libraries. However, my own background as a C# .Net developer makes things slightly less pleasant. While there are many similarities between Java and C#, the differences are like tiny stones stuck in my shoe. Not painful enough to stop walking, but a niggling nuisance nonetheless. Consequently, I find the code samples to be quite verbose from what I’m used to, and I have yet to identify which parts are verbose because of FRP and which are just Java’s eccentricities.</p>
<p>Pro Tip: The <a href="https://github.com/SodiumFRP/sodium/tree/master/book">book samples</a> are also implemented in C#, which are all part of the GitHub project. I would recommend running the C# examples instead of the Java ones from the book. If you’re so inclined.</p>
<h2 id="target-audience">Target Audience</h2>
<p>This book is targeted towards “programmers familiar with object oriented programming. No prior knowledge of functional programming is needed.” That fits my profile almost perfectly. This is by no means a “For Dummies” book though. It is not ashamed to throw readers like myself in the deep-end, and then stand and laugh as I fumble to stay afloat.</p>
<p>OK, that last line was a tad melodramatic. I’m only mildly exaggerating of course. While Chapter 1 was a gentle introduction into what FRP is and isn’t, Chapter 2 dives into the primitives that make up an FRP system. I appreciate the use of examples and diagrams to illustrate new concepts such as cells and streams, but I always feel like I am missing something due to a lack of prior functional programming experience.</p>
<p>There is no time to catch my breath though as the hits keep coming with one concept after another. Looking back, this is one of the densest Chapter 2 of any book I’ve read. This either says something about the depth of this book, or the shallowness of my mind. Take it how you will.</p>
<p>Pro Tip: Having <em>some</em> awareness of what functional programming is will absolutely help readers understand this book better.</p>
<p>I will continue sharing more impressions about this book next week and hopefully start working on my date picker widget.</p>
<div class="subsection subsection-embed">
  Photo credit: <a href="https://www.flickr.com/photos/henk-sijgers/15625028439/">henk.sijgers (on when I can)</a> via <a href="https://visualhunt.com/photos/city/">Visual hunt</a> / <a href="http://creativecommons.org/licenses/by-nc/2.0/">CC BY-NC</a>
</div>]]></content></item><item><title>Events Are Evil</title><link>https://www.coderfrontline.com/events-are-evil/</link><pubDate>Sun, 12 Jun 2016 12:57:28 +1200</pubDate><guid>https://www.coderfrontline.com/events-are-evil/</guid><description>&lt;p>Events are evil. Yes, that is quite the incendiary statement to make. To clarify, I don’t mean events in the physical world like rock concerts and art festivals. I am referring to the common event handling patterns most programmers are familiar with, such as button click event handlers and JavaScript callbacks. They are popular because they are simple to set up – most languages support some form of asynchronous event handling out of the box. However, its prevalence does not mean it is perfect, and I have recently come across a different event handling paradigm that promises to rehabilitate events.&lt;/p></description><content type="html"><![CDATA[<p>Events are evil. Yes, that is quite the incendiary statement to make. To clarify, I don’t mean events in the physical world like rock concerts and art festivals. I am referring to the common event handling patterns most programmers are familiar with, such as button click event handlers and JavaScript callbacks. They are popular because they are simple to set up – most languages support some form of asynchronous event handling out of the box. However, its prevalence does not mean it is perfect, and I have recently come across a different event handling paradigm that promises to rehabilitate events.</p>
<p>I first heard about Functional Reactive Programming last month at an <a href="/techweek-akl-2016/">Techweek AKL</a> event. The blurb went like this:</p>
<blockquote>
<p>“Event-based application logic is a special challenge with today&rsquo;s ever greater demands on the programmer&rsquo;s art. Functional programming (FP) is a powerful general approach that uses composability to tame application complexity, but event handling has remained tricky. Functional Reactive Programming (FRP) applies functional methods to transform the event handling problem.”</p>
</blockquote>
<p>I’ve certainly experienced my fair share of event handling angst. One of my most recent descent into event handling hell is to implement a pair of smart date pickers that look something like this:<figure id="attachment_148" style="width: 300px" class="wp-caption aligncenter"></p>
<p><img class="wp-image-148 size-medium" src="/wp-content/uploads/sites/2/2016/06/Smart-Date-Picker.png" alt="Smart date picker" width="300" height="153" srcset="/wp-content/uploads/sites/2/2016/06/Smart-Date-Picker.png 300w, /wp-content/uploads/sites/2/2016/06/Smart-Date-Picker.png 570w" sizes="(max-width: 300px) 100vw, 300px" /><figcaption class="wp-caption-text">Smart Date Picker Mockup</figcaption></figure></p>
<p>The user picks the date range that they would like a report for. They can constrain it by weeks, months, or financial quarters. The date pickers obey that setting, e.g. if the user is reporting on months, selecting 5 August as the start date will bump it to 1 August. To add another layer of complexity, the user is constrained to picking dates that the system has data for. For example, if the system only has data beginning 3 August, the date picker would be fixed at 3 August even though it wanted to select the first of the month.</p>
<p>Sounds simple? It started innocently enough but bugs started appearing when unexpected combinations were selected. A big component of the date bumping process is the date picker change event handler that tries to maintain a valid date range. The start date picker’s change event handler can change the end date, which would trigger the end date’s own event handler, which may change the start date, which would trigger the… (and so on and so forth). To avoid an infinite loop, an ‘amnesty’ is used to break the loop, which may leave the date pickers with an invalid range.</p>
<p>Debugging was also a pain as change event handlers could be triggered from multiple sources, and it’s not clear which event path is ‘correct’. It’s now in a stable state, but god forbid I have to troubleshoot it again!</p>
<p>That digression serves to illustrate why I was intrigued and went along to the <a href="http://www.meetup.com/Functional-Programming-Auckland/">Functional Programming Auckland Meetup</a> on FRP. Stephen Blackheath did a quick-fire demo, implementing a block stacking game in Java using FRP. I will admit that most of the demo flew over my head, as Stephen launched into the code with very little exposition. That is partly due to time constraints and the audience (who are mainly functional programmers familiar with the ‘functional’ way). My experience with functional constructs is limited to C#’s lambda expressions, which I find very useful but not sufficient enough for me to follow along with his demo.</p>
<p>Of course, one does not need to understand the intricacies of classical art to appreciate the Mona Lisa. So it is with FRP. I was curious about what Functional Reactive Programming might herald, and I was determined to learn more. I approached Stephen during post-event drinks and I offered to review his upcoming <a href="https://www.manning.com/books/functional-reactive-programming">Manning’s book on Functional Reactive Programming</a> (co-authored with Anthony Jones). It is currently on the Manning’s Early Access Program, which means it is still subject to revisions. The first chapter ‘Stop Listening!’ is free (check the sidebar), and I highly recommend it to get Stephen and Anthony’s take on why events are evil. The part about the six plagues of listeners is fantastic and provides a solid argument as to why we need to consider new patterns.</p>
<p>Over the next few weeks I will chronicle my attempt to learn FRP by implementing the Smart Date Picker above using Streams and Cells (FRP primitives). I will rely only on the <a href="https://www.manning.com/books/functional-reactive-programming">book</a>, the <a href="https://forums.manning.com/forums/functional-reactive-programming">book’s forum</a>, the <a href="http://sodium.nz/">Sodium library forum</a> and minimal web searching in order to give an honest book review from the perspective of a developer who’s mainly done imperative coding in C#. I will set up a GitHub page so you can follow my progress.</p>
<p>Many thanks to Stephen for allowing me to review his book. I am grateful that New Zealand has some great minds doing some great work in emerging areas.</p>]]></content></item><item><title>Developing Software on Windows 10 IoT</title><link>https://www.coderfrontline.com/developing-software-on-windows-10-iot/</link><pubDate>Sun, 05 Jun 2016 09:35:42 +1200</pubDate><guid>https://www.coderfrontline.com/developing-software-on-windows-10-iot/</guid><description>&lt;p>It’s taken me awhile to get into the Internet of Things due to my lack of knowledge around interfacing with the hardware. Luckily, developing software on Windows 10 IoT is almost a breeze for .Net developers thanks to Microsoft’s great tooling support. There are a lot of great tutorials online so I will focus instead on highlighting unique aspects about programming applications for the Raspberry Pi 3.&lt;/p></description><content type="html"><![CDATA[<p>It’s taken me awhile to get into the Internet of Things due to my lack of knowledge around interfacing with the hardware. Luckily, developing software on Windows 10 IoT is almost a breeze for .Net developers thanks to Microsoft’s great tooling support. There are a lot of great tutorials online so I will focus instead on highlighting unique aspects about programming applications for the Raspberry Pi 3.</p>
<h2 id="universal-windows-platform">Universal Windows Platform</h2>
<p>Commonly shortened to UWP, this is Microsoft’s latest effort to create a common set of system APIs across different Windows devices and architecture. I still remember the circus when Windows 8 introduced Win RT. Time will tell if UWP lasts the distance or gets superseded by the next major Windows release. For the moment though, you will need to create a Universal Windows Platform application in order to run it on Windows 10 IoT.</p>
<p>UWP provides a rich set of APIs, but it is by no means a complete replacement for the full Windows desktop API. The standard UWP template reveals WPF window classes with standard XAML support – or so it seems. Upon further inspection, UWP XAML is missing some features such as Triggers, which many developers like to use. There are workarounds in both XAML and code-behind, but it is something to be aware of. Namespaces may also differ from what desktop developers are used to, and some UWP-specific NuGet packages might be required.</p>
<h2 id="visual-studio-2015-debugging-experience">Visual Studio 2015 debugging experience</h2>
<p>Visual Studio 2015 provides a first-rate debugging and deployment experience, in all editions. I created a project in both the Ultimate edition I use at work, and the free Community edition on a home laptop. There are no differences between them in terms of working with the Pi. I was able to pick the ARM platform and run it on a Remote Device. It prompts you to pick an auto-detected device, or manually enter an IP address. And it just works – no fiddling with app certificates or manually selecting executables to send over the wire.</p>
<h2 id="raspberry-pi-remote-connection">Raspberry Pi remote connection</h2>
<p>One current issue with the auto-detection is that the listening server on the RasPi sometimes times out. It does not show up in the <a href="/configuring-windows-10-iot-raspberry-pi-3/">IoT Core Dashboard</a> app and you can’t access the web configuration page either. The running app usually remains operational, but it will need to be soft reset to be able to deploy and debug again.</p>
<h2 id="communicating-with-hardware">Communicating with hardware</h2>
<p>The next step is to communicate with external hardware. This is an area I have yet to investigate in any depth but online code snippets suggest it is quite trivial to send signals to the RasPi’s GPIO pins. I also bought a <a href="https://www.raspberrypi.org/products/sense-hat/">Sense HAT</a>, which is a convenient add-on board that conveniently sits on top of the Pi and has an 8×8 RGB LED matrix, gyroscope, accelerometer, magnetometer, temperature, barometric pressure, and humidity sensors. Even more convenient is the <a href="https://www.hackster.io/laserbrain/windows-iot-sense-hat-10cac2">open-source .Net library created by Mattias Larsson</a> to conveniently poll the Sense HAT’s sensors. It comes with a great samples library to kick-start any Sense HAT project.</p>
<h2 id="summary">Summary</h2>
<p>While it will always have its detractors, I am personally a fan of what Microsoft is doing in the IoT space and I feel empowered to finally bring my software skills into the hardware world. I will have lots more to write about my experiences with developing software on Windows 10 IoT after I learn more about it. I would encourage you to try it too because the Internet is coming to your things. Are you ready for it?</p>
<p>For the next few weeks we will completely switch tacks. I received a reviewer’s copy of <a href="https://www.manning.com/books/functional-reactive-programming">Functional Reactive Programming</a>, authored by Kiwi technologists Stephen Blackheath and Anthony Jones, creators of the Sodium FRP library. I’m finding time to work through it and will be sharing my thoughts on the book and the pattern itself.</p>
<p>Photo credit: <a href="https://www.flickr.com/photos/caitlinator/2971879868/">Caitlinator</a> via <a href="https://visualhunt.com/photos/travel/">Visual Hunt</a> / <a href="http://creativecommons.org/licenses/by/2.0/">CC BY</a></p>]]></content></item><item><title>Configuring Windows 10 IoT on Raspberry Pi 3</title><link>https://www.coderfrontline.com/configuring-windows-10-iot-on-raspberry-pi-3/</link><pubDate>Sun, 29 May 2016 09:06:07 +1200</pubDate><guid>https://www.coderfrontline.com/configuring-windows-10-iot-on-raspberry-pi-3/</guid><description>&lt;p>Configuring Windows 10 IoT is the next logical step after &lt;a href="https://www.coderfrontline.com/installing-windows-10-iot/">OS installation&lt;/a>. These tips should apply to any of the boards supported by Windows 10 IoT, but I will focus on the Raspberry Pi 3.&lt;/p></description><content type="html"><![CDATA[<p>Configuring Windows 10 IoT is the next logical step after <a href="/installing-windows-10-iot/">OS installation</a>. These tips should apply to any of the boards supported by Windows 10 IoT, but I will focus on the Raspberry Pi 3.</p>
<h2 id="prerequisites">Prerequisites</h2>
<p>Windows 10 IoT is free, but you need a full Windows 10 desktop/laptop environment to get the most out of it. You can access the Pi’s web configuration page from almost any device, but certain steps require Powershell.</p>
<h2 id="on-device-configuration">On-Device Configuration</h2>
<p>There are some basic options you can change from within the default startup app. Since this is an IoT device I assume you have a network cable plugged in. This is especially important as there is no way to set the date/time directly. It will instead query a time server automatically, but I have found that it usually takes about 15 minutes for it to correct itself. This is slightly annoying since I don’t have a real-time clock on my Pi. Alternatively, you can also use the <a href="http://stackoverflow.com/a/32925725">Powershell set-date command</a> to manually set the date – useful if your device is not network-enabled.</p>
<p>You can access some basic settings from this default startup app. The Settings screen will allow you to do the following (as of May 2016):</p>
<ul>
<li>Connect to a broadcasted WiFi network (see below for tips on non-broadcast SSIDs).</li>
<li>Activate Bluetooth (RasPi 3 on-board Bluetooth chip not supported as of May 2016).</li>
<li>Set the time zone.</li>
</ul>
<p>You should also note the assigned IP address on the home page.</p>
<h2 id="windows-device-portal">Windows Device Portal</h2>
<p>Windows creates a web configuration page on port 8080. You can browse to it and log in to the administrator account using the default password p@ssw0rd.</p>
<p>You will obviously want to change that default password immediately and the web configuration will allow that in addition to:</p>
<ul>
<li>Selecting output screen resolution (requires a restart)</li>
<li>Running installed apps</li>
<li>Install new apps via package uploads</li>
<li>Selecting network connection profile</li>
<li>Enabling Windows IoT Remote Server – a highly recommended step during debugging and set up. This allows Remote Clients to connect.</li>
</ul>
<p>You can get a <a href="https://developer.microsoft.com/en-us/windows/iot/win10/tools/deviceportal">comprehensive rundown</a> over at Microsoft.</p>
<h2 id="windows-10-iot-core-dashboard">Windows 10 IoT Core Dashboard</h2>
<p>This is a handy utility especially if you have multiple boards running Windows 10 IoT (lucky you!). You can find the <a href="https://developer.microsoft.com/en-us/windows/iot/win10/kitsetuprpi">download link</a> in Microsoft’s guide. It lists all the discoverable Windows 10 IoT devices on the network and allows some basic configuration from within the app itself. It can also launch the web configuration portal to save you from remembering IP or machine names.<figure id="attachment_130" style="width: 450px" class="wp-caption aligncenter"></p>
<p><img class=" wp-image-130" src="/wp-content/uploads/sites/2/2016/05/IoTDashboard.png" alt="Windows 10 IoT Dashboard" width="450" height="192" srcset="/wp-content/uploads/sites/2/2016/05/IoTDashboard.png 300w, /wp-content/uploads/sites/2/2016/05/IoTDashboard.png 768w, /wp-content/uploads/sites/2/2016/05/IoTDashboard.png 1024w" sizes="(max-width: 450px) 100vw, 450px" /><figcaption class="wp-caption-text">Windows 10 IoT Dashboard</figcaption></figure></p>
<h2 id="windows-10-iot-remote-client">Windows 10 IoT Remote Client</h2>
<p>Long story short: this is Remote Desktop for Windows 10 IoT. You can’t RDP into Windows 10 IoT (yet) but this app, which can be found in the Windows App Store, allows you to remotely view and control your Raspberry Pi. Highly recommended so you don’t need to connect a the RasPi up to any monitor or TV just to do some minor configuration.</p>
<h2 id="connecting-to-hidden-wifi-networks">Connecting to hidden WiFi networks</h2>
<p>By ‘hidden’ I mean WiFi networks that do not broadcast their SSIDs. It’s a bit of a hassle at the moment as there is no interactive way to specify the SSID to look for. I needed to connect the RasPi to my work Wifi (which is non-broadcast) and I came across this excellent guide on <a href="https://developer.microsoft.com/en-us/windows/iot/win10/SetupWiFi.htm">importing WiFi profiles through PowerShell</a>. Scroll down to the Option 2 heading and go from there.</p>
<p>That guide currently advises you to export the desired WiFi profile from the computer you are working on, in order to import it into the RasPi. However, my work PC does not have a WiFi adapter, so I worked around it by using PowerShell to export a saved profile on the RasPi itself. I opened it up in Notepad and tweaked the SSID and WPA2 key, saved it as the new profile’s name, and proceeded to import the profile using PowerShell.</p>
<p>In case that did not work, here’s a template you can use to roll your own profile. Note that you will need to transmit the Wi-Fi key in plaintext.</p>
<div class="highlight"><pre class="chroma"><code class="language-xml" data-lang="xml"><span class="cp">&lt;?xml version=&#34;1.0&#34; encoding=&#34;US-ASCII&#34;?&gt;</span>
<span class="nt">&lt;WLANProfile</span> <span class="na">xmlns=</span><span class="s">&#34;http://www.microsoft.com/networking/WLAN/profile/v1&#34;</span><span class="nt">&gt;</span>
    <span class="nt">&lt;name&gt;</span>SampleNonBroadcast<span class="nt">&lt;/name&gt;</span>
    <span class="nt">&lt;SSIDConfig&gt;</span>
        <span class="nt">&lt;SSID&gt;</span>
            <span class="nt">&lt;name&gt;</span>SampleNonBroadcast<span class="nt">&lt;/name&gt;</span>
        <span class="nt">&lt;/SSID&gt;</span>
        <span class="nt">&lt;nonBroadcast&gt;</span>true<span class="nt">&lt;/nonBroadcast&gt;</span>
    <span class="nt">&lt;/SSIDConfig&gt;</span>
    <span class="nt">&lt;connectionType&gt;</span>ESS<span class="nt">&lt;/connectionType&gt;</span>
    <span class="nt">&lt;connectionMode&gt;</span>auto<span class="nt">&lt;/connectionMode&gt;</span>
    <span class="nt">&lt;MSM&gt;</span>
        <span class="nt">&lt;security&gt;</span>
            <span class="nt">&lt;authEncryption&gt;</span>
                <span class="nt">&lt;authentication&gt;</span>WPAPSK<span class="nt">&lt;/authentication&gt;</span>
                <span class="nt">&lt;encryption&gt;</span>TKIP<span class="nt">&lt;/encryption&gt;</span>
                <span class="nt">&lt;useOneX&gt;</span>false<span class="nt">&lt;/useOneX&gt;</span>
            <span class="nt">&lt;/authEncryption&gt;</span>
            <span class="nt">&lt;sharedKey&gt;</span>
                <span class="nt">&lt;keyType&gt;</span>passPhrase<span class="nt">&lt;/keyType&gt;</span>
                <span class="nt">&lt;protected&gt;</span>false<span class="nt">&lt;/protected&gt;</span>
                <span class="nt">&lt;keyMaterial&gt;</span> <span class="c">&lt;!-- insert key here --&gt;</span> <span class="nt">&lt;/keyMaterial&gt;</span>
            <span class="nt">&lt;/sharedKey&gt;</span>
        <span class="nt">&lt;/security&gt;</span>
    <span class="nt">&lt;/MSM&gt;</span>
<span class="nt">&lt;/WLANProfile&gt;</span>
</code></pre></div><p>Microsoft publishes <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa369853(v=vs.85).aspx">different Wi-Fi profile samples</a> if the above does not suit your Wi-Fi settings.</p>
<p>I hope the above tips and tricks helped you in configuring Windows 10 IoT for the Raspberry Pi 3. You can expect things to change as Microsoft is actively developing this area. Consider this more of a historical record of how the ‘early days’ looked like.</p>
<p>Next week: Developing Software on Windows 10 IoT</p>
<p>Photo credit: <a href="https://www.flickr.com/photos/the-wanderers-eye/11356591736/">“The Wanderer&rsquo;s Eye Photography”</a> via <a href="https://visualhunt.com/">Visual Hunt</a> / <a href="http://creativecommons.org/licenses/by-nc-sa/2.0/">CC BY-NC-SA</a></p>]]></content></item><item><title>Installing Windows 10 IoT on Raspberry Pi 3</title><link>https://www.coderfrontline.com/installing-windows-10-iot-on-raspberry-pi-3/</link><pubDate>Sun, 22 May 2016 09:22:28 +1200</pubDate><guid>https://www.coderfrontline.com/installing-windows-10-iot-on-raspberry-pi-3/</guid><description>&lt;p>Installing Windows 10 IoT on a Raspberry Pi 3 can be quite easy… if you take care of a few things up front. I’m wording this blog post from a total newbie’s perspective – someone who might know how to write software, but is taking their first dip into doing IoT in general and Raspberry Pi 3 in particular. If that fits your profile, keep reading.&lt;/p></description><content type="html"><![CDATA[<p>Installing Windows 10 IoT on a Raspberry Pi 3 can be quite easy… if you take care of a few things up front. I’m wording this blog post from a total newbie’s perspective – someone who might know how to write software, but is taking their first dip into doing IoT in general and Raspberry Pi 3 in particular. If that fits your profile, keep reading.</p>
<p>The first thing you need is a device where you can install Windows 10 IoT on, such as the Raspberry Pi. Microsoft supports other boards as well, but I have gone with the Raspberry Pi (commonly shortened to Raspi) as it’s the most prominent of them. Next, I highly recommend getting the latest model the <a href="https://www.raspberrypi.org/blog/raspberry-pi-3-on-sale/">Raspi 3</a>. Besides having upgraded specs, it now comes with on-board WiFi and Bluetooth. This easily frees up one to two USB ports for other peripherals.</p>
<p><strong>Tip #1:</strong> As of post time (May 2016), Windows 10 IoT supports the on-board Broadcom WiFi chip but not the Bluetooth chip. You should get your own BT dongle if you envision the need to use Bluetooth now, although I’m sure Microsoft will support it fairly soon.</p>
<p><strong>Tip #2:</strong> I found some posts in passing that slammed the choice of embedded WiFi chip on the Raspi 3 as it <a href="https://www.reddit.com/r/raspberry_pi/comments/4ah4oi/psa_the_raspberry_pi_3s_embedded_wifi_card_does/">doesn’t support some advanced features</a>. If you need capabilities such as promiscuous mode, you might benefit from an external WiFi dongle too.</p>
<p>That’s the hardware part more or less sorted.</p>
<p>Raspis use SD cards as the main storage by default. Directly installing Windows 10 IoT on a fresh SD card is possible, but I would highly recommend the use of NOOBS (New Out Of Box Software). It fits my needs as a newbie perfectly. Think of it as a NuGet Package Manager for Raspi OSes. It’s a lightweight bootloader that is able to connect to the Internet and download your choice of compatible OSes. Straight off the bat I was able to pick Raspbian (Linux distro with a complete desktop experience) and Windows 10 IoT. NOOBS has got a pretty <a href="https://github.com/raspberrypi/noobs/wiki/NOOBS-partitioning-explained">clever partitioning method</a> that allows multiple OSes on a single SD card.</p>
<p><strong>Tip #3:</strong> To make things even easier for the n00bs among us, you can buy SD cards with NOOBS preloaded on them. I got mine from <a href="https://pishop.nz/RPI-16GB-NOOBS.html">Pi Shop NZ</a>. I plugged that into my Raspi 3 (which I bought from them too) and it went straight into NOOBS.</p>
<p><strong>Tip #4:</strong> Get a 16GB card or larger. Windows 10 IoT itself takes up almost 8GB which means it won’t fit on a NOOBS 8GB if you want to try other OSes as well.</p>
<p><strong>Tip #5:</strong> If you’re setting your own NOOBS SD card up, make sure to get the fastest SD card you can afford. Not all Class 10 micro SD cards are equal. I found a handy <a href="http://www.pidramble.com/wiki/benchmarks/microsd-cards">micro SD benchmark</a> geared towards Raspis.</p>
<p>Once you pick your OS and begin installation (every installation wipes out the entire SD card), you can go get a delicious beverage because the partitioning and installation is quite slow (see Tip 5). Think about 2 hours if you’re doing both Raspbian and installing Windows 10 IoT.</p>
<p>When it gets to Windows’ turn, NOOBS will direct you to a Windows 10 IoT download page. You will need to login with a Microsoft account, sign up for Windows Insider, and then pick the correct installation for your device. Rather than reproduce the steps here when it’s in constant flux, you should check out Microsoft’s official guide to installing <a href="https://ms-iot.github.io/content/en-US/win10/Noobs.htm">Windows 10 IoT using NOOBS</a>.</p>
<p><strong>Tip #6:</strong> <a href="https://insider.windows.com/">Sign up for Windows Insider</a> before you begin. I had trouble proceeding to the next step when I was doing it via NOOBS and had to restart the whole installation again. It was OK the next time as I was already a Windows Insider member.</p>
<p>If all goes well, NOOBS should redirect you to the OS selection page where you can pick Windows 10 IoT. This was also the part where I stumbled and required quite a few tries so do read my tips below.</p>
<p><strong>Tip #7:</strong> Initial boot can take a while. However, 2 hours might just be too long to wait. The first time I managed to get to the Windows boot screen, it started at 4am (don’t ask) and it was still going at 6am. I cancelled and restarted the installation.</p>
<p><strong>Tip #8:</strong> On the other hand, some patience is required. On my next installation I was not as patient and pulled the power after a few minutes. This resulted in some corrupt config and it hangs on the Windows boot logo with a cryptic error message. I was not able to fix it and had to restart the installation again. 5 to 10 minutes is a reasonable time to wait.<figure id="attachment_126" style="width: 300px" class="wp-caption aligncenter"></p>
<p><img class="size-medium wp-image-126" src="/wp-content/uploads/sites/2/2016/05/DefaultAppRpi2.png" alt="Default Windows 10 IoT startup app" width="300" height="225" srcset="/wp-content/uploads/sites/2/2016/05/DefaultAppRpi2.png 300w, /wp-content/uploads/sites/2/2016/05/DefaultAppRpi2.png 768w, /wp-content/uploads/sites/2/2016/05/DefaultAppRpi2.png 1024w" sizes="(max-width: 300px) 100vw, 300px" /><figcaption class="wp-caption-text">Default Windows 10 IoT startup app</figcaption></figure></p>
<p>With lots of luck it should take you into the default app for Windows 10 IoT (hurrah!). You can pick some globalisation settings and connect to WiFi from this startup app, but not much else. Remember, there is no desktop on this Windows and you’ll need to load apps from another Windows 10 machine. This is a topic I will get into very soon. But first, some tips for <a href="/configuring-windows-10-iot-raspberry-pi-3">configuring Windows 10 IoT on the RasPi 3</a>.</p>]]></content></item><item><title>Windows 10 IoT on Raspberry Pi 3 – A Toe Dip</title><link>https://www.coderfrontline.com/windows-10-iot-on-raspberry-pi-3-a-toe-dip/</link><pubDate>Sun, 15 May 2016 11:04:32 +1200</pubDate><guid>https://www.coderfrontline.com/windows-10-iot-on-raspberry-pi-3-a-toe-dip/</guid><description>&lt;p>Being a software engineering graduate, I’ve always looked at hardware as the other side of the river from me. It sounds a bit surprising considering my first job was at Agilent (now &lt;a href="http://jobs.keysight.com/country-malaysia/#section-overview">Keysight&lt;/a>), a top electronics measurement company, but I’ve always treated the hardware component of my work with a little apprehension. However, the Internet of Things (IoT) is becoming very prolific and it’s no longer something I can easily ignore. I’ve thus decided to start dipping my toes in that cold, cold river, beginning with installing Windows 10 IoT on a Raspberry Pi 3. I will share my experiences as I learn more about it.&lt;/p></description><content type="html"><![CDATA[<p>Being a software engineering graduate, I’ve always looked at hardware as the other side of the river from me. It sounds a bit surprising considering my first job was at Agilent (now <a href="http://jobs.keysight.com/country-malaysia/#section-overview">Keysight</a>), a top electronics measurement company, but I’ve always treated the hardware component of my work with a little apprehension. However, the Internet of Things (IoT) is becoming very prolific and it’s no longer something I can easily ignore. I’ve thus decided to start dipping my toes in that cold, cold river, beginning with installing Windows 10 IoT on a Raspberry Pi 3. I will share my experiences as I learn more about it.</p>
<p>I consider Windows 10 IoT as Microsoft’s acknowledgement that IoT is poised to start a revolution. They missed the smartphone train, and are barely holding on to their niche in the tablet space (Surface Pro), but they’re definitely taking big steps forward to make sure the Windows brand name lives on in small and headless (zero interface) devices. Thus, Windows 10 IoT is their entry into defining a Universal Windows Platform (UWP) for popular IoT platforms like the Raspberry Pi. Briefly speaking, UWP promises a consistent set of Windows APIs to target, regardless of the device. The idea being that code that targets UWP APIs are platform-agnostic, and should <a href="https://msdn.microsoft.com/en-us/windows/uwp/layout/design-and-ui-intro">look and perform the same</a> no matter where the code is run.</p>
<p>Hearing about Windows 10 IoT being available was a great motivation for me to get started. Sure, it’s gotten some <a href="http://hackaday.com/2015/08/13/raspberry-pi-and-windows-10-iot-core-a-huge-letdown/">bad reviews</a> (takeaway: run!) but that’s inevitable because people expected the full Windows 10 experience. So did I, which meant some disappointment when I discovered there’s no Windows desktop or ability to run multiple foreground apps (slightly ironic considering the Windows moniker – what? No windows?).</p>
<p>However, that overlooks some key points. The main one for me is that I can use development tools (Visual Studio 2015), languages (C#), and frameworks (WPF) that I’m familiar with onto a new platform. I plan to get around to developing on Linux, like on the excellent Raspbian distro, but I see Windows 10 IoT as helping to remove a major barrier between ideas and implementation.</p>
<p>I highly doubt I would get started without having Windows 10 IoT because there is just so much to consider when doing IoT – different processor architecture, resource constraints, communicating with external sensors/peripherals, and finally the software. I felt that Windows 10 IoT gives me a confident footing with its software platform (as feature-lite as it still is), and so I can focus more on the other pillars of what makes up IoT. I suspect this is the same for a lot of software developers who are already struggling to learn about breadboards and resistor colour codes, which bodes well for Microsoft if they can quickly solidify the Windows 10 IoT development experience.</p>
<p>I will be sharing my experiences with developing on the Raspberry Pi 3 over the next few weeks, and what you should watch out for.</p>]]></content></item><item><title>Techweek AKL 14-22 May 2016</title><link>https://www.coderfrontline.com/techweek-akl-14-22-may-2016/</link><pubDate>Mon, 09 May 2016 03:55:08 +1200</pubDate><guid>https://www.coderfrontline.com/techweek-akl-14-22-may-2016/</guid><description>&lt;p>The first ever &lt;a href="http://techweek.co.nz/">Techweek AKL&lt;/a> starts in less than a week and I&amp;rsquo;m excited to attend some of the events. I think it&amp;rsquo;s a great start to building NZ&amp;rsquo;s tech resources. Sure, it&amp;rsquo;s no TechCrunch Disrupt but this will definitely start us down that path. However I don&amp;rsquo;t think it&amp;rsquo;s very well publicised as I only found out about it while glancing through the last &lt;a href="http://ourauckland.aucklandcouncil.govt.nz/">Our Auckland newsletter&lt;/a>. Consider this my small part in raising its visibility.&lt;/p></description><content type="html"><![CDATA[<p>The first ever <a href="http://techweek.co.nz/">Techweek AKL</a> starts in less than a week and I&rsquo;m excited to attend some of the events. I think it&rsquo;s a great start to building NZ&rsquo;s tech resources. Sure, it&rsquo;s no TechCrunch Disrupt but this will definitely start us down that path. However I don&rsquo;t think it&rsquo;s very well publicised as I only found out about it while glancing through the last <a href="http://ourauckland.aucklandcouncil.govt.nz/">Our Auckland newsletter</a>. Consider this my small part in raising its visibility.</p>
<p>Techweek AKL has various events that help you “immerse yourself in the latest STEM trends from nanotech to biotech, from the Internet of Things to virtual reality, from the on-demand economy to peer-to-peer business.” While it&rsquo;s not a programming-centric event, software will undoubtedly be a major driving force behind those new breakthroughs. Hence I think it&rsquo;s helpful for software developers to check out some of the events and network with current/future industry leaders.</p>
<p>Unfortunately there is a cost involved in many of the main keynote events as they involve international speakers. I am a bit cash-strapped at the moment so have focused my attendance on the free events. Come say hi if you see me at the following Techweek AKL events:</p>
<ul>
<li>16 May (Monday) 5-8pm: <a href="http://techweek.co.nz/events/the-connected-city-with-nokia-and-jll#content">The Connected City with Nokia and JLL</a></li>
<li>17 May (Tuesday) 6-9pm: <a href="http://www.meetup.com/Functional-Programming-Auckland/events/229451761/">Functional Reactive Programming in Java with Sodium</a></li>
</ul>
<p>There are many others I would like to check out but they happen during working hours or have a decent cost involved. I highly recommend checking out the <a href="http://techweek.co.nz/events/ethereum-disrupting-the-global-financial-system#content">Ethereum - Disrupting the Global Financial System</a> mini-conference (<a href="http://www.ethereum.nz/">$280!</a>).</p>
<div class="subsection subsection-embed">
  Photo credit: <a href="https://www.flickr.com/photos/colleague/4278414807/">Lambroso</a> via <a href="https://visualhunt.com/">Visual hunt</a> / <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC BY-SA</a>
</div>]]></content></item><item><title>Strategy Lenses: How Strategy is Formulated</title><link>https://www.coderfrontline.com/strategy-lenses-how-strategy-is-formulated/</link><pubDate>Sun, 08 May 2016 01:18:46 +1200</pubDate><guid>https://www.coderfrontline.com/strategy-lenses-how-strategy-is-formulated/</guid><description>&lt;p>I wanted to do a quick add-on to last week’s post about the many &lt;a href="https://www.coderfrontline.com/definitions-of-strategy/">definitions of strategy&lt;/a>, specifically: How is strategy formulated? Again, many perspectives abound and one approach is the strategy lenses, as found in &lt;a href="http://amzn.to/1X1hV7x">Exploring Strategy 10&lt;sup>th&lt;/sup> edition&lt;/a>. In it, the authors present various ways of comprehending strategy development, and they can be loosely linked to &lt;a href="https://www.coderfrontline.com/definitions-of-strategy/">Mintzberg’s 5 P’s of strategy&lt;/a> I covered last week.&lt;/p></description><content type="html"><![CDATA[<p>I wanted to do a quick add-on to last week’s post about the many <a href="/definitions-of-strategy/">definitions of strategy</a>, specifically: How is strategy formulated? Again, many perspectives abound and one approach is the strategy lenses, as found in <a href="http://amzn.to/1X1hV7x">Exploring Strategy 10<sup>th</sup> edition</a>. In it, the authors present various ways of comprehending strategy development, and they can be loosely linked to <a href="/definitions-of-strategy/">Mintzberg’s 5 P’s of strategy</a> I covered last week.</p>
<p>The below text is excerpted from <a href="http://amzn.to/1X1hV7x"> Exploring Strategy 10<sup>th</sup> edition</a> with some of my own analysis thrown in:</p>
<h2 id="design-lens">Design Lens</h2>
<p>The design lens views strategy development as a logical process of analysis and evaluation. This is the most commonly held view about how strategy is developed and what managing strategy is about. It encourages objective analysis through the use of formal concepts and frameworks.</p>
<p>This matches most closely with the strategy as plan and strategy as ploy definitions. It is definitely what most business consultants recommend, since their bread-and-butter is convincing clients that they can plan their way to success with a few choice tools like a SWOT Analysis.</p>
<h2 id="experience-lens">Experience Lens</h2>
<p>The experience lens views strategy as the outcome of people’s taken-for-granted assumptions and ways of doing things. Given that strategies are chosen and implemented by people, then their experience is going to matter. Strategy through the experience lens puts people, culture and history centre stage in strategy development.</p>
<p>This can be linked to the strategy as perspective viewpoint. It emphasises that effective strategy cannot be simply designed on paper. Instead, it has to take into account what the existing people (the agents) are comfortable with and are able to carry out.</p>
<h2 id="variety-lens">Variety Lens</h2>
<p>The variety or ideas lens views strategy as the bubbling up of new ideas from the variety of people in and around organisations. Top managers cannot know everything about their organisations and markets. According to the variety lens, therefore, strategy can emerge not just from the top, but also from the periphery and bottom of the organisation.</p>
<p>Similar to the previous lens, it puts the spotlight on the ‘coal face’. They are the closest to the ground and so can often be able to give feedback on what’s working and what’s not. Unfortunately, most strategy development happens at the top because it’s commonly viewed as the job of ‘senior managers’. In short, this lens encourages strategists to look outside of themselves.</p>
<h2 id="discourse-lens">Discourse Lens</h2>
<p>The discourse lens views language as important both for understanding and changing strategy and for managerial power and identity. Managers are always using language to pursue their objectives. Through this lens, unpicking managers’ discourse can uncover hidden meanings and political interests.</p>
<p>I was most intrigued by this lens because it put a label to something I had long suspected – that strategy development is influenced by communication, especially communication that comes with interests and biases attached. This is inevitable as strategy changes have an effect on people for better or worse. Some of them, you might expect, would try to manoeuvre strategy to their advantage.</p>
<h2 id="footnote">Footnote</h2>
<p>I hope you enjoyed reading about the different strategy lenses, and appreciate that they can be approached from many ways and yet be correct. The key implication is to always consider other lenses and definitions. Strategy is an exciting field and it doesn’t need to include a single SWOT Analysis!</p>]]></content></item><item><title>Clash of Culture - MediaWorks and Mark Weldon Part Ways</title><link>https://www.coderfrontline.com/clash-of-culture-mediaworks-and-mark-weldon-part-ways/</link><pubDate>Wed, 04 May 2016 01:00:25 +1200</pubDate><guid>https://www.coderfrontline.com/clash-of-culture-mediaworks-and-mark-weldon-part-ways/</guid><description>A clash of culture happens when cultures don&amp;rsquo;t mesh - and the resulting fireworks can be very dangerous. It gives further reason to care about culture and how one&amp;rsquo;s personal culture can affect the entire organisation. Some choice excerpts from NZ Herald - 4 May 2016 article on Mark Weldon&amp;rsquo;s resignation (all **emphasis **is mine):
“People in that company actually love that company. The issue for Mark is that he wasn&amp;rsquo;t really a cultural fit.</description><content type="html"><![CDATA[<p>A clash of culture happens when cultures don&rsquo;t mesh - and the resulting fireworks can be very dangerous. It gives further reason to <a href="/why-care-about-culture/">care about culture</a> and how one&rsquo;s personal culture can affect the entire organisation. Some choice excerpts from <a href="http://www.nzherald.co.nz/business/news/article.cfm?c_id=3&amp;objectid=11633341">NZ Herald - 4 May 2016</a> article on Mark Weldon&rsquo;s resignation (all **emphasis **is mine):</p>
<ul>
<li>“People in that company actually love that company. The issue for Mark is that he wasn&rsquo;t really a cultural fit. He, for his own reasons, wanted to develop a culture that he believed in but it ran very <strong>contrary to the culture that existed</strong> there - and it was always going to end up in a tough situation.” - Mark Jennings (former MediaWorks news chief)</li>
<li>Former weekend newsreader Carolyn Robinson tweeted: “Goodbye Weldon. Don&rsquo;t trip on the ruins you created as you leave.” Former Campbell Live producer Pip Keane posted: “It&rsquo;s definitely a karma day.”</li>
<li>“People work very much for each other. That seemed to be very <strong>different to the way Mark saw things</strong>.”</li>
<li>“The culture was a no blame culture. If something did go wrong we all accepted responsibility for it. It wasn&rsquo;t a culture to single people out. It meant we were close and people were always prepared to go over and above what they were paid for and what was expected of them. The <strong>hard thing for me was to see people drop off that</strong>.”- Mark Jennings</li>
</ul>
<p>Allow me to defend Mark on some of those issues. He came in when MediaWorks was on the brink of bankruptcy. People (the Board and creditors) expect swift action during a crisis, and that&rsquo;s exactly what he provided. There is little time to sit around and do feasibility studies on a rescue mission when the ship is rapidly sinking! And while I acknowledge that MediaWorks looks like it has a great culture (the no blame culture is similar where I work), we have to be honest - it&rsquo;s not producing the results required to sustain itself. I can imagine Mark pinpointing the culture as something that needs to change, but perhaps he went too far or off-course.</p>
<p>Will acting CEO David Chalmers continue Mark&rsquo;s strategy or dial it back down to avoid another clash of culture? Time will tell I suppose. For now (and in conjunction with May the 4th), may the force be with Mark&rsquo;s next endeavour.</p>
]]></content></item><item><title>The Many Definitions of Strategy</title><link>https://www.coderfrontline.com/the-many-definitions-of-strategy/</link><pubDate>Sun, 01 May 2016 02:38:17 +1200</pubDate><guid>https://www.coderfrontline.com/the-many-definitions-of-strategy/</guid><description>&lt;p>What is strategy in a business context? That is an even more elusive question than &lt;a href="https://www.coderfrontline.com/culture-re-introduction/">what culture is&lt;/a>. I always thought strategy meant market positioning, but my recent academic foray has exposed me to the many definitions of strategy. I list them below, and while some may contradict another, they are in fact all correct. How can that be, you ask? I reckon it is similar to light and sound, which can behave like a wave or a particle under different circumstances (the &lt;a href="https://en.wikipedia.org/wiki/Wave%E2%80%93particle_duality">wave-particle duality&lt;/a>). To paraphrase Einstein, the different definitions of strategy present “&lt;em>contradictory pictures of reality; separately neither of them fully explains the phenomena of”&lt;/em> strategy_, “but together they do”_.&lt;/p></description><content type="html"><![CDATA[<p>What is strategy in a business context? That is an even more elusive question than <a href="/culture-re-introduction/">what culture is</a>. I always thought strategy meant market positioning, but my recent academic foray has exposed me to the many definitions of strategy. I list them below, and while some may contradict another, they are in fact all correct. How can that be, you ask? I reckon it is similar to light and sound, which can behave like a wave or a particle under different circumstances (the <a href="https://en.wikipedia.org/wiki/Wave%E2%80%93particle_duality">wave-particle duality</a>). To paraphrase Einstein, the different definitions of strategy present “<em>contradictory pictures of reality; separately neither of them fully explains the phenomena of”</em> strategy_, “but together they do”_.</p>
<p>This is the point where I defer to much smarter writers to do the explanation. The following definitions are taken from a textbook <a href="http://amzn.to/1SFoVSb">Managing Change, 6<sup>th</sup> Edition by Bernard Burnes</a> wherein he shares five definitions of strategy from <a href="http://amzn.to/23gyPi5">Mintzberg’s book The Strategy Process</a> (or see this <a href="http://www.ftpress.com/articles/article.aspx?p=378964&amp;seqNum=5">FT article</a>). I also provide some examples from the real world.</p>
<h2 id="strategy-as-a-plan">Strategy as a plan</h2>
<p>According to this view, strategy is some form of consciously intended course of action which is created ahead of events. This can be either a general strategy or a specific one. If specific, it may also constitute a ploy.</p>
<h3 id="real-life-example">Real-life example</h3>
<p>Microsoft’s deliberate plan to repackage .Net from the ground-up as a <a href="https://www.dotnetfoundation.org/netcore">cross-platform runtime</a>, and especially re-architecting <a href="https://docs.asp.net/en/latest/conceptual-overview/aspnet.html">ASP .Net Core</a> to follow de-facto web development standards, is an example where they are purposefully staking a claim in what they see as the future of software – one where Windows is no longer the dominant OS. I previously shared my <a href="/cutting-edge-technology-cuts/">negative experience with ASP .Net Core</a> before I realised how much of it has changed.</p>
<h2 id="strategy-as-a-ploy">Strategy as a ploy</h2>
<p>This is where strategy is a manoeuvre to outwit an opponent. An example of this is when a firm threatens to lower its prices substantially to deter new entrants into its market. It is the threat to lower prices that is the consciously intended course of action, and not any actual plan to do so.</p>
<h3 id="real-life-example-1">Real-life example</h3>
<p>It is hard to find a real-life example, since we as observers have no way of telling if a strategic move is merely a ploy. I will try to offer one in the form of <a href="http://www.businessinsider.com.au/netflix-will-spend-5-billion-on-programming-in-2016-2015-2">Netflix recently announcing their intention to spend US$5 billion in 2016 to produce original content</a>. Why did they have to announce it? They could have built a marketing campaign around how Netflix has more original content than their competitors, but instead they touted that extravagant figure up-front. While I believe they will eventually spend close to that, it looks more like a ploy to rattle up the competition and lock customers in. I’m a Netflix viewer, and I for one am excited to stick around to see what $5,000,000,000 of original content gets me.</p>
<h2 id="strategy-as-a-pattern">Strategy as a pattern</h2>
<p>This is where we observe, after the event, that an organisation has acted in a consistent manner over time, i.e. whether consciously or not, the organisation exhibits a consistent pattern of behaviour. We can say from this that an organisation has pursued a particular strategy. This may not be the strategy it intended to pursue, but it is the one that has emerged from the action of the organisation. Therefore, though the organisation’s realised strategy could be the product of a conscious and deliberate plan, this is often not the case.</p>
<h3 id="real-life-example-2">Real-life example</h3>
<p>This is termed as “emergent” strategy, whereby a pattern of behaviour defines a strategy when we look back at it. I propose that Blackberry (remember them?) fits this definition. When their plans for world domination were halted by Apple iOS and Google Android, a pattern emerged from their efforts to maintain relevance in the marketplace. This started with a major overhaul in <a href="https://en.wikipedia.org/wiki/BlackBerry_10">Blackberry 10</a> to prioritise touch screen inputs, and when that didn’t work, acceded to using Android for their latest devices starting with the <a href="https://en.wikipedia.org/wiki/BlackBerry_Priv">Priv</a>. Blackberry CEO John Chen responded to the Android adoption by saying, “…We could keep the pride and die hungry or we can eat well and not so proud, maybe. So I chose to eat well. …” Hence, I doubt the decision to go on Android was done deliberately, but one that emerged through its efforts to keep itself sustainable.</p>
<h2 id="strategy-as-a-position">Strategy as a position</h2>
<p>From this perspective, strategy is about positioning the organisation in order to achieve or maintain a sustainable competitive advantage. Mintzberg <em>et al</em> argue that most organisations try to avoid head-on competition. What they seek to achieve is a position where their competitors cannot or will not challenge them. In this sense, strategy is also seen as a game: groups of players circling each other, each trying to gain the high ground.</p>
<h3 id="real-life-example-3">Real-life example</h3>
<p>Apple’s smartphones, from day one, have positioned itself as a premium product. This has helped it rise above the tide of competitors by setting a healthy profit margin (<a href="https://www.quora.com/What-is-the-profit-margin-of-an-iPhone-6">estimated 65%</a>) on each phone. With the exception of the iPhone 5c to help enter emerging markets, Apple manages to brand itself as worth those extra dollars. Chief rival Samsung have long taken note of this working strategy and is having the same success with its S-series phones.</p>
<h2 id="strategy-as-perspective">Strategy as perspective</h2>
<p>This definition sees strategy as a somewhat abstract concept that exists primarily in people’s minds. For members of an organisation, the actual details of its strategy, as such, are irrelevant. What is important is that everyone in the organisation shares a common view of its purpose and direction which, whether people are aware of it or not, informs and guides decision-making and actions. Consequently, without the need for detailed plans, the organisation, through a shared understanding, pursues a consistent strategy or purpose.</p>
<h3 id="hypothetical-example">Hypothetical example</h3>
<p>Strategy as perspective basically refers to a <a href="/why-care-about-culture/">culture-driven</a> strategy. Without having an explicit strategy plan/ploy/position, a company’s actions can still be cohesive when it is bound by the internal culture. For example, the hypothetical <a href="/cultural-web/">Acme Inc.’s culture</a> is one of continuous improvement. They also love Agile Scrum. From this emerges a strategy of monthly software releases that Acme uses to keep their customers engaged and happy.</p>
<h2 id="footnote">Footnote</h2>
<p>It is important to note that this is only one person’s definitions. Indeed, there are probably as many definitions of strategy as there are companies in the world, so take this as a starting point to formulate your own thoughts on what strategy is.</p>
<p>Next week: How is strategy formulated?</p>]]></content></item><item><title>Cutting-Edge Technology Cuts</title><link>https://www.coderfrontline.com/cutting-edge-technology-cuts/</link><pubDate>Sun, 24 Apr 2016 04:51:09 +1200</pubDate><guid>https://www.coderfrontline.com/cutting-edge-technology-cuts/</guid><description>&lt;p>I bring you a cautionary tale this week about the dangers of using cutting-edge technology and how it can cut you. Like many programmers I get excited with the prospect of using new technology, frameworks, or languages – especially for commercial uses. It’s one thing to try stuff out on the weekend and build tutorial projects, but it’s another ball game to actually build something someone would buy. So I rubbed my hands with glee when the opportunity arose to redesign a web app that was written in ASP .Net MVC 3.&lt;/p></description><content type="html"><![CDATA[<p>I bring you a cautionary tale this week about the dangers of using cutting-edge technology and how it can cut you. Like many programmers I get excited with the prospect of using new technology, frameworks, or languages – especially for commercial uses. It’s one thing to try stuff out on the weekend and build tutorial projects, but it’s another ball game to actually build something someone would buy. So I rubbed my hands with glee when the opportunity arose to redesign a web app that was written in ASP .Net MVC 3.</p>
<p>While there are some firms that like to upgrade their technology with every major release, they are the exception from the norm. For the majority, technology is merely the vehicle to deliver business value to customers, and there is no reason to change vehicles while the current one is still working fine. That’s why there are still a lot of production software running on COBOL or VB6.</p>
<p>The web app product that I’ve been working on (let’s call it Firewatch – no relation to the <a href="http://www.firewatchgame.com/">interesting game by Campo Santo</a>) was created about 5 years ago on ASP .Net MVC 3. Cutting-edge technology at that time, but in the intervening years there’s been a bit of an explosion in the web development world with the rise of mature frameworks like Bootstrap, Node JS, and AngularJS. They have redefined how most web apps are developed these days, and Microsoft hasn’t been quiet either. They introduced Web API to support creating RESTful services and the upcoming ASP .Net Core further moves the framework towards being cross-platform and use de-facto web standards.</p>
<p>In late 2015 I was asked to look into redesigning the Firewatch frontend and saw it as a chance to move things up a notch. I looked around and read about the upcoming ASP .Net 5 (codename vNext) and it looked really promising. According to the <a href="https://github.com/aspnet/Home/wiki/Roadmap">product roadmap</a> at the time, they were releasing RC1 in November followed by RTM in the first quarter of 2016. I thought “Hmm that fits the project schedule just fine. I can start with RC1 and transition onto the RTM when it’s released.”</p>
<p>I did an impassioned presentation to my colleagues on why going onto the cutting-edge technology of ASP .Net 5 was the right choice and got them quite excited. The first couple of weeks building up the basic views went fine, but then I hit a major roadblock – referencing projects built on classic .Net was a real hassle. There were some real oddities in how it tries to wrap existing projects into NuGet packages, and I wasn’t the only one having <a href="https://github.com/aspnet/Tooling/issues/45#issuecomment-182812165">issues with wrapping</a> either. That thread was created May 2015 and is still getting occasional posts from frustrated developers 11 months later. Even when I managed to do the workaround on my machine, the build machine did not recognise the wrapped packages.</p>
<p>The last straw that broke the camel (i.e. me) was the announcement that they’re <a href="http://www.hanselman.com/blog/ASPNET5IsDeadIntroducingASPNETCore10AndNETCore10.aspx">renaming ASP .Net 5 to ASP .Net Core</a>. It finally dawned on me that vNext was not just a major step up, it’s a major step to the side. I had picked ASP .Net 5 on the basis that it is the next major release, as its name would suggest. This announcement finally acknowledges that this change is foundational and developers should not assume their prior knowledge is transferable to the new wild west of .Net Core.</p>
<p>I threw my hands up and backtracked on my recommendations. I proposed moving down to ASP .Net 4.5.1 with MVC 5 and Web API 2 while Microsoft ironed out the kinks. Indeed, as I write this, the roadmap has been updated to have an RC2 with a TBD delivery date. The only issue is once Firewatch gets all its needs met by the existing framework, there would be little reason to do a major architectural update just to go onto .Net Core.</p>
<p>The lesson I learned is: cutting-edge technology might be cool, but be prepared to bleed.</p>
<p>Reminders to self:</p>
<ul>
<li>Don’t trust product roadmaps even from established vendors like Microsoft.</li>
<li>When evaluating any technology, consciously seek out existing issues and what many developers constantly complain about. GitHub issues page is a fantastic resource.</li>
<li>Rapidly prototype a test project containing unique idiosyncrasies of my project and not just stick within the sample projects playground which always works brilliantly.</li>
</ul>
<p>Photo credit: <a href="https://www.flickr.com/photos/fernandoreyes/2532211558/">Fernando Reyes Palencia</a> via <a href="https://visualhunt.com/">Visualhunt.com</a> / <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC BY-SA</a></p>]]></content></item><item><title>A Theory on Success - How to Fail at Almost Everything and Still Win Big</title><link>https://www.coderfrontline.com/a-theory-on-success-how-to-fail-at-almost-everything-and-still-win-big/</link><pubDate>Sun, 17 Apr 2016 04:52:27 +1200</pubDate><guid>https://www.coderfrontline.com/a-theory-on-success-how-to-fail-at-almost-everything-and-still-win-big/</guid><description>&lt;p>&lt;a href="http://amzn.to/1Qf49Xg">How to Fail at Almost Everything and Still Win Big: Kind of the Story of My Life&lt;/a> is the title of an excellent book about success (or lack thereof!) by &lt;a href="http://blog.dilbert.com/">Scott Adams&lt;/a>, &lt;a href="http://www.dilbert.com/">Dilbert&lt;/a> creator and frequent writer on his personal blog. I’ve been an avid reader of his for years, and have read his non-Dilbert fiction books (&lt;a href="http://amzn.to/1Qf4lWq">God’s Debris&lt;/a> and &lt;a href="http://amzn.to/1SSEq8P">The Religion War&lt;/a>) as well. What I enjoy most about Scott’s writing style is the concise manner he puts his points across. It’s an important skill to have when trying to make readers laugh in 3 comic panels, and he puts it to good use in his writing. The following is a brief overview of the key points I took away from his book.&lt;/p></description><content type="html"><![CDATA[<p><a href="http://amzn.to/1Qf49Xg">How to Fail at Almost Everything and Still Win Big: Kind of the Story of My Life</a> is the title of an excellent book about success (or lack thereof!) by <a href="http://blog.dilbert.com/">Scott Adams</a>, <a href="http://www.dilbert.com/">Dilbert</a> creator and frequent writer on his personal blog. I’ve been an avid reader of his for years, and have read his non-Dilbert fiction books (<a href="http://amzn.to/1Qf4lWq">God’s Debris</a> and <a href="http://amzn.to/1SSEq8P">The Religion War</a>) as well. What I enjoy most about Scott’s writing style is the concise manner he puts his points across. It’s an important skill to have when trying to make readers laugh in 3 comic panels, and he puts it to good use in his writing. The following is a brief overview of the key points I took away from his book.</p>
<p>Scott put together an excellent SlideShare presentation – “<a href="http://www.slideshare.net/Scottadams925/goals-are-for-losers-passion-is-overrated">Passion is Overrated, and Goals are for Losers</a>” which I would encourage you to check out before reading my thoughts below. Keep in mind that the slides are only an excerpt of a much larger variety of topics in the book.</p>
<h2 id="passion">Passion</h2>
<p>I was often told that following my passion is the path to success. I have always acknowledged the joys of doing something you’re passionate about – but it also made me uneasy. For example, I loved video games but I was sure I couldn’t make a steady living out of it. Scott helped illuminate the passion fallacy. It is success that breeds passion, and not the other way round.</p>
<p>He instead proposes that personal energy is the fuel that leads to success. It makes simple sense when I think about it. There are times when I am super passionate about my work, but there are days when I would rather stay in bed. Instead of focusing on my lack of passion during tough times, I choose to focus on ways to increase my personal energy. This might involve taking a short weekend trip, or plan office social events, or the simplest – catch up on sleep. I find that simple actions can increase my own energy, which helps me perform better at work that leads to increased passion when I successfully complete it.</p>
<p>If personal energy is the fuel, what is the vehicle to success?</p>
<h2 id="systems">Systems</h2>
<p>Scott asserts that goals are only useful for narrow purposes, whereas the world today is increasingly complex and fast-paced. This really resonated with my own experience. Back in university I would create goals every semester based on the SMART guideline, and the top one was always to score the best possible grade. Lo and behold – it worked and I scored A’s for all courses, bar one.</p>
<p>I was fully convinced about the power of goal statements, but I have not been able to replicate goal-setting in my working life. Goals worked in school because courses were known ahead of time and there were fixed evaluation standards. Real life is just a tad messier, I’m afraid! How does one create a Specific (the S in SMART) goal when the goalposts keep shifting?</p>
<p>Instead of goals, Scott recommends the use of systems, which are basically patterns of behaviours that inevitably lead to positive outcomes. Wait a minute – patterns of behaviours? That sounds like culture! Some examples of systems vs goals that Scott uses are:</p>
<ul>
<li>Goal: Wanting to lose 10 pounds.</li>
<li>System: Learning how to eat right.</li>
</ul>
<p>A goal makes the person feel like a failure until it is attained, after which the cycle restarts. It also requires willpower, which humans have a limited amount of. A system, on the other hand, empowers that person to make good food choices without needing willpower.</p>
<p>I interpret it as modifying our personal culture to create habits that will improve the odds of success. This is still a work in progress, but some of the things I have been doing are studying towards a Graduate Diploma in Strategic Management, and writing for this blog. I wouldn’t be able to tell you what my goals are for them. In other words, I have not given myself a success/failure dichotomy. Instead, they are part of my system to improve my own skills in critical thinking, business-domain knowledge, and writing. These little skills all help, I believe, to move me towards ‘success’. Even if I don’t know what success looks like yet!</p>
<h2 id="a-quote-on-success">A quote on success</h2>
<p>I will end this post with a quote that Scott shared in the book. I agree with him that this simple sentence contains many pearls of wisdom:</p>
<blockquote>
<p><strong>If you want success, figure out the price, then pay it.</strong></p>
</blockquote>
<p>Go <a href="http://amzn.to/1Qf49Xg">check the book out</a> – the paperback is the cost of a lunch. A lunch will sustain you for 6 hours, but this book may sustain you for life.</p>]]></content></item><item><title>Why Care About Culture</title><link>https://www.coderfrontline.com/why-care-about-culture/</link><pubDate>Sun, 10 Apr 2016 07:43:23 +1200</pubDate><guid>https://www.coderfrontline.com/why-care-about-culture/</guid><description>&lt;p>Over the last 3 posts I have &lt;a href="https://www.coderfrontline.com/culture-re-introduction/">re-introduced culture&lt;/a>, &lt;a href="https://www.coderfrontline.com/elements-culture-onion/">explained it as an onion&lt;/a>, and &lt;a href="https://www.coderfrontline.com/cultural-web/">explored the cultural web&lt;/a>. It’s now crunch time – why care about culture at all? Culture is dynamic and monolithic, made up of deeply-held assumptions and embedded in corporate DNA. Many authors have tried to discredit the idea of cultural change as a strategic move. They recommend tailoring strategies and tactics to fit the existing culture instead.&lt;/p>
&lt;p>So, why care about culture? I will skip the textbook answers this time and share my personal view. I care about culture because it affects how well I can do my job.&lt;/p></description><content type="html"><![CDATA[<p>Over the last 3 posts I have <a href="/culture-re-introduction/">re-introduced culture</a>, <a href="/elements-culture-onion/">explained it as an onion</a>, and <a href="/cultural-web/">explored the cultural web</a>. It’s now crunch time – why care about culture at all? Culture is dynamic and monolithic, made up of deeply-held assumptions and embedded in corporate DNA. Many authors have tried to discredit the idea of cultural change as a strategic move. They recommend tailoring strategies and tactics to fit the existing culture instead.</p>
<p>So, why care about culture? I will skip the textbook answers this time and share my personal view. I care about culture because it affects how well I can do my job.</p>
<p>Keep in mind that culture is not something that only large organisations have. Each and every one of us has an individual culture that is shaped by our life experience and environment. Hence, we bring our own cultural values to the organisation we work for. Two things can happen between your personal culture and organisation culture: either they mostly match, or they mostly don’t.</p>
<p>If they match – great! But what if it doesn’t? Then one’s options get murkier. I try to avoid getting into this situation by researching the culture of the company I’m considering joining. I can look through their website, the tone of their public communications, how their office is laid out, and how they conduct their interviews. This helps me flesh out a <a href="/cultural-web/">cultural web analysis</a>. Granted, I will never be able to get a complete picture but I now have better tools (and so do you!) besides the generic interview question: “So… what’s the culture like?”</p>
<p>I then ask myself, “Can I fit the culture of this place?” There will never be a perfect fit, so the real question is more like, “Can I adapt to the culture of this place?” For example, trust is an important ingredient for me to work at my peak, and so I don’t think I’ll do well in a place where I am required to punch in/out and do minute-level tracking of my work. I would personally consider that a form of micro-management and it wouldn’t fit my way of working. I very much prefer to be entrusted with a task and I’ll deliver a quality result in the allocated time.</p>
<p>On the other side of the interview table, it also helps to understand that candidates bring their culture with them and so we need to evaluate if their culture will fit the role being hired for. My opinion is that skills and qualifications are a small part of the interview process. Knowledge and skills can be learnt, but their personal culture is mostly fixed. Some attempt to evaluate this via psychometric testing. However, professional opinions of its effectiveness vary, and I do not yet know enough to form my opinion around it.</p>
<p>In summary, yes, you really should care about culture if only for the sake of making sure you’re with the right company. That is what I found most useful about understanding culture. There are bigger questions left to answer - “How can I meld organisational culture to my own?” is one that comes to mind. We’ll leave those for now and come back to the topic of culture at a later time.</p>]]></content></item><item><title>Cultural Web</title><link>https://www.coderfrontline.com/cultural-web/</link><pubDate>Sun, 03 Apr 2016 02:35:26 +1200</pubDate><guid>https://www.coderfrontline.com/cultural-web/</guid><description>&lt;p>A Cultural Web Analysis is another useful tool that helps tease out the constituent parts of an organisation’s culture. It builds upon the &lt;a href="https://www.coderfrontline.com/elements-culture-onion/">Onion Model of Culture mentioned previously&lt;/a>, but has more concrete classifications that I found helpful. The Cultural Web was introduced by Gerry Johnson and Kevan Scholes, who were also writers of the excellent Exploring Strategy textbook I used for my Strategic Management course.&lt;/p>
&lt;p>Once again we will apply it on the fictional Acme Inc. software development team so you can see how elements of the Onion Model translate (and get expanded) by the Cultural Web.&lt;/p></description><content type="html"><![CDATA[<p>A Cultural Web Analysis is another useful tool that helps tease out the constituent parts of an organisation’s culture. It builds upon the <a href="/elements-culture-onion/">Onion Model of Culture mentioned previously</a>, but has more concrete classifications that I found helpful. The Cultural Web was introduced by Gerry Johnson and Kevan Scholes, who were also writers of the excellent Exploring Strategy textbook I used for my Strategic Management course.</p>
<p>Once again we will apply it on the fictional Acme Inc. software development team so you can see how elements of the Onion Model translate (and get expanded) by the Cultural Web.</p>
<p>The Cultural Web consists of 6 elements that, taken together, define the “paradigm” of the organisation. Simply put, they are the core assumptions that people in the organisation take for granted. This is the hardest to analyse regardless of your membership status with the organisation – members find it hard to define things they do habitually, and non-members are not privy to the inner-goings that will reveal the paradigm.</p>
<p><img class="aligncenter wp-image-51 size-medium" src="/wp-content/uploads/sites/2/2016/04/culture-web.jpg" alt="Cultural Web" width="300" height="298" srcset="/wp-content/uploads/sites/2/2016/04/culture-web.jpg 300w, /wp-content/uploads/sites/2/2016/04/culture-web.jpg 150w, /wp-content/uploads/sites/2/2016/04/culture-web.jpg 500w" sizes="(max-width: 300px) 100vw, 300px" /></p>
<p>The Cultural Web Analysis goes some way to propose a structured approach in identifying the “behavioural, physical, and symbolic manifestations of a culture” (all quotes in this post are from <a href="http://amzn.to/1V1uBev">Exploring Strategy, 10<sup>th</sup> edition</a>).</p>
<ul>
<li>Rituals and routines: Rituals are special events that emphasise important aspects of the culture, while routines are “the way we do things around here on a day-to-day basis”.
<ul>
<li>Acme: A yearly ritual for Acme developers is to conduct an in-house <em>code retreat</em> that gives the developers a chance to try different development techniques and reinforce the power of pair programming and unit testing. This is largely due to <em>test-driven development</em> being a key routine that they practice everyday.</li>
<li>Maps to Rituals and Practices in the Onion Model.</li>
</ul>
</li>
<li>Stories: They are tales told between themselves, outsiders, and new members, in order to explain why things are done a certain way. They highlight the “successes, disasters, heroes, villains, and mavericks” in the organisation’s past.
<ul>
<li>Acme: The tale of how Vanushka saved the product launch is one that is often brought up when explaining why Acme does aggressive test-driven development. It is a story containing heroes, successes, and disasters.</li>
<li>Maps to Heroes in the Onion Model.</li>
</ul>
</li>
<li>Symbols: “Objects, events, acts or people” that represent an idea larger than their functional purpose. For example, company cars serve a functional purpose but they also symbolise status and hierarchy for those who own one.
<ul>
<li>Acme: Developers have a junior, intermediate, and senior ranks, which symbolise seniority and the influence they have on product decisions. In other words, the functional purpose of the job rank is to denote the experience of a developer, but it also confers power beyond its intended function.</li>
<li>Maps to Symbols in the Onion Model.</li>
</ul>
</li>
<li>Power: Refers to the power structures in the organisation. Power is the “ability to persuade, induce or coerce others into following certain courses of action”. The book authors noted that “the most powerful individuals… are likely to be closely associated with… the long-established ways of doing things”.
<ul>
<li>Acme: The job titles mentioned above are certainly a power structure. “Heroes” like Vanushka are also conferred power in influencing key architectural decisions, thanks to the stories that fuel his reputation.</li>
<li>Maps to Symbols in the Onion Model.</li>
</ul>
</li>
<li>Organisational Structures: The “roles, responsibilities, and reporting relationships in organisations”. This is simply an organisational chart, but the key point is to look into why it is structured as such because it will reveal the power structures or other symbols.
<ul>
<li>Acme: The development team is actually divided into 2 reporting groups, one for Software Architects, and another for Software Developers. The architects act as consultants, and the developers make the final decision on the best architecture for their needs. From this we can deduce that the power of architects is limited to the advisory stage, unlike most organisations where architects have veto-like power.</li>
<li>Maps to Symbols in the Onion Model.</li>
</ul>
</li>
<li>Control Systems: They are the “formal and informal ways of monitoring and supporting people… and tend to emphasise what is seen to be important in the organisation”. A great example given in the textbook is about how public service organisations tend to emphasise how public moneys are used rather than the level of service provided, and this is reflected in the control mechanisms used.
<ul>
<li>Acme: Peer <em>code reviews</em> are a control system used to ensure that Acme’s development practices are adhered to, especially the presence of unit tests. Besides that, <em>360-degree reviews</em> form a small part of the annual performance evaluation.</li>
<li>Maps to Practices in the Onion Model.</li>
</ul>
</li>
</ul>
<p>All of those six elements inform, and are informed by, the Paradigm. Mapped to the Values core of the Onion Model, they are the commonly held assumptions in the organisation. They tend to be very basic rather than specific. Looking back at the Cultural Web Analysis for Acme Inc., one might surmise that a paradigm of the development team is the importance of technical excellence through their aggressive unit testing practice and stories told. However, from that we can note a lack of focus on customer satisfaction, i.e. Acme might create the most perfect, bug-free software ever written, but does it actually meet the customer’s needs?</p>
<p>Now that you have a good idea of what a Cultural Web Analysis entails, I urge you to take a cursory look at your organisation, team, family, and yes, even yourself! Culture exists on the personal level all the way to the largest organisations, and being able to analyse it is the first step in planning for success. It shouldn’t take more than 30 minutes to do a first draft that fleshes out the main parts.</p>
<p>I will conclude this introductory series on culture next week by answering the question I previously posed – “Why should I care?”</p>]]></content></item><item><title>Posting Schedule</title><link>https://www.coderfrontline.com/posting-schedule/</link><pubDate>Sun, 27 Mar 2016 22:36:42 +1200</pubDate><guid>https://www.coderfrontline.com/posting-schedule/</guid><description>The posting schedule for this blog is about once a week. I set aside about 4 hours a week to work on the blog, and this week I&amp;rsquo;m using that time to approve a new logo through Mike on Fiverr and update some site elements based on the new graphics.
My posts on culture resume next week.</description><content type="html"><![CDATA[<p>The posting schedule for this blog is about once a week. I set aside about 4 hours a week to work on the blog, and this week I&rsquo;m using that time to approve a new logo through <a href="https://www.fiverr.com/actualreviewnet/design-3-awesome-and-professional-logo-design-concepts-for-your-business-logo" target="_blank">Mike on Fiverr</a> and update some site elements based on the new graphics.</p>
<p>My posts on culture resume next week.</p>
]]></content></item><item><title>Elements of the Culture Onion</title><link>https://www.coderfrontline.com/elements-of-the-culture-onion/</link><pubDate>Sat, 19 Mar 2016 22:43:16 +1200</pubDate><guid>https://www.coderfrontline.com/elements-of-the-culture-onion/</guid><description>&lt;p>My last post gave a &lt;a href="https://www.coderfrontline.com/culture-re-introduction/">brief explanation of what culture is&lt;/a>, the main takeaway point being that culture is all around us on different levels. The next logical question is, “&lt;a href="https://www.coderfrontline.com/why-care-about-culture/">Why should I care?&lt;/a>” I&amp;rsquo;ll answer that in the next few weeks because we need to take a short detour – specifically, how would one analyse and assess the culture of a given group? The answer may lie in the culture onion.&lt;/p>
&lt;p>Although cultures can be difficult to compartmentalise, try we must, and much smarter people before us have offered some suggestions. Let&amp;rsquo;s check them out and apply it on a fictional group – the Acme Inc. software development team._&lt;/p>
&lt;p>_&lt;/p></description><content type="html"><![CDATA[<p>My last post gave a <a href="/culture-re-introduction/">brief explanation of what culture is</a>, the main takeaway point being that culture is all around us on different levels. The next logical question is, “<a href="/why-care-about-culture/">Why should I care?</a>” I&rsquo;ll answer that in the next few weeks because we need to take a short detour – specifically, how would one analyse and assess the culture of a given group? The answer may lie in the culture onion.</p>
<p>Although cultures can be difficult to compartmentalise, try we must, and much smarter people before us have offered some suggestions. Let&rsquo;s check them out and apply it on a fictional group – the Acme Inc. software development team._</p>
<p>_</p>
<figure id="attachment_35" style="width: 271px" class="wp-caption aligncenter">
<p><img class="wp-image-35 size-medium" src="/wp-content/uploads/sites/2/2016/03/Hofstede-model.jpg" alt="Hofstede's culture onion model" width="271" height="300" srcset="/wp-content/uploads/sites/2/2016/03/Hofstede-model.jpg 271w, /wp-content/uploads/sites/2/2016/03/Hofstede-model.jpg 459w" sizes="(max-width: 271px) 100vw, 271px" /><figcaption class="wp-caption-text">Hofstede&rsquo;s culture onion model</figcaption></figure></p>
<p>(Source: <a href="http://www.unfoldconflicts.nl/defriending/">Unfold Conflicts</a>)</p>
<p>It’s helpful here to think of culture as an onion. The outermost layer is the <strong>Symbols</strong> layer. These are the visible signs of culture that even non-members can see. A good example is job titles, like how Acme’s developers are segmented into junior, intermediate, and senior software engineers.</p>
<p>Peel back the symbols layer and you might find the <strong>Heroes</strong> layer. These are the people that embody the whole culture, and is usually an aspirational figure. For example, one of Acme’s heroes is Vanushka ‘the Brave’, who worked all night that one time to get their Docker installation on Azure running again. Such heroics are praised and newcomers are told of how Vanushka saved the company’s reputation before the big launch.</p>
<p><strong>Rituals</strong> come after the Heroes layer, and as the name suggests, it represents the habitual activities that occur without much thought (or are taken for granted). In Acme, developers mark the end of a sprint by having Friday afternoon pizza and drinks. It’s not a formalized procedure or mandated management practice – it is accepted that it “just happens”.</p>
<p>Cutting across the first 3 layers of the onion are <strong>Practices</strong>. They represent the activities that are performed regularly and are influenced by the Symbols, Heroes, and Rituals. For instance, Acme practices test-first development (<em>ritual</em>) and any developer who sneaks code in without a suitable test would get a swift rebuke from a Senior Engineer (<em>symbol</em>). After all, Vanushka is the aspirational figure (<em>hero</em>) that other developers look up to and it was unit tests that helped Vanushka troubleshoot the critical issue.</p>
<p>At the core, which all the previous layers inform and derive from, are the <strong>Values</strong> (also known as <strong>Paradigms</strong>). They represent the deeply held beliefs within the culture and are the hardest to identify, especially from the outside. They are usually quite basic in nature, but absolutely crucial in that it supports the rest of the culture. One of Acme’s paradigms is the importance of following process, as when coders who miss a unit test are called out. Another attribute valued by Acme is the dedication to getting work done at all costs, as when Vanushka spent all night fixing a critical issue.</p>
<p>The double-edged sword of Values is that they are ingrained and are difficult (some would say impossible) to change. Let’s say the unspoken practice of working late to fix production defects is seriously damaging developers’ work-life balance. Is it a simple matter of outlawing work after 8pm? The issue here is that the “get work done at all costs” ethic is a core value of Acme, and any person who attempts to change it will have to confront the <a href="https://meaningofevolution.wordpress.com/2014/02/02/cultural-evolution-and-a-rubber-band/">cultural rubber band</a>. This is a topic I will come to at a later stage when I write about culture change efforts.</p>
<p>The key point of my post is: culture is comprised of many elements and some are more ingrained than others.</p>
<p>Next week, I will present a model of analyzing culture that I personally found helpful to identify the different layers of the culture onion.</p>]]></content></item><item><title>Culture - a re-introduction</title><link>https://www.coderfrontline.com/culture-a-re-introduction/</link><pubDate>Sun, 13 Mar 2016 01:38:15 +1200</pubDate><guid>https://www.coderfrontline.com/culture-a-re-introduction/</guid><description>&lt;p>‘Culture’ as a term is a loaded word. Experts from different fields have their own definitions, which makes it that much harder to comprehend. It is also understandable when people react negatively as it gets bandied about. It’s used as a scapegoat – “Our product launch failed because we didn’t factor in the culture”, and often elicits eye-rolling – “We’ll boost company morale with our culture change programme!” It’s also a common phrase in job ads – “Come join us, we’ve got a great culture!”&lt;/p>
&lt;p>Are any of them valid statements? I think it’s time to strip culture back down to basics, in order to understand how it affects us.&lt;/p></description><content type="html"><![CDATA[<p>‘Culture’ as a term is a loaded word. Experts from different fields have their own definitions, which makes it that much harder to comprehend. It is also understandable when people react negatively as it gets bandied about. It’s used as a scapegoat – “Our product launch failed because we didn’t factor in the culture”, and often elicits eye-rolling – “We’ll boost company morale with our culture change programme!” It’s also a common phrase in job ads – “Come join us, we’ve got a great culture!”</p>
<p>Are any of them valid statements? I think it’s time to strip culture back down to basics, in order to understand how it affects us.</p>
<p>Mind you, this is a blog post not a thesis, so we won’t be able to comprehend every facet of culture but we can at least cover some ground. The best analogy I’ve come across likens culture to the air we breathe. It’s all around us, but we don’t notice it until it’s gone. It’s also surprisingly hard to define. Yes, we can define the air around us as a mixture of hydrogen, nitrogen, oxygen, and other gases. But that will ignore its life-sustaining properties, the nuances in different smells (pleasant AND unpleasant!), and what it means to us. The same is true with any definition of culture – it’s at best incomplete and you should keep that in mind with the next few blog posts.</p>
<p>At its core, culture is “the way <strong>we</strong> do things”. ‘We’ is a very fluid term that can refer to any grouping of people that have a shared identity. The most common example is the idea of a national culture, that people within a country act or behave a certain way. No discussion of national culture would be complete without mentioning the comprehensive work of Geert Hofstede, who profiled national cultures along a range of cultural variables. Check some of the results out on the <a href="http://geert-hofstede.com/countries.html">Hofstede Centre</a> to see analyses on national cultures.</p>
<p>It’s an utterly convenient set of results, but I need to point out some shortcomings in his work. First, his initial results are derived from studying employee values in IBM in their international subsidiaries. This is hardly representative although subsequent studies have expanded their respondents to include “commercial airline pilots and students”, “civil service managers”, and “&lsquo;up-market&rsquo; consumers” (Hofstede Centre). <a href="https://en.wikipedia.org/wiki/Sampling_bias">Sampling bias</a>, anyone?</p>
<p>Secondly, some countries are so big, i.e. India and China, that there will undoubtedly be geographic variations within the results. Hence, Dr. Hofstede’s results are a mere launching pad for further analyses on culture. For more information on this, check out the <a href="http://www.ccl.org/leadership/pdf/assessments/globestudy.pdf">GLOBE study</a> and <a href="https://www.mindtools.com/pages/article/seven-dimensions.htm">Trompenaars’ ten-year study of management</a>.</p>
<p>Most people simply stop at national culture, which would be a disservice. The fact is culture binds people in groupings beyond geographical boundaries. Logical groups such as organisations will have its own culture, and if we expand our magnification level, we’ll note that departments might have its own sub-culture too. Look closer again and you might pick out individual teams as having their own culture quirks. And that is the messy reality when we try to study culture and how it affects everything from strategy implementation to hiring an employee.</p>
<p>And how exactly does one study culture? My next post will detail some <a href="/elements-culture-onion/">basic elements of culture</a> and a simple analytical tool that might help uncover the nuances of culture.</p>]]></content></item><item><title>Yet another Tech blog?</title><link>https://www.coderfrontline.com/yet-another-tech-blog/</link><pubDate>Sun, 06 Mar 2016 15:00:53 +1200</pubDate><guid>https://www.coderfrontline.com/yet-another-tech-blog/</guid><description>&lt;p>Oh no – not another one! Yes, I’ll be the first to acknowledge that there are probably enough programming and tech blogs out there. I’m doing this because I believe I have a unique perspective to share that you’ll be interested in. Coder on the Frontline is a blog focused around the realities of commercial software development today – think missed deadlines, incomplete requirements, Agile fanatics, and that latest buzzword ‘DevOps’. I can see you nodding your head already.&lt;/p></description><content type="html"><![CDATA[<p>Oh no – not another one! Yes, I’ll be the first to acknowledge that there are probably enough programming and tech blogs out there. I’m doing this because I believe I have a unique perspective to share that you’ll be interested in. Coder on the Frontline is a blog focused around the realities of commercial software development today – think missed deadlines, incomplete requirements, Agile fanatics, and that latest buzzword ‘DevOps’. I can see you nodding your head already.</p>
<p>I will also be sharing my thoughts on the world surrounding software development. We don’t work in a vacuum – there’s testing, customer support, sales, management – the list goes on. They’re happening around us at the same time, and the more we know about them, the better we can do our jobs. I aim to build that bridge between programmers and everyone else.</p>
<p>A little backstory: I finished my degree in Software Engineering in 2006, and went straight to work for an R&amp;D team in an American multinational specializing in test and measurement. I enjoyed the benefits of working for a large company – subsidized lunches, free GP visits, and free t-shirts with the latest department initiatives emblazoned across it. On the other hand, I felt increasingly constrained on multiple levels. I was a human resource – more resource, not so much human. I was merely a number, literally, as all company resources had to be accessed using our employee ID.</p>
<p>I hatched an escape plan, and in 2011 I made my way to New Zealand armed with 3 bags and a work visa. I had never travelled outside Asia, and only 9 months to find permanent work or leave.  A risky proposition, but I was prepared to fail and head home. Fortune favours the bold (and the right economic climate), because I was lucky to find a coding job in Auckland after 8 weeks. That’s where I’ve worked at for the past 5 years, and what a difference it was. It’s a small family-run firm with a niche product and market. At under 30 people in the whole place, there are no employee IDs and we developers have to do more than just cut code. I finally discovered the human portion of ‘human resource’.</p>
<p>I had grown enough that I began wondering “What’s next?” and that eventually led me to study towards a Graduate Diploma in Strategic Management. As of this writing I’m 8 months from completing my studies with the Open Polytechnic, and the things I’ve learned have spurred me to create this blog. I see my daily work through fresh lenses now, and it is my hope to empower you to do the same.</p>
<p>I am by no means an expert (Tip #1: be wary of anyone calling themselves an expert), so I invite you to join the conversation and learn from each other. I will reflect and share my thoughts on a variety of issues – from strategy to coding reviews to politics (yes, even politics). It may get a bit ugly, but that’s life for coders on the frontline!</p>]]></content></item></channel></rss>