tag:blogger.com,1999:blog-41753110487043324082024-01-01T21:38:30.532-08:00Can't Grok, Won't Grok<i><b>grok</b> (grŏk) (Slang)
To understand profoundly through intuition or empathy.</i>Rob Cooperhttp://www.blogger.com/profile/04578932741770127659noreply@blogger.comBlogger162110tag:blogger.com,1999:blog-4175311048704332408.post-34170485499543791402021-03-18T00:13:00.006-07:002021-03-18T03:11:08.039-07:00Technical Debt - The Unseen and Surprising<h2>TL;DR;</h2>
<ul>
<li>We accrue technical debt in different, often unseen and innocent ways:
<ul>
<li>'Unexpected' - created by unpredictable or aggressive change.</li>
<li>'Unintended' - created by something missed at the design/development phase.</li>
<li>'Tools and Tech' - opportunity cost of <em>not</em> leveraging faster, more effective tooling and technologies.</li>
<li>'Team changes' - codebase incoherence due to number of contributors (who may no longer be part of the team).</li>
</ul>
</li>
<li>As with all work - get it into the backlog so it's visible.</li>
<li>Weigh up not only the cost of clearing technical debt, but also the value <em>gained</em> from clearing <em>quickly</em>.</li>
<li>If you can't 'sell' the benefits of a refactoring - you probably shouldn't do it.</li>
</ul>
<hr />
<p>'Technical Debt' (Tech Debt) is explained nicely by <a href="https://en.wikipedia.org/wiki/Technical_debt">Wikipedia</a>:</p>
<blockquote>
<p>Technical debt (also known as design debt or code debt, but can be also related to other technical endeavors) is a concept in software development that reflects the implied cost of additional rework caused by choosing an easy (limited) solution now instead of using a better approach that would take longer.</p>
</blockquote>
<p>Many roll with the financial metaphor and discuss 'interest' (time, effort) to clear the debt.</p>
<p>Tech debt is recognition that "we're <em>intentionally</em> cutting corners here". This may <em>sound</em> bad - but there's several great reasons to do take on tech debt - to name a few:</p>
<ol>
<li><strong>Speed to market</strong> - especially if a new product where scale and reliability are less important than early user feedback.</li>
<li><strong>Beta testing</strong> - similar to the above - but normally to a closed group. While we may not ship the product to the public - we're willing to 'roll forward' with warts-and-all. This is very typical in Scrum teams where Products are continuously incremented.</li>
<li><strong>Deadlines</strong> - the <em>real</em> kind. While generally rare - they do exist. Contractual or legal obligations may force corners to be cut.</li>
</ol>
<p>I believe these are well understood - and often agreeable. <em>However,</em> I keep seeing 'Technical Debt' getting used for very different types of problems. They need different approaches to solve.</p>
<h2>Traditional Tech Debt</h2>
<p>Let's get the common and easy one out of the way. <strong>When knowingly cutting corners, define up-front when you expect/want to pay that debt off.</strong> Similar to how you'd take out a loan.</p>
<p>For example:</p>
<ul>
<li>"We know this won't scale" - "When we hit a sign up rate of X/Y, we'll get this into the next Sprint"</li>
<li>"We want to get this out ASAP, with some known bugs" - "We'll clean these up next Sprint"</li>
<li>"To meet contratual agreements - we'll do X, but we must spend the next Y Sprints cleaning up"</li>
</ul>
<p>Generally speaking - the more 'interest' you need to pay, it's best done quickly.</p>
<h2>Unexpected Tech Debt</h2>
<p>Increasingly common - especially with the rise of more highly distributed, service-orientated systems. Essentially <strong>the system becomes a victim of it's own success and/or isn't refactored quickly enough to meet rapidly-changing business demands.</strong></p>
<p>For example:</p>
<ul>
<li><strong>Explosion of usage</strong> (e.g. increased user counts, taking an API public) means that the system is now operating way beyond it's original design. For example: Data stored may not be partitioned effectively given the new usage patterns.</li>
<li><strong>What <em>seemed</em> sensible at the time... Wasn't.</strong> While moving fast - things might get implemented in the heat of the moment - and look fine. The holistic view of the system is missed - and a key refactoring should have taken place to accommodate the new demand. For example: Addition of new markets introducing cross-cutting, leaky models into an architecture.</li>
</ul>
<p>These ones are very tricky and frankly - often painful for the development team. They could start to manifest as performance issues. Or, the 'awesome team that made this business' suddenly starting to look slow and like a bug factory.</p>
<p>A typical phrase I use when working with a team experiencing these is:</p>
<blockquote>
<p>"Knowing what you know now - how would you build it?"</p>
</blockquote>
<p>If the solution is architecturally very different - you've likely got some unexpected tech debt.</p>
<p>As soon as these are identified - <em>get them in the backlog</em>. Make sure the Product Owners are <em>extremely</em> aware of the problem and how <strong>it's only going to get worse</strong>. Sitting down and devising some immediate (albeit hacky) mitigations while figuring out a long-term fix is often needed. Give the Product Owner options to work with.</p>
<h2>Unintended Tech Debt</h2>
<p>If 'unexpected' is the tech debt created in the future, 'unintended' is created in the past. This is essentially <strong>"we built with the best of intentions, but we missed something"</strong>.</p>
<p>Again, this is becoming increasingly common - especially with the glorification of phrases like "move fast and break things".</p>
<p>I like to throw different ones around like:</p>
<ul>
<li>"Don't break the till" (or 'cash register' for our friends speaking American English 😊). If people can't pay, you don't get paid.</li>
<li>"Don't break the door" - No signups, no users - not to mention reputation damage. Ever seen a busted door during a extremely successful marketing campaign? Not pretty.</li>
</ul>
<p>There are certain areas where unintended tech debt can be <em>very</em> damaging - so extra care/attention is required. I'm not advocating <a href="https://en.wikipedia.org/wiki/Big_Design_Up_Front">"Big Design Up Front" (BDUF)</a>, but "care and attention to details when and where it matters".</p>
<p>This kind of tech debt can vary in severity based on what's affected. However, normally these come as a nasty shock to the team and can result in high-priority fixes. Not only do these lower the profile of the development team, but also ruin plans in progress. Not fun for anyone involved.</p>
<p>The key here is quality design and testing. Spend <em>enough</em> time in the design/modelling phase. What's your testing plan? Do you have adequate time to perform exploratory testing? What else can be <a href="https://en.wikipedia.org/wiki/Shift-left_testing">shifted-left</a>?</p>
<h2>Tech and Tools</h2>
<p>It's worth highlighting these because:</p>
<h3>Tools and technologies evolve</h3>
<p>What was good yesterday, may be superseded tomorrow by something 100x better. <em>Not</em> leveraging that can introduce debt due to opportunity cost etc.</p>
<p>To help overcome this - I think best thing is a <strong>healthy culture of curiosity, learning and sharing</strong> among the developers. We can't learn <em>everything</em> so spread the load and get talking about the highlights!</p>
<p>Make sure you and your team has the freedom to learn, play and discover what's new and upcoming so they can be ready to run with it.</p>
<h3>Platforms change, as do their costs</h3>
<p>I remember having to rent fixed kit with a fixed cost (👴). We now live in incredible times with a veritable feast of <a href="https://en.wikipedia.org/wiki/Platform_as_a_service">PaaS</a> options on the table. These are constantly evolving - potentially offering (significant) cost savings both in usage and (often more importantly) saved developer time and cognitive load.</p>
<p>Similar to the above - a healthy culture creating awareness is key. If you're in an organisation large enough to have Architects around - this should absolutely be one of their core objectives to be on top of this.</p>
<h2>Team Changes</h2>
<p>We work in teams with multiple Developers. There's churn. A lot of opinions end up in the code. You end up with code that's "kind of OK", but over time has become increasingly awkward or downright dangerous to work with. Yes, we know "it needs a refactor, and better tests". But, few are willing to do it given the risks it <em>might</em> introduce.</p>
<p>Whenever I am working with teams and hear grumbles of "oh no, we need to go near <em>that</em>", I'll start to ask what their understanding of the problem(s) are, how they intend to fix it, and risks.</p>
<p>If it feels like a <a href="https://en.wikipedia.org/wiki/Spike_(software_development)">spike</a> is needed to work out answers, then we'll do that.</p>
<p>Once we're armed with plan and possible solution(s) - I'll then ask:</p>
<ul>
<li>"What is your estimate if we <em>don't</em> take time to fix this?"</li>
<li>"... and what if <em>had</em> fixed it, per this plan?</li>
</ul>
<p>If the plan means smaller, more confident estimates - we likely commit to it. <em>Especially</em> if we know that there's a lot of change in that area coming up. Having several 5-pointers turn into a series of 2's by taking the time to 'finally fix that thing' not only feels good from a planning point-of-view, but general pride in the codebase.</p>
<h2>'Dislike' Isn't 'Debt'</h2>
<p>This is the one that tends to lose me most friends 😉 It's important to call it out though, because <strong>it's doing us harm.</strong></p>
<p>When adding tech debt to the backlog - <strong>it needs to be based on 'this is causing objective pain'</strong> - not "I don't like it" or "this would be cool".</p>
<p>This will often manifest as "The Great Refactoring", only to discover one or more of the following:</p>
<ol>
<li>It's in a part of the codebase that's barely touched - and no further changes needed on the horizon.</li>
<li>The developer flew solo - often creating more of the 'incoherence' problem. They dip in, changing patterns/conventions in place <em>in just that bit</em> - may look good for them, but the wider team now struggles with it.</li>
<li>It was an opportunity to introduce {coolest pattern/technology of the day} - often <em>adding</em> complexity rather than taking it away.</li>
<li><strong>The Product Owner doesn't really 'get' it, and trusted the developer in that 'we just need it'.</strong></li>
</ol>
<p>This is tricky to pick up. It <em>can</em> be difficult to judge if a refactor adds <em>enough</em> value. It's important that we try though because <strong>these low/no/negative value-add refactorings cost time, energy but more importantly - <em>trust</em>.</strong></p>
<p>As <em>professionals</em> we need to work with our Product Owners and the rest of the team, and be conscious of the investment (our time, opportunity cost, increases in complexity) we're proposing.</p>
<p>A good way of getting a sense of it is to simply do the maths! Take your daily salary - plus some for that of your <a href="https://en.wikipedia.org/wiki/Pair_programming">pair</a>. Guesstimate time you're going to spend on it - what would be required to get that return on investment back? This can be a real eye-opening experience - especially when you consider that some people go down the rabbit hole for entire <em>Sprints</em> or more.</p>
<p>In my experience - there's two common warning signs:</p>
<ol>
<li>'Tech Debt' Sprints appearing on plans.</li>
<li>Developer X (often a senior) doing a 'thing' for days/weeks that no-one else on the team can really explain. But "they know what they're doing".</li>
</ol>
<p>Arguably - local leadership could/should pick this up, but we're all human. Everyone has good intentions.</p>
<p>So, <strong>be conscious of your investments. If you can't 'sell it' to your Product Owner (as you should), skip it</strong> (or spend more time figuring out the benefits).</p>
<h2>To close...</h2>
<p>Not all tech debt is created equal, much (most?) of it is unintentional. This unintentional debt often has very negative side effects when it becomes apparent. There's several warning signs we can look out for. Once discovered, get it into your backlog to review and resolve.</p>
<p>Understanding the cost of both paying off the debt, and <em>delay</em> in paying of the debt are key for prioritising.</p>
<p>Work with your Product Owner - if you can't 'sell' a refactoring, you probably shouldn't be doing it. Present options/trade-offs. <em>Negotiate</em>.</p>
<p>Now go create.</p>
<p>Happy hacking!</p>
Rob Cooperhttp://www.blogger.com/profile/04578932741770127659noreply@blogger.com0tag:blogger.com,1999:blog-4175311048704332408.post-37329482665198464182021-03-18T00:05:00.001-07:002021-03-18T02:13:17.778-07:00Deliberate Practice for Programmers - Learn a New Language!<p>In the last post - we talked about <em>why</em> deliberate practice is important, and that I aim to approach my practice with:</p>
<ol>
<li><strong>Purpose</strong> - I’m spending my non-refundable time on something, I want it to count.</li>
<li><strong>Plan</strong> - Before I start, I think about how I’m going to <em>structure</em> my practice so that it (hopefully) meets it’s purpose.</li>
<li><strong>Progress</strong> - Ensuring I take time to reflect on the practice, and adjust as necessary.</li>
</ol>
<p>To get specific (we’re programmers, after all) - this translates to:</p>
<h2 id="defining-purpose">Defining Purpose</h2>
<p>Creating plans to exercise ‘something’ that I encounter in my career - for example (and this list is <em>far</em> from exhaustive):</p>
<ol>
<li>Learning a new programming language.</li>
<li>Working with different IDE’s to develop and debug.</li>
<li>Traversing and processing data.</li>
<li>Effective automated testing. From unit to end-to-end.</li>
<li>Creating build and deployment pipelines.</li>
<li>Working with different databases and ORMs.</li>
<li>Performance profiling and testing.</li>
<li>Finding memory leaks.</li>
<li>Rapid prototyping.</li>
<li>Paradigm shifts - e.g. object-oriented to functional.</li>
</ol>
<p>I will find myself in a situation where either I or a colleague needs some help with a specific area - I then go to my list and see if I either have something defined that works, or start defining what I want from the session based on needs.</p>
<h2 id="defining-a-plan">Defining a Plan</h2>
<p>Given the <em>Purpose</em> I then start to think about a <em>Plan</em>.</p>
<p>Let’s say I want to pick up a new language as the client I am working with is on a different stack. I think I generally need to:</p>
<h3 id="get-the-basics">1. Get the basics</h3>
<p>Can I <em>start</em> to express myself in the new language?</p>
<ol>
<li>How do I define basic types? (Integers, Floats, Booleans, Strings, Array)</li>
<li>How do I concatenate or interpolate strings?</li>
<li>How do I read from/write to the console?</li>
<li>What are the basic control flow statements? (<code>if/else</code>, <code>foreach</code>, <code>switch</code> etc.)</li>
<li>How do I define functions and methods?</li>
<li>Can I define anonymous functions?</li>
<li>How do I control the <em>visibility</em> of those functions and methods?</li>
<li>How do exceptions work? How do I handle them?</li>
</ol>
<p>This stage is generally easier if you know how to code already - you’ll often ask “<em>How do I do X in Y?</em>” This can lead to easier searches. However, having a checklist makes as a great teaching aid for fledgling programmers.</p>
<p>By the time I’m done with this list - I’m <em>generally</em> able to bumble my way through a problem.</p>
<h3 id="get-productive-and-effective">2. Get Productive and Effective</h3>
<p>Now that I can write <em>some</em> code - I am starting to think more about how it’s really <em>working</em>:</p>
<ul>
<li>How do I define, run and interpret automated tests?</li>
<li>What data structures do I have available to me? How could/would I implement them if not?</li>
<li>What foundation / base libraries do I have available for common things - for example collections, HTTP, serialisation etc.</li>
<li>How do I use packages/modules that others have created?</li>
</ul>
<p>At this stage, I’m probably starting to feel a lot more confident. I’ve got tests backing up my work and I’m using tried-and-tested code from others where possible.</p>
<h3 id="optimise">3. Optimise!</h3>
<p>I’m writing code - but it’s likely not the ‘best’ code. I’m likely upsetting the veterans in the codebase with every pull request. Now I start to think about:</p>
<ul>
<li>Going ‘native’ - how do I write more idiomatic code for that language? Is the method named <code>IsAuthenticated</code>, <code>isAuthenticated</code>, <code>is_authenticated</code>, <code>is_authenticated?</code> or <code>HOW IZ I AUTHENTICATED YR USER</code>?</li>
<li>Thinking about performance - using correct data structures (because not everything belongs in an array, y’all), understanding how they’re traversed etc.</li>
<li>Being conscientious with memory usage - how do I get stuff off the heap? Reduce allocations etc.</li>
</ul>
<h2 id="reflect-on-progress">… Reflect on Progress</h2>
<p>I’ll open up some notes, and work my way through the above, in order. Getting “the basics” might take an hour or so. From there, I’ll try and start solving some simple problems via Katas.</p>
<p>As I start to learn more (e.g. more expressive/cleaner ways of saying things) - I’ll continually refine my notes.</p>
<p>I get a real sense of achievement in seeing my notes evolve. <strong>Going back to something you’ve <em>personally</em> written and editing/improving <em>proves</em> progress.</strong></p>
<p>I’ll also solidify/verify the growth by tackling random coding problems (e.g. from the likes of <a href="https://www.codingame.com/">CodinGame</a> or <a href="https://www.codewars.com/">CodeWars</a>).<br>
It’s amazing how quickly you can get <em>something</em> going!</p>
<p>Rinse and repeat!</p>
<h1 id="enough-talk-lets-code">Enough Talk, Let’s Code!</h1>
<p>We’ve outlined a plan - let’s go learn the basics of a new language!</p>
<p>Now - my ‘home’ language is C#, but I’ve done some JavaScript, TypeScript, Python, Ruby and Java at varying levels. I’m gonna pick a random just for funsies - <a href="https://elixir-lang.org/">Elixir</a>.</p>
<p>🥰 Big thanks to the awesome that is <a href="https://repl.it/l">repl.it</a> for enabling me to hack in a browser-based IDE! I highly recommend trying it (or similar) so that you can get to <em>the language</em> without worrying about IDE setup etc.</p>
<h2 id="run-the-list">Run the List</h2>
<pre class=" language-elixir"><code class="prism language-elixir"><span class="token comment"># How do I define basic types? (Integers, Floats, Booleans, Strings, Array)</span>
a_int <span class="token operator">=</span> <span class="token number">1</span>
a_float <span class="token operator">=</span> <span class="token number">1.0</span>
a_bool <span class="token operator">=</span> <span class="token boolean">true</span>
a_str <span class="token operator">=</span> <span class="token string">"Elixir"</span>
a_arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span>
<span class="token comment"># How do I concatenate or interpolate strings?</span>
ans <span class="token operator">=</span> <span class="token string">"Forty-two"</span>
meaning <span class="token operator">=</span> <span class="token string">"The answer to the great question.. Of Life, the Universe and Everything.. Is.. <span class="token interpolation"><span class="token delimiter punctuation">#{</span>ans<span class="token delimiter punctuation">}</span></span>."</span>
<span class="token comment"># How do I read from/write to the console?</span>
user_name <span class="token operator">=</span> IO<span class="token punctuation">.</span>gets<span class="token punctuation">(</span><span class="token string">"What's your name? "</span><span class="token punctuation">)</span> <span class="token comment"># Trailing space to look nicer in console</span>
IO<span class="token punctuation">.</span>puts<span class="token punctuation">(</span><span class="token string">"Hello, <span class="token interpolation"><span class="token delimiter punctuation">#{</span>user_name<span class="token delimiter punctuation">}</span></span>!"</span><span class="token punctuation">)</span>
<span class="token comment"># Note that you get the trailing newline with gets- so you'll likely want to trim</span>
x <span class="token operator">=</span> String<span class="token punctuation">.</span>trim<span class="token punctuation">(</span>IO<span class="token punctuation">.</span>gets<span class="token punctuation">(</span><span class="token string">"?"</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
x <span class="token operator">=</span> IO<span class="token punctuation">.</span>gets<span class="token punctuation">(</span><span class="token string">"?"</span><span class="token punctuation">)</span> <span class="token operator">|></span> String<span class="token punctuation">.</span>trim<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment"># Can also pipe - easier on the eyes?</span>
<span class="token comment"># What are the basic control flow statements? (`if/else`, `foreach`, `switch` etc.) </span>
<span class="token comment"># https://elixir-lang.org/getting-started/case-cond-and-if.html</span>
<span class="token comment"># https://elixir-lang.org/getting-started/recursion.html</span>
<span class="token keyword">if</span> <span class="token boolean">true</span> <span class="token keyword">do</span>
<span class="token comment"># ...</span>
<span class="token keyword">else</span>
<span class="token comment"># ...</span>
<span class="token keyword">end</span>
<span class="token keyword">unless</span> <span class="token boolean">true</span> <span class="token keyword">do</span>
<span class="token comment"># ...</span>
<span class="token keyword">end</span>
<span class="token keyword">for</span><span class="token punctuation">(</span>i <span class="token operator">=</span> <span class="token number">0</span>; i <span class="token operator"><</span> sizeof<span class="token punctuation">(</span>array<span class="token punctuation">)</span>; i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
array<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> array<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">*</span> <span class="token number">2</span>;
<span class="token punctuation">}</span>
<span class="token comment"># Enum module also has map and reduce functions</span>
<span class="token comment"># https://elixir-lang.org/getting-started/enumerables-and-streams.html#enumerables</span>
Enum<span class="token punctuation">.</span>map<span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token keyword">fn</span> x <span class="token operator">-></span> x <span class="token operator">*</span> <span class="token number">2</span> <span class="token keyword">end</span><span class="token punctuation">)</span>
<span class="token comment"># [2, 4, 6]</span>
IO<span class="token punctuation">.</span>puts<span class="token punctuation">(</span>Enum<span class="token punctuation">.</span>reduce<span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">fn</span> x<span class="token punctuation">,</span> acc <span class="token operator">-></span> acc <span class="token operator">+</span> x <span class="token operator">*</span> <span class="token number">2</span> <span class="token keyword">end</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token comment"># 12</span>
beats <span class="token operator">=</span> <span class="token keyword">case</span> play <span class="token keyword">do</span>
<span class="token string">"scissors"</span> <span class="token operator">-></span> <span class="token string">"paper"</span>
<span class="token string">"paper"</span> <span class="token operator">-></span> <span class="token string">"rock"</span>
<span class="token string">"rock"</span> <span class="token operator">-></span> <span class="token string">"lizard"</span>
<span class="token string">"lizard"</span> <span class="token operator">-></span> <span class="token string">"spock"</span>
<span class="token string">"spock"</span> <span class="token operator">-></span> <span class="token string">"scissors"</span>
<span class="token string">"scissors"</span> <span class="token operator">-></span> <span class="token string">"lizard"</span>
<span class="token string">"lizard"</span> <span class="token operator">-></span> <span class="token string">"paper"</span>
<span class="token string">"paper"</span> <span class="token operator">-></span> <span class="token string">"spock"</span>
<span class="token string">"spock"</span> <span class="token operator">-></span> <span class="token string">"rock"</span>
<span class="token string">"rock"</span> <span class="token operator">-></span> <span class="token string">"scissors"</span>
<span class="token keyword">end</span>
<span class="token comment"># How do I define functions and methods?</span>
<span class="token comment"># (Elixir is functional, and doesn't have concept of Objects, Classes and Methods)</span>
<span class="token keyword">defmodule</span> MyModule
<span class="token keyword">def</span> sum<span class="token punctuation">(</span>a<span class="token punctuation">,</span> b<span class="token punctuation">)</span>
a <span class="token operator">+</span> b
<span class="token keyword">end</span>
<span class="token keyword">end</span>
<span class="token comment"># How do I control the visibility of those functions and methods?</span>
<span class="token keyword">defp</span> im_a_private_function
<span class="token comment"># ...</span>
<span class="token keyword">end</span>
<span class="token comment"># Can I define anonymous functions?</span>
sum <span class="token operator">=</span> <span class="token keyword">fn</span> <span class="token punctuation">(</span>a<span class="token punctuation">,</span> b<span class="token punctuation">)</span> <span class="token operator">-></span> a <span class="token operator">+</span> b <span class="token keyword">end</span>
sum <span class="token operator">=</span> <span class="token capture function">&</span><span class="token punctuation">(</span><span class="token argument variable">&1</span> <span class="token operator">+</span> <span class="token capture function">&b</span><span class="token punctuation">)</span> <span class="token comment"># Shorthand using &</span>
<span class="token comment"># Note, these need to be called with .</span>
x <span class="token operator">=</span> sum<span class="token punctuation">.</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span> <span class="token comment"># -> 5</span>
<span class="token comment"># How do exceptions work? How do I handle them?</span>
<span class="token comment"># https://elixir-lang.org/getting-started/try-catch-and-rescue.html</span>
raise ArgumentError<span class="token punctuation">,</span> <span class="token attr-name">message:</span> <span class="token string">"Argument out of range"</span>
<span class="token keyword">try</span> <span class="token keyword">do</span>
<span class="token comment"># ...Code that might raise</span>
<span class="token keyword">rescue</span>
ArgumentException <span class="token operator">-></span> <span class="token string">"Caught the ArgumentException"</span>
<span class="token keyword">end</span>
<span class="token comment"># Define custom exceptions via a Module with defexception</span>
<span class="token keyword">defmodule</span> MyError
<span class="token keyword">defexception</span> <span class="token attr-name">message:</span> <span class="token string">"Default message"</span>
<span class="token keyword">end</span>
</code></pre>
<h1 id="now-go-play...">Now Go Play…</h1>
<ol>
<li><strong>Define a <em>Purpose</em></strong> - What would you like to learn? Try to keep this in the abstract so it will be reusable for exploring similar scenarios. “Languages” over “C#”, “Build Systems” over “TeamCity”, “Cloud” over “Azure”.</li>
<li><strong>Define a <em>Plan</em></strong> - How will you go about exploring? Make a list - or map - to keep you focused. Iterate and refine this map as you learn more about this “type” of problem. For example - anonymous functions are so useful for cleaning up code, so I added a specific item for in to my list above to make sure I found out if it’s possible, and how to do it.</li>
<li><strong>Reflect</strong> - How will you solidify your learning? What’s next? I really like to have some kind of physical output here - <strong>working code FTW</strong>, but - it’s your practice! Do what you like!</li>
</ol>
<p>Now go practice.</p>
<p>Happy hacking! 🤩</p>Rob Cooperhttp://www.blogger.com/profile/04578932741770127659noreply@blogger.com0tag:blogger.com,1999:blog-4175311048704332408.post-89500488061773705262020-12-06T12:59:00.002-08:002021-03-18T02:12:34.996-07:00Programmers Need Deliberate Practice<h2 id="tldr">TL;DR;</h2>
<ul>
<li>Consistent, effective practice is a key part of a healthy, enjoyable career.</li>
<li>Most people practice without purpose.</li>
<li>This means they either quit and/or learn less than they could.</li>
<li>Read this for inspiration on how to take a more considered approach to your practice.</li>
</ul>
<p><em>Note: I’m English, but opted for the US English spelling of ‘Practice’ throughout (as opposed to ‘practise/practice’) to avoid confusion with the difference in spelling within the term ‘Deliberate Practice’.</em></p>
<h2 id="practice">Practice?</h2>
<p>I think we can all agree on a couple of things:</p>
<ol>
<li>People who are experts practice often.</li>
<li>Experts are extremely disciplined with their practice.</li>
</ol>
<p>This will generally come as no surprise when I mentioned, and people will rarely argue those points. They make sense.<br>
Thanks to the growing number of interviews and podcasts - experts are getting more limelight, and we’re getting more sneak-peeks into that practice routines, habits and rituals (podcasts like Tim Ferriss’ are awesome for this).</p>
<p><em>However</em> - the one thing that <em>does</em> surprise me when I ask my peers what <em>their</em> practice schedule/routine is - I’m met with blank faces/realisations of “oh, I don’t have one”.</p>
<p>If they do - it will likely be something that will be pretty loose/unregimented. So if then prodded on the <em>effectiveness</em> of that practice - we’re back to blank faces. <strong>I don’t want that - I want to meet up with people and have them bursting with excitement on how they’re growing.</strong></p>
<p>The idea of effective practice has been has been solidified with the concept of <em>deliberate</em> practice. That we shouldn’t just “go through the motions” - but need to take a considered, thoughtful approach to our practice - that ensures we <strong>get outside our comfort zone and <em>grow</em>.</strong></p>
<p>This is important - because I feel this is something that is <em>sorely</em> missing from the tech community generally. Many of us tend to hack around on things, work on side projects, contribute to open source etc. - which are all <em>AWESOME</em>. But how many of us take a disciplined, thoughtful approach to learning, growing and <em>honing</em> our skillset?</p>
<p>To be clear - I’ve been hit-and-miss over the years as well - which is why I’m spending real time on it now, and want to help you while I’m at it!</p>
<p>This is <em>important</em> and something I deeply care about - we’re all time-poor, and what you spend you aren’t getting back. <strong>Make it count!</strong></p>
<h2 id="common-problems-with-peoples-practice">Common Problems with People’s Practice</h2>
<ol>
<li><strong>They don’t have one!</strong> Pretty self-explanatory.</li>
<li><strong>Lack of direction.</strong> They do things ‘just because’ - and work through the motions rather than aim for growth.</li>
<li><strong>Lack of relevancy.</strong> The practice doesn’t seem relevant/useful to their day-to-day, so they either don’t engage well with it - or bin it.</li>
<li><strong>Scope too large.</strong> They never get to an “ah-ha” moment - normally ending the session with frustration and lack of desire to come back. This often occurs when we either don’t have enough direction/leading questions and/or we’ve not identified the 20% we need to practice to give 80% of understanding (see ‘Pareto Principle’).</li>
<li><strong>Additional noise unrelated to the desired growth area.</strong> Perhaps you want to practice with a certain design pattern, but spent over an hour battling framework incompatibility issues instead.</li>
</ol>
<h2 id="but-what-about-katas">But What About Katas?</h2>
<p>I know some of you are thinking “Rob! I know, this is why we do Katas!”. I hear you, but I’ve been doing and leading these for years and I have to say - the results vary <em>wildly</em> - sadly leaning on the side of ‘poor’.</p>
<p>For the uninitiated - a ‘Kata’ (the term taken from the usage in martial arts) is essentially repetition of a problem to see how we solve it. Better people than me have done a lot of write-up on this - so check out the links if you want more info. Essentially a kata will play out like:</p>
<ol>
<li>Bunch of coders get in a room.</li>
<li>They solve a pre-defined problem.</li>
<li>They discuss their code/thought-processes/lessons learned etc.</li>
</ol>
<p>Now, these are great - and if you’ve not done one. Do! They’re great fun, and you <em>will</em> learn <em>something</em>. I’ll link to a few at the end of this post for you.</p>
<p>I think part of the problem is that perhaps ‘Kata’ isn’t an adequate analogy. Katas are about increasing muscle memory or certain movements (getting progressively harder as you gain skills). I think Katas like this have a place, and I will continue to do them (The Gilded Rose is awesome, for example). But I think there’s a missing piece - and once found (and done well) you can do away with ‘repetitive’ Katas all-together.</p>
<p>The goal of this series of blog posts is to help do just that! 🥋 😁</p>
<h2 id="if-not-katas-then-what">If Not Katas, Then What?</h2>
<p>I’m not suggesting you do away Katas. I don’t care for reinventing things that are (<em>mostly</em>) working well. Let’s just change up how you prep for them. I always think “3 P’s”:<br>
1. <strong>Purpose</strong> - Why are you doing this? Is it meaningful to your life right now?<br>
2. <strong>Plan</strong> - How are you going to <em>effectively</em> meet the <em>purpose</em> of the Kata? (Read: “remove the noise, stay focused, get outside comfort zone, learn”).<br>
3. <strong>Progress</strong> - Reflect. What d-id you learn? What <em>didn’t</em> you learn? (You may discover way after doing the Kata! Go back and update it!) How will you take this forward into current/future projects?</p>
<p>Now each Kata <em>should</em> standardise points 1 and 2 (Purpose and Plan). <strong>Most katas lack focus</strong> (sound familiar? ‘Stories’ anyone? <em>Cough</em> 😂) <strong>and/or don’t get you reaching outside your comfort zone enough.</strong> Many people will solve the problem with what they know, and quickly move on. If you take just <em>one</em> thing from this post - take 5-10 mins to <em>think</em> before you practice about <em>WHY</em> you’re practicing.</p>
<p>Point 3 (Progress) is often done well (I always enjoy the group chats) - <strong>but I rarely (if ever) see Katas <em>refined</em>.</strong></p>
<p>So, let’s walk through some quick examples! .⚠️ This series of posts <em>will</em> go into more detailed examples - this is just a primer to get you going/thinking!</p>
<h2 id="ideas-to-get-startedimprove">Ideas to Get Started/Improve</h2>
<h3 id="gilded-rose">Gilded Rose</h3>
<p>This is one of my favourite Katas - and it will always have a special place in my heart. So let’s start with that one.</p>
<ol>
<li>If you’ve not done it before - just do it as per the README. 🚧</li>
<li>Now consider the <em>purpose</em> - we’re talking about <em>refactoring</em> here - so what common problems come in to play? The goal of refactoring is to make the code easier to understand and (perhaps) easier to extend in the future. Here’s some ideas:
<ul>
<li>Pair up with someone else! Does the refactoring make sense to you both as you go?</li>
<li>“Person down the hall test” - fly solo and then have a peer review your code <em>from cold</em> at the end. For an added twist - submit the code anonymously, and only let them view it as a pull request. How quickly can the understand the code and the reason for your changes?</li>
<li>Define one or more <em>additional</em> requirement - but keep it secret until the end of the Kata and ask participants “What if?” The purpose is then the conversation, not the code.</li>
<li>Consider the <em>test runner output</em> - if there’s a failure when adding new behaviours - <em>do those failure messages make it clear what the expectation is?</em></li>
</ul>
</li>
</ol>
<h3 id="frameworks-patterns-and-paradigms">Frameworks, Patterns and Paradigms</h3>
<p>Last, but not least to plant the seeds of some of what’s to come in this series. What about <em>frameworks, [design] patterns and [modelling] paradigms</em>?</p>
<p>Now these are everywhere - likely cross multiple layers (which each has their own <em>purpose</em>. But here’s some points to consider for some common ones:</p>
<ul>
<li><em>UI</em> - How do we bind to the UI to data? How do we maintain isolation across elements? How do we isolate elements to begin with? How do we cache content? How is that parameterised? How do we bind elements to data? What trade-offs does that design bring? How do we augment content based on device capability?</li>
<li><em>Data modelling (and implementation)</em> -</li>
<li><em>Database access (and ORMs)</em> - How do we do basic CRUD operations? How do we do single property/column updates? How do we examine the execution plan and/or examine query performance? How/when do indexes/pages lock? How do we effectively partition data?</li>
<li><em>Messaging</em> - What options do we have for sending messages across boundaries? What about receiving <em>and</em> processing them? What trade-offs do each entail? What patterns exists for common systems (e.g. eCommerce, Chat, Streaming, Gaming)</li>
</ul>
<h3 id="others">Others</h3>
<p>Other (but equally important) areas to note:</p>
<ul>
<li><em>Algorithms</em> - What algorithms can be used given the problem? What are the pros/cons/trade-offs?</li>
<li><em>Data Structures</em> - Similar to the above - how can the data structures used by the code be changed/effect the outcome?</li>
<li><em>Performance</em> - Under what circumstances does your code perform well? When <em>doesn’t</em> it? Are those OK? Practice identifying the usage patterns and <em>explaining</em> them to mere mortals ☺️</li>
</ul>
<h2 id="in-summary">In Summary</h2>
<p>I hope I’ve given you pause or thought about your practice. Practice is good - <em>great</em> practice is better. Take time to think about the problems you need to solve and <strong>create a method to solve them in a way that gets you <em>growing</em>.</strong></p>
<p>I look forward to sharing more about how I do this - code and all - in this series.</p>
<p>Until then - happy hacking! 🤩💻</p>
<h2 id="links">Links</h2>
<p><em>Some are Amazon links - for which I am an affiliate. I wouldn’t recommend books that I’ve not read and enjoyed.</em> 😉</p>
<ul>
<li><a href="https://jamesclear.com/deliberate-practice-theory">‘Deliberate Practice’ on James Clear’s site</a> (Author of ‘<a href="https://amzn.to/2JSGQg7">Atomic Habits</a>’) - contains some great links to other good articles, too.</li>
<li><a href="https://tim.blog/podcast/">The Tim Ferriss Podcast</a> - Very high-quality interviews of high-performers from all walks of life.</li>
<li><a href="https://github.com/emilybache/GildedRose-Refactoring-Kata">The Gilded Rose Kata on Emily Bache’s GitHub</a> (Author of ‘<a href="https://amzn.to/2JPiaFj">The Coding Dojo handbook</a>’)</li>
<li><a href="https://www.codingame.com/">CodinGame</a> - Great source of problems to solve, with a web-based IDE. I use this almost daily!</li>
<li><a href="https://www.codewars.com/">codewars</a> - Another great source of problems to solve.</li>
<li><a href="http://codekata.com/">CodeKata</a> - One of the original sites - although I don’t think it’s actively maintained/contributed to any more. There’s some classic problems on here worth checking out though.</li>
<li><a href="https://kata-log.rocks">Kata-Log</a> - Nice little library of Katas, including the <a href="https://kata-log.rocks/bowling-game-kata">Bowling Game Kata</a>.</li>
</ul>Rob Cooperhttp://www.blogger.com/profile/04578932741770127659noreply@blogger.com0tag:blogger.com,1999:blog-4175311048704332408.post-68021511482220782012014-01-21T10:52:00.001-08:002014-01-21T10:52:01.337-08:00Using Private NuGet Packages in Azure Web Sites<p>After <em>wayyy</em> too long – I’ve finally started breaking up my code into re-usable components and putting together <a href="http://nuget.org"><strong>NuGet</strong></a><strong> </strong>feeds for them. In many case – I’m trying to put these together into a state that is suitable for others and releasing them as Open Source on <a href="https://github.com"><strong>GitHub</strong></a>.</p> <p>However, there is some code that I don’t want to go out to the public – but I still want to be able to break them up into components and generate NuGet packages for them. Enter the awesome <a href="http://www.myget.org/">MyGet</a>.</p> <p>MyGet allows you to create your own private NuGet feeds <a href="https://www.myget.org/features">amongst a whole load of other cool stuff</a> – now the next challenge: <strong><em>how do I get Azure to build my site and restore the package from the private feed?</em></strong></p> <h3>Enable NuGet Package Restore</h3> <p>This is super-easy, and in many cases you might have already done it .</p> <p>Right click the <em>Solution</em> and click “<strong>Enable NuGet Package Restore</strong>”. This will create a “.nuget” directory within your solution folder. In here are a few key files:</p> <ul> <li>NuGet.Config <li>NuGet.exe <li>NuGet.targets</li></ul> <p>Now – we just need to tell NuGet about our private package feed.</p> <h3>Update Your .targets File</h3> <p>The “.targets” file is the one we’re really interested in. <strong>Open it up in <a href="http://www.sublimetext.com/2">a decent text editor</a>.</strong></p> <p>You will see something like the following:</p><pre class="csharpcode"><span class="kwrd"><</span><span class="html">ItemGroup</span> <span class="attr">Condition</span><span class="kwrd">=" '$(PackageSources)' == '' "</span><span class="kwrd">></span>
<span class="rem"><!-- Package sources used to restore packages. By default, registered sources under %APPDATA%\NuGet\NuGet.Config will be used --></span>
<span class="rem"><!-- The official NuGet package source (https://www.nuget.org/api/v2/) will be excluded if package sources are specified and it does not appear in the list --></span>
<span class="rem"><!--</span>
<span class="rem"> <PackageSource Include="https://www.nuget.org/api/v2/" /></span>
<span class="rem"> <PackageSource Include="https://my-nuget-source/nuget/" /></span>
<span class="rem"> --></span>
<span class="kwrd"></</span><span class="html">ItemGroup</span><span class="kwrd">></span></pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<p>Go ahead and un-comment the “PackageSource elements and replace the “Include” <strong>for the second element</strong> with your private NuGet packages feed URL from MyGet.</p>
<p>This will be something like “<strong>https://www.myget.org/F/your-feed-name/</strong>”.</p>
<h3>Push It!</h3>
<p>If you’re sane – you’ve <a href="http://www.windowsazure.com/en-us/documentation/articles/web-sites-publish-source-control/"><strong>set up Azure to deploy via source control</strong></a>. Go ahead and <strong>git-add</strong> your new files to the repository and push them up to GitHub.</p>
<p>If all goes to plan, your site will be updated using the NuGet package from your private feed.</p>
<p>Happy hacking!</p> Rob Cooperhttp://www.blogger.com/profile/04578932741770127659noreply@blogger.com1tag:blogger.com,1999:blog-4175311048704332408.post-27493667320426275312014-01-20T05:10:00.001-08:002014-01-20T05:10:40.812-08:00Installing Windows Live Writer on Windows 8<p>It’s been a LONG time since I blogged – and I figured I’m going to get back <em>ON IT!</em></p> <p>So – first things first, I needed to install the awesome <strong>Windows Live Writer. </strong>So I Google “Windows Live Writer” – and it brings me to <strong><a href="http://www.microsoft.com/en-gb/download/details.aspx?id=8621">this download page</a>.</strong></p> <p><strong>The problem? </strong>This installer doesn’t work on Windows 8. I get the error message:</p> <blockquote> <p><strong>Couldn’t install programs</strong></p> <p>You already have a more recent version of Windows Live.</p></blockquote> <p>Another quick Google later – and I came across the <strong><a href="http://windows.microsoft.com/en-gb/windows-live/essentials">Windows Live Essentials Page</a></strong> – hit the “Download now” button and you’ll be good to go :)</p> <p><strong>Side Note:</strong> I know that upon expanding “System Requirements” – I can see Windows 8 isn’t listed. But it’s not immediately obvious and the browser knows my OS anyway :P</p> Rob Cooperhttp://www.blogger.com/profile/04578932741770127659noreply@blogger.com0tag:blogger.com,1999:blog-4175311048704332408.post-44194224855914260862013-02-25T23:25:00.001-08:002013-02-25T23:25:43.475-08:00Could not load file or assembly msshrtmi or one of its dependencies<p>So, I recently upgraded my Azure Tools to October 2012, and everything decided to fall apart <em>in my deployment environment</em>. Great. Thanks Microsoft.</p>
<p>I installed the latest tools, fixed the code caused by the <a href="http://blogs.msdn.com/b/windowsazurestorage/archive/2012/10/29/windows-azure-storage-client-library-2-0-breaking-changes-amp-migration-guide.aspx">breaking changes in the Azure Storage Client Library</a> and then having tested locally - fired off a deployment to Azure.</p>
<p>I then got greeted with a YSOD saying:</p>
<blockquote>
<p>Could not load file or assembly msshrtmi or one of its dependencies</p>
</blockquote>
<p>Erm, say what now? I don't even have a reference to this anywhere in my project. However, I know that when that is the case, this is normally some low-level GAC'd thing that is causing the problems.</p>
<p>A <a href="https://www.google.co.uk/search?q=Could+not+load+file+or+assembly+msshrtmi+or+one+of+its+dependencies&oq=Could+not+load+file+or+assembly+msshrtmi+or+one+of+its+dependencies">quick Google</a> reveals that I am far from alone on this issue. I ended up trying out the steps outlined</p>
<ul>
<li>Trying out <a href="http://stackoverflow.com/a/8277413">this stackoverflow answer</a>.</li>
<li>I skipped over <a href="http://jake.ginnivan.net/azure-and-msshrtmi">this code-based solution</a> as frankly, it seemed way too hacky for me.</li>
<li>I tried removing all the 'PlatformTarget' references, as mentioned <a href="http://robertgreiner.com/2012/10/could-not-load-file-or-assembly-msshrtmi/">here</a>.</li>
</ul>
<div>All to no avail..</div>
<h2>I Found This Fix</h2>
<p>I then did this - and it worked!</p>
<ul>
<li><strong>Right-click your Azure project (the one with the blue globe).</strong></li>
<li><strong>Click the "Application" tab.</strong></li>
<li><strong>Note that there is a button telling you that you have a newer SDK installed?</strong></li>
<li><strong>CLICK IT!</strong></li>
</ul>
<div>So, it turns out that some minor changes get made to a few files that make all the difference:</div>
<div>
<ul>
<li><strong>.csdef file</strong> - 'schemaVersion' is updated.</li>
<li><strong>.ccproj</strong> - 'ProductVersion' and 'CloudExtensionsDir' are updated.</li>
<li><strong>.csproj</strong> - You're Azure SDK references will be updated (ServiceRuntime, Diagnostics etc.)</li>
</ul>
<p>I think the killer was the 'CloudExtensionsDir' for me, this changed FROM:</p>
<pre><CloudExtensionsDir Condition=" '$(CloudExtensionsDir)' == '' ">$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Windows Azure Tools\1.7\</CloudExtensionsDir></pre>
<p>TO:</p>
<pre><CloudExtensionsDir Condition=" '$(CloudExtensionsDir)' == '' ">$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Windows Azure Tools\1.8\</CloudExtensionsDir></pre>
<p>There you have it - check for the button in the Cloud Project Properties "Application" tab, and make sure your 'CloudExtensionsDir' is pointing to the latest install of your SDKs, which are located:</p>
<pre>C:\Program Files\Microsoft SDKs\Windows Azure\.NET SDK</pre>
<p>I hope this helps!</p>
</div>Rob Cooperhttp://www.blogger.com/profile/04578932741770127659noreply@blogger.com0tag:blogger.com,1999:blog-4175311048704332408.post-5340837943037634202013-02-05T12:54:00.001-08:002013-02-05T12:54:31.886-08:00I'm Debt Free!<p>Hello Ladies and Gentlemen!</p>
<p>I've just logged into my Internet banking and confirmed it - <strong>I'm finally debt free</strong>.</p>
<p><img style="display: block; margin-left: auto; margin-right: auto;" title="Loan_Status.png" src="http://lh5.ggpht.com/-N9muKOyyogM/URFxhCfjEOI/AAAAAAAAAVU/mDAh3HhMQQA/Loan_Status.png?imgmax=800" alt="Loan Status" width="472" height="103" border="0" /></p>
<p>The last payment on my last loan went out yesterday, and the only credit I have now is on a air miles card that I pay off in full every month.</p>
<p><strong>My money is my own again.</strong></p>
<p>This is awesome stuff - not only for the financial gain, but also for the immense emotional relief this gives me.</p>
<h2>To Be Cathartic..</h2>
<p>There was a lot of bad emotion and memories attached to this loan in particular, here's some mental associations that spring to mind:</p>
<ul>
<li>Not being able to afford proper food - basically living on pasta and ketchup during the worst parts.</li>
<li>This of course had the knock-on effect of making me unhealthy, I was sick - a lot.</li>
<li>No hot water or heating - this actually did wonders for my ability to take cold showers!</li>
<li>The banging of the front door as debt collectors wanted to get money I didn't have.</li>
<li>The constant stream of red letters, legal threats, phone calls hassling me (I ended up disconnecting the phone).</li>
<li>Even when I started to get <em>some</em> cash (after clearing off smaller loans) - I'd still have to toss-up "food" or "heating" over "geek book to improve my skills and get out of this dead-end job".</li>
</ul>
<div>But the one that really broke my heart - <strong>having to lie to my mother and tell her I was OK and not to worry about me.</strong></div>
<div><strong><br /></strong></div>
<div>People sometimes ask me "why?" - why didn't you ask for help, and then I tell them:</div>
<blockquote>
<div>… because I got myself into the mess, I had to get myself out.</div>
</blockquote>
<div>I made some bad, stupid decisions. I got myself into a bad situation. I was weak and almost ready to throw in the towel. I thought I was done.</div>
<div> </div>
<div>But when we are at our weakest is when we show our true strength.</div>
<div> </div>
<div>I had to get through it, for <em>me</em> - for my own.. Manliness! <strong>I had to know that I could right the wrongs and come out better for it</strong>. Otherwise, what was the point?</div>
<div> </div>
<div>What kind of person would it make me if I did all this stuff, took money and property from companies that were built by people just trying to put food on the table for their families and said <em>"ohhh I can't afford to pay you because I am a fucking idiot who jumped into things that I couldn't handle"</em>. I'm not that guy.<strong> </strong>If I screw up, I fix it. No question.</div>
<h3>Get Out of the Hole</h3>
<div>So I did all I know how to do. I worked. I studied. I gritted my teeth.</div>
<div> </div>
<div>I also cried, got frustrated, wanted to give up, got depressed, cried some more and got angry. It's really easy to get sucked into this spiral when you can never afford to go out and can't afford TV to distract you etc.</div>
<div> </div>
<div>But I carried on working, I carried on studying and I carried on gritting my teeth and smiling to the outside world.</div>
<div> </div>
<div>Then I cleared a debt. Some crappy high interest card loan that I got to pay off another. (LOL)</div>
<div>Then I cleared another - these guys must have loved me because they kept sending me new ones after I chopped it up - and they were so kind to give me <em>more</em> money (I kept chopping them up - I made it my new personal goal to see if I could chop up enough cards to cover the stupid amount of interest I paid them).</div>
<div> </div>
<div>Then I felt it - <em>momentum</em>.</div>
<div> </div>
<div>I was on to something. I realised that it wasn't about the penny-pinching and meticulous planning. It was about focusing on the most wasteful parts of your budget and getting them down as low as you can go. Two things come out of this:</div>
<div><ol>
<li><strong>You make money.</strong> Last week there was no money, now you've found some. Yay.</li>
<li><strong>You lose the stress.</strong> Everything else is in hand and you're focusing on the few things you can actually do something about.</li>
</ol>
<h3>Make It Fun</h3>
<p>I was always amazed how people that had to deal with horrific things made games out of them (for example, paramedics that score points based on damage at a roadside traffic accident). It sounds sick, but it's a <em>coping mechanism</em>. If you focus on the game side of it, it removes all the emotional stress that you'd normally have so you can actually focus on the task at hand.</p>
<p>I made it a game. Each month I would pick an item from my budget to pick on, then see "how low I could go". My favourite - "Weekly Groceries". Got that down to £10/week. Impossible? No. Boring? Kinda :) Helped me kick ass? <strong>Definitely*.</strong></p>
<p style="font-size: 11px;">* this actually freed up about £150 a month. Would you say "no" to an extra £150?</p>
<h3>Are You OK?</h3>
<p>As my momentum picked up, I continued smashing debt - then one day I awoke and realised something..</p>
<p><strong>I wasn't lying to my mother after all. I <em>was</em> OK.</strong></p>
<p>Grit your teeth. Do the work. It may not be easy work, and it will take time. Sometimes there's only one way out of a situation. Toil.</p>
<p>Fast-forward a few years. It's all over.. I now live a life that I truly love. I have amazing friends that challenge me, help me grow and become a better person. I'm not only financially richer - but I'm mentally richer. <strong>I'm good. I'm really, really good!</strong></p>
<h3>Lastly...</h3>
<p>I have to say a big "thank you" to my friends and family - you're everything to me. There are times when you have saved me and you don't even know it.</p>
<p><strong>I love you all.</strong></p>
<p>Now, I have to get back to work ;)</p>
</div>Rob Cooperhttp://www.blogger.com/profile/04578932741770127659noreply@blogger.com3tag:blogger.com,1999:blog-4175311048704332408.post-22067515432237289652012-11-27T13:06:00.001-08:002012-11-27T13:07:57.147-08:00HSBC "Fast Balance" App for iPhone - Unable to Verify *RESOLVED*<p>Wow, this is just a nice big bag of fail..</p>
<p>I recently downloaded <a href="https://itunes.apple.com/gb/app/hsbc-fast-balance/id499232422?mt=8">HSBC "Fast Balance"</a> since it'll make keeping my budget up to date, but I was having epic problems registering my account with them, I kept getting an error message saying <strong>"Unable to Verify"</strong> and something about my address not matching up.</p>
<p>Well, after trying about 500 permutations of my address, I was about ready to give up. I ended up getting on the phone to Internet Banking Support (08456 002 290) and walking through it with them..</p>
<p>Turns out, their address validation doesn't seem to like flat numbers. My address is similar to:</p>
<pre>Flat X<br />A Number Some Street<br />London<br />POSTCODE</pre>
<p>Turns out, in order to get it to validate, I had to do this:</p>
<pre>A Number<br />Some Street<br />London<br />POSTCODE</pre>
<p>Which in my mind, is a completely different address. Also keep in mind that when I log into Internet Banking, it appears exactly like the top one.. So as far as I was concerned, that's how they had it on the system.</p>
<p>So, dear app developers for HSBC - as one developer to another <strong><em>GET IT TOGETHER!</em></strong></p>
<p>I hope others find this useful :)</p>
<p>On a similar note - <strong>if you bank with Barclays, check out <a href="https://itunes.apple.com/gb/app/barclays-mobile-banking/id536248734?mt=8">their iPhone app</a></strong> - it's a polar opposite experience. Well designed, easy to use, feature rich and worked first time. Serious kudos to the Barclays development team. </p>Rob Cooperhttp://www.blogger.com/profile/04578932741770127659noreply@blogger.com0tag:blogger.com,1999:blog-4175311048704332408.post-73244960250853693762012-10-09T23:35:00.001-07:002012-10-23T12:46:33.257-07:00Lean Startup Machine London Review<blockquote>
<p>29 hours across 3 days, 25 interviews, 3 pivots, 1 idea.</p>
</blockquote>
<p>Last weekend I attended the <a title="http://leanstartupmachine.com" href="http://leanstartupmachine.com">Lean Startup Machine</a> (LSM) here in London. I wasn't really sure what to expect since I don't know anyone who had already been to one. I definitely wanted to go to something practical and hands-on, because while I feel I "get" the Lean books ("<a title="https://www.amazon.co.uk/dp/0670921602/ref=as_li_ss_til?tag=leonisoftw-21&camp=2902&creative=19466&linkCode=as4&creativeASIN=0670921602&adid=0QZ464H1ES25RBBQMNN7&" href="https://www.amazon.co.uk/dp/0670921602/ref=as_li_ss_til?tag=leonisoftw-21&camp=2902&creative=19466&linkCode=as4&creativeASIN=0670921602&adid=0QZ464H1ES25RBBQMNN7&">The Lean Startup</a>" and "<a title="https://www.amazon.co.uk/dp/1449305172/ref=as_li_ss_til?tag=leonisoftw-21&camp=2902&creative=19466&linkCode=as4&creativeASIN=1449305172&adid=1V9XZG4569SHA65XN7Q7&" href="https://www.amazon.co.uk/dp/1449305172/ref=as_li_ss_til?tag=leonisoftw-21&camp=2902&creative=19466&linkCode=as4&creativeASIN=1449305172&adid=1V9XZG4569SHA65XN7Q7&">Running Lean</a>") in terms of <em>why</em> they outline the Customer Development (I really recommend "<a title="https://www.amazon.co.uk/dp/0984999302/ref=as_li_ss_til?tag=leonisoftw-21&camp=2902&creative=19466&linkCode=as4&creativeASIN=0984999302&adid=1T46BQ9Q8KSWQN3044XB&" href="https://www.amazon.co.uk/dp/0984999302/ref=as_li_ss_til?tag=leonisoftw-21&camp=2902&creative=19466&linkCode=as4&creativeASIN=0984999302&adid=1T46BQ9Q8KSWQN3044XB&">The Startup Owners Manual</a>" to learn about this) they do - where I was struggling was the <em>how to do it</em>.<br /><br /></p>
<h2>What's Lean Startup Machine?</h2>
<p>It's an event that will really get you focused on the first part of the 3 stages of a startup* - <strong>Problem/Solution Fit</strong>. Before we start worry about producing the end-product we need to ensure that it's designed to solve a problem that people actually have.<br /><br />* At least this one was - there may be future events focused on other areas.<br /><br /></p>
<h2>Why Should I Go to Lean Startup Machine?</h2>
<p>If you're new to Lean principles, or having problems with <em>really</em> feeling confident about your ideas before implementation - this is for you. TBH, I would even go so far as to say "do it regardless".<br /><br />Go to LSM to radically change the way you <em>approach</em> innovative product development. <strong>You don't have to be working on a startup</strong>, the "startup" bit is a bit of a misnomer, go if you're looking to do something <em>innovative</em>.<br /><br /></p>
<h2>What Happens at Lean Startup Machine?</h2>
<p>Simply put, you become part of a team that essentially validates an idea to see if it has problem/solution fit. <br /><br /></p>
<h3>The Idea</h3>
<p>You can either bring your own idea and pitch it to the group, or you can jump in on someone elses.<br /><br />What I would say is this <strong>"the actual idea is pretty much meaningless, what's important for the weekend is <em>process</em>"</strong>.<br /><br /></p>
<h3>Team Size</h3>
<p>I saw a few teams really struggling at the 4+ mark. This weekend is <em>intense</em>. It's imperative that you are in a <em>small</em> (2-4 people) team that <em>gets on well</em>.<br /><br />There are times you will be tired, times where you will be confused and times where you might feel completely lost. Only a good team can pull you through this.<br /><br />I was in a two-man team (we splintered off from another large team) and while we got on absolutely great - we found that we kind of burned each other out quite fast. Therefore, <strong>I would recommend a team of 3-4 people</strong>.<br /><br /></p>
<h3>The Process</h3>
<p>At an incredible rate, you will go from "just an idea pitch" to getting out on the streets, finding your target customer and <em>talking</em> to them.<br /><br />I think it's fair to say that a lot of us were really outside our comfort zone with this. For many, it was a complete baptism of fire. We just aren't used to profiling and finding people, let alone forming a good question flow and conversing in the right way to validate our assumptions.<br /><br />The key focal point is the <a title="http://leanstartupmachine.com/validationboard" href="http://leanstartupmachine.com/validationboard">Validation Board</a>, on which you place your target customer segment, the key problem you are solving for them and all your <em>core assumptions</em>. Ideas are always loaded with them - "people want my solution", "people have the problem", "they would use a mobile app", "everyone would <em>LOVE</em> to get involved" etc.<br /><br />Once your core assumptions are on the board, you pick the next riskiest one (the one that if proved would mean you need to seriously re-think how this thing is going to work). For most, the first iteration on this is normally "do they even have the problem I am defining". Once you have some <strong>hard data</strong>, you then decide to <em>pivot</em> (change an integral part of the problem/solution) or <em>persevere</em> (continue on to the next riskiest assumption).<br /><br />One key point to note here - the term 'pivot' is often thrown around by those that have read the "lean" books. <strong>A pivot is a <em>fundamental</em> change in you business strategy</strong>, like changing customer segments, the problem you are actually trying to solve or the pricing model etc.<br /><br /></p>
<h3>Validation</h3>
<p>How do we validate? Getting out of the building! At LSM, you don't have a choice! You <em>will</em> be herded out and expected to come back with results! This is <em>really</em> important. We had some amazing conversations with people throughout the weekend and it's really changed how I approach new ideas.<br /><br />"Getting Out of the Building" can mean:<br /><br /></p>
<ul>
<li><strong>Face-to-face with actual customers.</strong></li>
<li>Online surveys.</li>
<li>Focus groups.</li>
<li>Testing your pitch via landing pages.</li>
</ul>
<p>Why is the first one in bold? Simply because <strong>that should always be the most preferable one</strong>. Seriously, I am a convert - it's amazing.<br /><br /></p>
<h2>Homing in</h2>
<p>Once you have pivoted and persevered a few times, you will start to realise a couple of things:<br /><br /></p>
<ol>
<li>Your idea where you are at now is quite different to your original hotshot idea.</li>
<li>You feel a lot more confident about what your idea is.</li>
</ol>
<p>You are now in a much better position to decide if you want to start "getting serious" about this idea (i.e. investing some money into it).<br /><br /></p>
<h2>Wrapping Up</h2>
<p>This weekend was really intense, I came away exhausted but absolutely buzzing with ideas to implement in <a title="http://leonis-software.co.uk" href="http://leonis-software.co.uk">my own startup</a>.<br /><br />The validation process we were taught at LSM really helped us focus on getting our assumptions tested - and in many cases, invalidated. <strong>This is a good thing.</strong> I was talking to my team mate Ben at the end and said:<br /><br /></p>
<blockquote>
<p>"Oh man, you realise that if I had run off with the original idea and started coding, I would have been working for 6 months, easy".</p>
</blockquote>
<p>This original idea was binned on the 2nd iteration of our validation board. It cost us about 2 hours in terms of having conversations and assimilating the results.<br /><br /><strong>Lean Startup Machine works.</strong><br /><br />For my team, we were getting some very strong signals that we are on to something with our idea at the end of the weekend (hence why I have not gone into too much detail about the idea yet). We will likely be running some more validation in the short term. Watch this space! :)<br /><br />Lastly, I would just like to say a big "thank you" to everyone that helped make it happen, especially the organisers (Ryan and Obe), you are all amazing.<br /><br />(I will do the rounds and list them here soon).<br /><br /> <br /><br /></p>Rob Cooperhttp://www.blogger.com/profile/04578932741770127659noreply@blogger.com0tag:blogger.com,1999:blog-4175311048704332408.post-55168642698082915742012-09-24T12:01:00.001-07:002012-10-01T14:08:30.285-07:00Apple MBP Cracked Screen - AppleCare "The Worlds Most Archaic Support"Sad times, today I dropped my Macbook Pro while leaving the office. Got home to find that I had a series of small fractures across the screen. Thankfully, the LCD is still intact, so only the glass needs to be replaced.<br/><br/>Naturally, I get on the phone to Apple Care:<br/><br/><ul>
<li>After spending <strong>25 minutes</strong> on the phone on hold (having given all the problem details to a robot woman), I finally get through to someone.</li>
<li>I then have to re-state all the information that I gave to the robot woman to the gent on the phone.</li>
<li>I then explain the level of damage to the screen, as ask for a quote at what the cost would be (roughly) to get it replaced. I get told "£150 for an older model".</li>
<li>I ask "Is my [early 2011] model considered old? Is that what it would cost for <em>this</em> model?" - the response is "no" to both. He doesn't know what it would cost "since we don't know the extent of the damage".</li>
<li>I repeat the level of damage. Support guy then says "allow £100-£150". OK, at this point I know he just doesn't know and decide to move on.</li>
<li>"OK, can I go ahead and get booked in to see someone at the store to get this sorted?". After waiting for a minute or two while he checks individual stores, I get told ALL the stores in central London are fully booked for the week, with one exception on Sunday afternoon.</li>
<li>I make the booking, accepting my fate that I now have to work with a cracked screen for a week. Not only that, I actually don't know if/when this is going to be fixed.</li>
</ul>
<strong>Ask yourself this, Apple - is this acceptable?</strong><br/><br/>I fundamentally think that companies boasting profits as much as Apple's really should get their basics in order. In my view, this is how it <em>should</em> work:<br/><br/><ul>
<li>I ring up, give my details to robot woman including MBP serial number and a chance to describe the problem in 10 seconds.</li>
<li>I get told there is a queue, and expected wait time.</li>
<li>I then get the choice to wait on hold, or get given a call back.</li>
<li>If they don't have my number (i.e. I am blocking it), I get asked to enter it.</li>
<li>Agent gets message from the system, opens up my account info, and listens to my problem. He now has the scene set <em>before</em> he calls me.</li>
<li>Nice things can happen here like getting relevant info ready on his machine. Possible repair charges, nearest stores with availability etc. You know, <em>relevant</em> information that means I don't get kept waiting while they try and find it.</li>
<li>We discuss issue, and make appropriate plans.</li>
</ul>
<strong>Why is a company that boasts having "the worlds smartest software" and insane profits still running call centres that are dumb?</strong><br/><br/>I do genuinely love my Apple products, but man their support is terrible. You are more than just products now Apple, get it together.<br/><br/> <strong>UPDATE: </strong>Glad to report that all is finally resolved, with a final fee of £150. Unfortunately, Apple said that they had (and always have to) replace the entire screen assembly. Seems rather wasteful, but hey - there product I guess. I complained that that seems incredibly steep for what is actually relatively minor damage. So they waived the labour fee (£25). Just glad to have my baby back in one piece. Just wish the whole process was more organised and less stressful!<br/><br/>Rob Cooperhttp://www.blogger.com/profile/04578932741770127659noreply@blogger.com0