<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Si</title>
    <description>The latest articles on Forem by Si (@devdrake0).</description>
    <link>https://forem.com/devdrake0</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F170949%2F7d341906-f8d9-4c9d-9bc4-420d70e49abf.png</url>
      <title>Forem: Si</title>
      <link>https://forem.com/devdrake0</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/devdrake0"/>
    <language>en</language>
    <item>
      <title>Value Receivers VS Pointer Receivers in Go</title>
      <dc:creator>Si</dc:creator>
      <pubDate>Mon, 29 Nov 2021 16:55:13 +0000</pubDate>
      <link>https://forem.com/devdrake0/value-receivers-vs-pointer-receivers-in-go-10lf</link>
      <guid>https://forem.com/devdrake0/value-receivers-vs-pointer-receivers-in-go-10lf</guid>
      <description>&lt;h2&gt;
  
  
  What is a Method?
&lt;/h2&gt;

&lt;p&gt;Before we start talking about Value Receivers and Pointer Receivers, let's make sure we have a good grasp of what a Method is.&lt;/p&gt;

&lt;p&gt;In &lt;a href="https://golang.org/%5D"&gt;Go&lt;/a&gt;, a Method is is a function that is defined on a type using a receiver argument.&lt;/p&gt;

&lt;p&gt;The following example is from &lt;a href="https://tour.golang.org/methods/1"&gt;Tour of Go&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Vertex&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Y&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Vertex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Abs&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sqrt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Y&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What is a Value Receiver?
&lt;/h2&gt;

&lt;p&gt;When using a Value Receiver, a copy is taken of the type and passed to the Method; similarly to what happens when passing-by-value to a normal function. When the method executes, the object copy sits in a different location in memory; thus any changes made to the object don't effect the original.&lt;/p&gt;

&lt;p&gt;Take the following example; even though we change the &lt;code&gt;Breed&lt;/code&gt; and &lt;code&gt;Weight&lt;/code&gt;, the original object remains unchanged.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Dog&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Breed&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;Weight&lt;/span&gt; &lt;span class="kt"&gt;int16&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;dog&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Breed&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Dalmation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Weight&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;40&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"dog before ValReceiver: %+v&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dog&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// {Breed:Dalmation Weight:40}&lt;/span&gt;
    &lt;span class="n"&gt;dog&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ValReceiver&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"dog after ValReceiver: %+v&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dog&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// {Breed:Dalmation Weight:40}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="n"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;ValReceiver&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Breed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Terrier"&lt;/span&gt;
    &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Weight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are some exceptions to this rule, for example when using slices; which contain a pointer to the underlying array and can lead to the original object being amended. The following is an example of this scenario:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Dog&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Breed&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;Weight&lt;/span&gt; &lt;span class="kt"&gt;int16&lt;/span&gt;
    &lt;span class="n"&gt;Friends&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;dog&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Breed&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Dalmation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Weight&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Friends&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"Fred"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Amy"&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"dog before ValReceiver: %+v&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dog&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// {Breed:Dalmation Weight:40 Friends:[Fred Amy]}&lt;/span&gt;
    &lt;span class="n"&gt;dog&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ValReceiver&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"dog after ValReceiver: %+v&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dog&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// {Breed:Dalmation Weight:40 Friends:[Chris Amy]}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="n"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;ValReceiver&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Breed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Terrier"&lt;/span&gt;
    &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Weight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;
    &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Friends&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Chris"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What is a Pointer Receiver?
&lt;/h2&gt;

&lt;p&gt;When using a Value Receiver, the memory address is passed to the Method; similarly to what happens when passing-by-reference to a normal function. When the method executes, it has a reference to the original object; thus any changes made to the object do affect the original.&lt;/p&gt;

&lt;p&gt;Take the following example; When the method changes the &lt;code&gt;Breed&lt;/code&gt; and &lt;code&gt;Weight&lt;/code&gt;, the original object is also changed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Dog&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Breed&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;Weight&lt;/span&gt; &lt;span class="kt"&gt;int16&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;dog&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Breed&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Dalmation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Weight&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;40&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"dog before PtrReceiver %+v&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dog&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// {Breed:Dalmation Weight:40}&lt;/span&gt;
    &lt;span class="n"&gt;dog&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PtrReceiver&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"dog after PtrReceiver: %+v&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dog&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// {Breed:Terrier Weight:10}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;PtrReceiver&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Breed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Terrier"&lt;/span&gt;
    &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Weight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Can I mix-and-match Value and Pointer Receivers?
&lt;/h2&gt;

&lt;p&gt;It is generally recommended you don't mix-and-match. If a type uses both Value and Pointer receiver, it will be hard for your consumers to know which method uses which type without having to read the code. However, yes you can mix-and-match.&lt;/p&gt;

&lt;p&gt;When doing so, remember the following rules (&lt;a href="https://stackoverflow.com/questions/33587227/method-sets-pointer-vs-value-receiver"&gt;ref&lt;/a&gt;):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you have a &lt;code&gt;*T&lt;/code&gt; you can call methods that have a receiver type of &lt;code&gt;*T&lt;/code&gt; as well as methods that have a receiver type of &lt;code&gt;T&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If you have a &lt;code&gt;T&lt;/code&gt; and it is addressable you can call methods that have a receiver type of &lt;code&gt;*T&lt;/code&gt; as well as methods that have a receiver type of &lt;code&gt;T&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If you have a &lt;code&gt;T&lt;/code&gt; and it isn't addressable, you can only call methods that have a receiver type of &lt;code&gt;T&lt;/code&gt;, not &lt;code&gt;*T&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If you have an interface &lt;code&gt;I&lt;/code&gt;, and some or all of the methods in &lt;code&gt;I&lt;/code&gt;'s method set are provided by methods with a receiver of &lt;code&gt;*T&lt;/code&gt; (with the remainder being provided by methods with a receiver of &lt;code&gt;T&lt;/code&gt;), then &lt;code&gt;*T&lt;/code&gt; satisfies the interface &lt;code&gt;I&lt;/code&gt;, but &lt;code&gt;T&lt;/code&gt; doesn't. That is because &lt;code&gt;*T&lt;/code&gt;'s method set includes &lt;code&gt;T&lt;/code&gt;'s, but not the other way around (see the first bullet).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short, you can mix and match methods with Value Receivers and Methods with Pointer Receivers, and use them with variables containing values and pointers, without worrying about which is which. Both will work, and the syntax is the same. However, if Methods with Pointer Receivers are needed to satisfy an Interface, then only a Pointer will be assignable to the Interface — a Value won't be valid.&lt;/p&gt;

</description>
      <category>go</category>
    </item>
    <item>
      <title>Debugging with delve</title>
      <dc:creator>Si</dc:creator>
      <pubDate>Mon, 29 Nov 2021 16:52:52 +0000</pubDate>
      <link>https://forem.com/devdrake0/debugging-with-delve-3m5e</link>
      <guid>https://forem.com/devdrake0/debugging-with-delve-3m5e</guid>
      <description>&lt;p&gt;Learn how to use Delve to debug your Go applications and tests.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is &lt;a href="https://github.com/go-delve/delve"&gt;delve&lt;/a&gt;?
&lt;/h2&gt;

&lt;p&gt;Delve is an open source debugger for the &lt;a href="//golang.org"&gt;Go&lt;/a&gt; programming language.&lt;/p&gt;

&lt;h2&gt;
  
  
  When should I use delve to debug my Go programmes?
&lt;/h2&gt;

&lt;p&gt;If you use one of the popular Code Editors (e.g. VSCode, Golang) they will handle this for you. If you use VIM, and Print statements aren't cutting it, then this tutorial is for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pre-requisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Install &lt;a href="//golang.org"&gt;Go&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Have at least a basic working knowledge of the language&lt;/li&gt;
&lt;li&gt;Install &lt;a href="https://github.com/go-delve/delve"&gt;delve&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Setting up
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Create a new directory in a place of your choice&lt;/li&gt;
&lt;li&gt;Run the &lt;code&gt;go mod init&lt;/code&gt; command (e.g &lt;code&gt;go mod init github.com/simondrake/biggest-num&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Create our &lt;code&gt;pkg&lt;/code&gt; directory - &lt;code&gt;mkdir -p pkg/biggestNum&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Add a &lt;code&gt;biggestNum.go&lt;/code&gt; file in the &lt;code&gt;biggestNum&lt;/code&gt; directory with the following contents:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;biggestNum&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;BiggestEvenNum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;biggest&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;biggest&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;isEven&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;biggest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;biggest&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;isEven&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;isEven&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;isEven&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Create another directory, separate from the one you created at the beginning of this section&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;go mod init example.com&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Change your &lt;code&gt;go.mod&lt;/code&gt; file to the following, which basically imports our &lt;code&gt;biggestNum&lt;/code&gt; package without having to push it up to GitHub (change directory names as required):
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;module&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;

&lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="m"&gt;1.16&lt;/span&gt;

&lt;span class="n"&gt;require&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;github&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;simondrake&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;biggestNum&lt;/span&gt; &lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="m"&gt;.0.0&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;replace&lt;/span&gt; &lt;span class="n"&gt;github&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;simondrake&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;biggestNum&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;../&lt;/span&gt;&lt;span class="n"&gt;biggest&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Create a &lt;code&gt;main.go&lt;/code&gt; file with the following contents (change import for &lt;code&gt;biggestNum&lt;/code&gt; as required):
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;

    &lt;span class="s"&gt;"github.com/simondrake/biggestNum/pkg/biggestNum"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;biggestNum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BiggestEvenNum&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;23&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;41&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;51&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Run &lt;code&gt;go run main.go&lt;/code&gt; and make sure you don't get any compilation errors.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Debugging your Application
&lt;/h2&gt;

&lt;p&gt;We now have a Go application we can debug, so let's start the debugger with &lt;code&gt;dlv debug&lt;/code&gt; and you should see the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ dlv debug
Type 'help' for list of commands.
(dlv)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add a breakpoint at line 10 of our &lt;code&gt;main.go&lt;/code&gt; file by running &lt;code&gt;breakpoint main.go:10&lt;/code&gt; (or &lt;code&gt;b main.go:10&lt;/code&gt; for short).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(dlv) b main.go:10
Breakpoint 1 set at 0x10cb9cf for main.main() ./main.go:10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run &lt;code&gt;continue&lt;/code&gt; (or &lt;code&gt;c&lt;/code&gt;) to run-to-breakpoint.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(dlv) c
&amp;gt; main.main() ./main.go:10 (hits goroutine(1):1 total:1)
     5:
     6:         "github.com/simondrake/biggestNum/pkg/biggestNum"
     7: )
     8:
     9: func main() {
=&amp;gt;  10:         b := biggestNum.BiggestEvenNum([]int{1, 4, 23, 12, 41, 51})
    11:
    12:         fmt.Println(b)
    13: }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From here we could continue (&lt;code&gt;c&lt;/code&gt;), which would run the programme to completion because there are no more breakpoints, but instead let's step-into the &lt;code&gt;BiggestEvenNum&lt;/code&gt; method by running &lt;code&gt;step&lt;/code&gt; (or &lt;code&gt;s&lt;/code&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; github.com/simondrake/biggestNum/pkg/biggestNum.BiggestEvenNum() /path/to/biggest-num/pkg/biggestNum/biggestNum.go:3
     1: package biggestNum
     2:
=&amp;gt;   3: func BiggestEvenNum(nums []int) int {
     4:         var biggest int
     5:
     6:         for _, n := range nums {
     7:                 if n &amp;gt; biggest &amp;amp;&amp;amp; isEven(n) {
     8:                         biggest = n
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note how the first line gives us a handy reference to where we are (&lt;code&gt;/path/to/biggest-num/pkg/biggestNum/biggestNum.go:3&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Now let's add another breakpoint in our &lt;code&gt;biggestNum&lt;/code&gt; package, on line 7:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(dlv) b /path/to/biggest-num/pkg/biggestNum/biggestNum.go:7
Breakpoint 2 set at 0x10cb8ea for github.com/simondrake/biggestNum/pkg/biggestNum.BiggestEvenNum() /path/to/biggest-num/pkg/biggestNum/biggestNum.go:7
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run &lt;code&gt;continue&lt;/code&gt; to get to our next breakpoint.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(dlv) c
&amp;gt; github.com/simondrake/biggestNum/pkg/biggestNum.BiggestEvenNum() /path/to/biggest-num/pkg/biggestNum/biggestNum.go:7 (hits goroutine(1):1 total:1)
     2:
     3: func BiggestEvenNum(nums []int) int {
     4:         var biggest int
     5:
     6:         for _, n := range nums {
=&amp;gt;   7:                 if n &amp;gt; biggest &amp;amp;&amp;amp; isEven(n) {
     8:                         biggest = n
     9:                 }
    10:         }
    11:
    12:         return biggest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can evaluate expressions by running &lt;code&gt;print&lt;/code&gt; (or &lt;code&gt;p&lt;/code&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(dlv) p n
1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can evaluate a function call by running &lt;code&gt;call&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(dlv) call isEven(n)
&amp;gt; github.com/simondrake/biggestNum/pkg/biggestNum.BiggestEvenNum() /path/to/biggest-num/pkg/biggestNum/biggestNum.go:7 (hits goroutine(1):2 total:2)
Values returned:
        ~r1: false
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can &lt;code&gt;continue&lt;/code&gt; to run the programme to the next iteration of the loop, or run &lt;code&gt;next&lt;/code&gt; (or &lt;code&gt;n&lt;/code&gt;) to go to the next line, but we're going to skip that by removing this breakpoint. First, get the name of the breakpoint with &lt;code&gt;breakpoints&lt;/code&gt; (or &lt;code&gt;bp&lt;/code&gt;) and then delete it&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(dlv) clear 2
Breakpoint 2 cleared at 0x10cb8ea for github.com/simondrake/biggestNum/pkg/biggestNum.BiggestEvenNum() /path/to/biggest-num/pkg/biggestNum/biggestNum.go:7
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we'll &lt;code&gt;stepout&lt;/code&gt; (or &lt;code&gt;so&lt;/code&gt;) of this package&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(dlv) so
&amp;gt; main.main() ./main.go:10
Values returned:
        ~r1: 12

     5:
     6:         "github.com/simondrake/biggestNum/pkg/biggestNum"
     7: )
     8:
     9: func main() {
=&amp;gt;  10:         b := biggestNum.BiggestEvenNum([]int{1, 4, 23, 12, 41, 51})
    11:
    12:         fmt.Println(b)
    13: }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From here you can &lt;code&gt;restart&lt;/code&gt; if you want to run the same debugger again, or &lt;code&gt;continue&lt;/code&gt; until completion of the application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Debugging tests
&lt;/h2&gt;

&lt;p&gt;So far, we've seen how to debug a Go application. But what if we wanted to debug our &lt;code&gt;biggestNum&lt;/code&gt; standalone? If you try running &lt;code&gt;dlv debug&lt;/code&gt; you'll get an error.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ dlv debug pkg/biggestNum/biggestNum.go
could not launch process: not an executable file
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But, delve does have a &lt;code&gt;test&lt;/code&gt; subcommand we can use to run our tests in debug mode. So, first, let's add the following test under &lt;code&gt;biggestNum_test.go&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;biggestNum&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"testing"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;TestBiggestEvenNum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;290&lt;/span&gt;

    &lt;span class="n"&gt;out&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;BiggestEvenNum&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="m"&gt;23&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;51&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;45&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;290&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;out&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"'%d' did not match expected '%d'"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To run the tests in debug mode, use &lt;code&gt;dlv test&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ dlv test pkg/biggestNum/*.go -test.v
Type 'help' for list of commands.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then set a breakpoint as we did in the previous step&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(dlv) b biggestNum.go:6
Breakpoint 1 set at 0x11607d3 for command-line-arguments.BiggestEvenNum() ./pkg/biggestNum/biggestNum.go:6``
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run &lt;code&gt;continue&lt;/code&gt; as we did before&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(dlv) continue
&amp;gt; command-line-arguments.BiggestEvenNum() ./pkg/biggestNum/biggestNum.go:6 (hits goroutine(4):1 total:1)
     1: package biggestNum
     2:
     3: func BiggestEvenNum(nums []int) int {
     4:         var biggest int
     5:
=&amp;gt;   6:         for _, n := range nums {
     7:                 if n &amp;gt; biggest &amp;amp;&amp;amp; isEven(n) {
     8:                         biggest = n
     9:                 }
    10:         }
    11:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then debug your package, as we did our application, in the previous section.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing thoughts
&lt;/h2&gt;

&lt;p&gt;You've learnt the basics of debugging with delve, but you should refer to the &lt;code&gt;help&lt;/code&gt; command output to learn about what else delve can do.&lt;/p&gt;

</description>
      <category>go</category>
      <category>delve</category>
      <category>testing</category>
    </item>
    <item>
      <title>Best programming audiobooks</title>
      <dc:creator>Si</dc:creator>
      <pubDate>Tue, 16 Jun 2020 15:56:04 +0000</pubDate>
      <link>https://forem.com/devdrake0/best-programming-audiobooks-o5d</link>
      <guid>https://forem.com/devdrake0/best-programming-audiobooks-o5d</guid>
      <description>&lt;p&gt;I struggle to read books, the words dance around on the page which results in me skipping over whole sentences/paragraphs. &lt;/p&gt;

&lt;p&gt;Sometimes I can go ten minutes and have no idea what I've just read.&lt;/p&gt;

&lt;p&gt;However, audiobooks are right up my street!&lt;/p&gt;

&lt;p&gt;What books convert well in the audiobook format?&lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>Binary to decimal converter</title>
      <dc:creator>Si</dc:creator>
      <pubDate>Tue, 19 May 2020 13:00:00 +0000</pubDate>
      <link>https://forem.com/codetips/binary-to-decimal-converter-2h2c</link>
      <guid>https://forem.com/codetips/binary-to-decimal-converter-2h2c</guid>
      <description>&lt;p&gt;&lt;a href="https://www.codetips.co.uk" rel="noopener noreferrer"&gt;CodeTips&lt;/a&gt; strives to help beginners, with zero or very little experience, learn to code.&lt;/p&gt;

&lt;p&gt;We do cross-post to other sites to reach a wider audience, but why not &lt;a href="https://mailchi.mp/92cccf7024b2/codetips" rel="noopener noreferrer"&gt;subscribe to our newsletter&lt;/a&gt; and get the newest articles straight to your mailbox? &lt;/p&gt;

&lt;p&gt;The original source for this content is &lt;a href="https://www.codetips.co.uk" rel="noopener noreferrer"&gt;CodeTips&lt;/a&gt;. The original content is kept up-to-date, but other sources may not be the latest version. &lt;/p&gt;




&lt;p&gt;Have you ever seen Binary, those ones and zeros that computers somehow understand, and wondered what it all means? Well,&lt;br&gt;
today we're going to demistify some of if by creating a small application that converts from binary to decimal. &lt;/p&gt;
&lt;h3&gt;
  
  
  What is decimal?
&lt;/h3&gt;

&lt;p&gt;Decimal is the numbering system that most of us use everyday. We're taught it from a young age, so it may seem like the&lt;br&gt;
only logical way of counting. Let's take a quick look at what it looks like to count in decimal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ..... 1001
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Decimal can also be referred to as Base 10. It includes the numbers 0-9 (ten possibilities) and each column in a number&lt;br&gt;
is a power of ten. &lt;/p&gt;

&lt;p&gt;Let's look at an example by breaking down the number 5,743, which we know is Five Thousand, Seven Hundred, and Fourty Three. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.codetips.co.uk%2Fassets%2Fimages%2Fcontent%2Fcreate-a-binary-to-decimal-converter-base-ten-representation.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.codetips.co.uk%2Fassets%2Fimages%2Fcontent%2Fcreate-a-binary-to-decimal-converter-base-ten-representation.svg" title="Base ten representation" alt="Base ten representation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, what did I mean when I said each column in a number is a power of ten? If we look at the above image, starting from the right-most box, we can say:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ten to the power of Zero (10^0) is 1. We have Three in this column, so our calculation is 3x1 (3).&lt;/li&gt;
&lt;li&gt;Ten to the power of One (10^1) is 10. We have Four in this column, so our calculation is 4x10 (40).&lt;/li&gt;
&lt;li&gt;Ten to the power of Two (10^2) is 100. We have Seven in this column, so our calculation is 7x100 (700).&lt;/li&gt;
&lt;li&gt;Ten to the power of Three (10^3) is 1000. We have Five in this column, so our calculation is 5x1000 (5000).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.codetips.co.uk%2Fassets%2Fimages%2Fcontent%2Fcreate-a-binary-to-decimal-converter-base-ten-power-representation.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.codetips.co.uk%2Fassets%2Fimages%2Fcontent%2Fcreate-a-binary-to-decimal-converter-base-ten-power-representation.svg" title="Base ten power representation" alt="Base ten power representation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Adding all of the numbers (5000 + 700 + 40 + 3) gives us 5,743.&lt;/p&gt;
&lt;h3&gt;
  
  
  What is binary?
&lt;/h3&gt;

&lt;p&gt;The above explanation of decimal may seem basic and pointless, but it's going to help to explain what binary is in this&lt;br&gt;
section.&lt;/p&gt;

&lt;p&gt;Binary, like decimal, is just a numbering system. Unlike decimal, it is referred to as Base 2, only includes&lt;br&gt;
the numbers 0 and 1 (two possibilities) and each column is a power of two. &lt;/p&gt;

&lt;p&gt;Let's look at an example by breaking down the binary number 10100101. Unlike the previous section it's not immediately clear&lt;br&gt;
what this number is, so we're going to walk through the same steps to find out. &lt;/p&gt;

&lt;p&gt;We know each column in a binary number is a power of two so, starting from the right-most number, we can say:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Two to the power of Zero (2^0) is 1. We have One in this column, so our calculation is 1x1 (1).&lt;/li&gt;
&lt;li&gt;Two to the power of One (2^1) is 2. We have Zero in this column, so our calculation is 0x2 (0).&lt;/li&gt;
&lt;li&gt;Two to the power of Two (2^2) is 4. We have One in this column, so our calculation is 1x4 (4).&lt;/li&gt;
&lt;li&gt;Two to the power of Three (2^3) is 8. We have Zero in this column, so our calculation is 0x8 (0).&lt;/li&gt;
&lt;li&gt;Two to the power of Four (2^4) is 16. We have Zero in this column, so our calculation is 0x16 (0).&lt;/li&gt;
&lt;li&gt;Two to the power of Five (2^5) is 32. We have One in this column, so our calculation is 1x32 (32).&lt;/li&gt;
&lt;li&gt;Two to the power of Six (2^6) is 64. We have Zero in this column, so our calculation is 0x64 (0).&lt;/li&gt;
&lt;li&gt;Two to the power of Seven (2^7) is 128. We have One in this column, so our calculation is 1x128 (128).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.codetips.co.uk%2Fassets%2Fimages%2Fcontent%2Fcreate-a-binary-to-decimal-converter-base-two-power-representation.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.codetips.co.uk%2Fassets%2Fimages%2Fcontent%2Fcreate-a-binary-to-decimal-converter-base-two-power-representation.svg" title="Base two power representation" alt="Base two power representation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Adding all the numbers (128 + 0 + 32 + 0 + 0 + 4 + 0 + 1) gives us 165. So, as you can see, at it's most basic&lt;br&gt;
level, binary is just a numbering system.&lt;/p&gt;
&lt;h3&gt;
  
  
  What are we building?
&lt;/h3&gt;

&lt;p&gt;In the last two sections we learnt that binary, like decimal, is just a numbering system. We also, unbeknowingly,&lt;br&gt;
detailed how to convert from binary to decimal (notice how we calculated the decimal representation for each binary&lt;br&gt;
digit, and then added them all up). &lt;/p&gt;

&lt;p&gt;We're now going to use this knowledge to write a programme that will perform this conversion for us.&lt;/p&gt;

&lt;p&gt;The following sections will show you how to write such a programme in JavaScript and Go. &lt;/p&gt;

&lt;p&gt;Note: Neither of the following sections are "production ready" - the code is to illustrate how to perform the conversion&lt;br&gt;
from binary to decimal in code, and we have omitted error handling and type checking for brevity. &lt;/p&gt;
&lt;h4&gt;
  
  
  JavaScript Implementation
&lt;/h4&gt;

&lt;p&gt;We know the best approach, to convert from binary to decimal, is to start with the right-most number/column. Let's start&lt;br&gt;
by writing a simple &lt;code&gt;binaryToDecimal&lt;/code&gt; function, which accepts a string (our binary number) and prints it out from the&lt;br&gt;
right-most column to the left-most column.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;binaryToDecimal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;binary&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;binary&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;binary&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because we're only printing out the numbers, our function just contains a simple &lt;a href="https://www.codetips.co.uk/what-are-loops" rel="noopener noreferrer"&gt;for loop&lt;/a&gt; (see &lt;a href="https://www.codetips.co.uk/arrays-and-loops-in-javascript" rel="noopener noreferrer"&gt;Arrays and Loops&lt;br&gt;
in JavaScript&lt;/a&gt; for a JavaScript specific explanation) which starts at end of the input&lt;br&gt;
(&lt;code&gt;binary.length-1&lt;/code&gt;), continues while &lt;code&gt;i&lt;/code&gt; is less than or equal to &lt;code&gt;0&lt;/code&gt;, and decrements &lt;code&gt;i&lt;/code&gt; by one for each loop.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;binaryToDecimal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1000101&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 1010001&lt;/span&gt;
&lt;span class="nf"&gt;binaryToDecimal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1110001&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 1000111&lt;/span&gt;
&lt;span class="nf"&gt;binaryToDecimal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1000100&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 0010001&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We know that each column, in a binary number, is a power of two so let's change our function to print out the exponent&lt;br&gt;
of each column.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;binaryToDecimal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;binary&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;pow&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;

    &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;binary&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pow&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="nx"&gt;pow&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We initialise a new &lt;code&gt;pow&lt;/code&gt; variable to zero because, like we did when calculating manually above, we start with two to&lt;br&gt;
the power of zero (2^0). &lt;/p&gt;

&lt;p&gt;On each loop, we work out the result of two to the power of &lt;code&gt;pow&lt;/code&gt; (2^pow), log the result and increment &lt;code&gt;pow&lt;/code&gt; ready for the next loop.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;binaryToDecimal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1000101&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="cm"&gt;/**
1
2
4
8
16
32
64
*/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We now have a function that accepts a string representation of a binary number, starts at the right-most column and&lt;br&gt;
works out the decimal representation for each column. The last thing to do is to calculate each column, and add the&lt;br&gt;
result together to get our decimal representation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;binaryToDecimal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;binary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;pow&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;

    &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;binary&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pow&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;binary&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="nx"&gt;pow&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We've now added a &lt;code&gt;result&lt;/code&gt; variable, which we increment based on the result of &lt;code&gt;r * parseInt(binary[i],10)&lt;/code&gt; where &lt;code&gt;r&lt;/code&gt; is&lt;br&gt;
the result of our power calculation and &lt;code&gt;parseInt&lt;/code&gt; will yield either zero or one.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;binaryToDecimal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;10100101&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 165&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's all there is to a binary to decimal converter. Keep reading if you'd like to see the Go implementation, or&lt;br&gt;
visit our handy &lt;a href="https://www.codetips.co.uk/binary-to-decimal-converter-tool" rel="noopener noreferrer"&gt;binary to decimal converter&lt;/a&gt;, which uses this logic, if you'd like to&lt;br&gt;
test out some numbers. &lt;/p&gt;
&lt;h4&gt;
  
  
  Go Implementation
&lt;/h4&gt;

&lt;p&gt;Like we discussed above, in the JavaScript implementation, we know the best approach, to convert from binary to decimal, is to start with the right-most number/column. &lt;/p&gt;

&lt;p&gt;We'll follow a similar pattern by first creating a simple &lt;code&gt;binaryToDecimal&lt;/code&gt; function, which accepts a string (our binary&lt;br&gt;
number) and prints it out from the right-most column to the left-most column.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;binaryToDecimal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"1000101"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// 1010001&lt;/span&gt;
    &lt;span class="n"&gt;binaryToDecimal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"1110001"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// 1000111&lt;/span&gt;
    &lt;span class="n"&gt;binaryToDecimal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"1000100"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// 0010001&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;binaryToDecimal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;binary&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;binary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;binary&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because we're only printing out the numbers, our function just contains a simple &lt;a href="https://www.codetips.co.uk/what-are-loops" rel="noopener noreferrer"&gt;for loop&lt;/a&gt; (see &lt;a href="https://www.codetips.co.uk/arrays-and-loops-in-go" rel="noopener noreferrer"&gt;Arrays and Loops&lt;br&gt;
in Go&lt;/a&gt; for a Go specific explanation) which starts at end of the input (&lt;code&gt;len(length)-1&lt;/code&gt;), continues while &lt;code&gt;i&lt;/code&gt; is less than or equal to &lt;code&gt;0&lt;/code&gt;, and decrements &lt;code&gt;i&lt;/code&gt; by one for each loop.&lt;/p&gt;

&lt;p&gt;Note how we are converting the value (&lt;code&gt;binary[i]&lt;/code&gt;) to a string. We have to do this because looping over a string in Go&lt;br&gt;
returns the byte representation of each character (48 for 0, 49 for 1). &lt;/p&gt;

&lt;p&gt;Because we are using characters that fit into one byte (0 and 1) this is safe. However, be cautious about using this technique when you cannot guarantee each character&lt;br&gt;
will fit into one byte as you may get skewed results.&lt;/p&gt;

&lt;p&gt;We know that each column, in a binary number, is a power of two so let's change our function to print out the exponent&lt;br&gt;
of each column.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"math"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;binaryToDecimal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"1000101"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c"&gt;/**
    1
    2
    4
    8
    16
    32
    64
    */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;binaryToDecimal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;binary&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pow&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;binary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pow&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;pow&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We initialise a new &lt;code&gt;pow&lt;/code&gt; variable to zero because, like we did when calculating manually, we start with two to the power of zero (2^0). &lt;/p&gt;

&lt;p&gt;On each loop, we work out the result of two to the power of &lt;code&gt;pow&lt;/code&gt; (2^pow), log the result and increment &lt;code&gt;pow&lt;/code&gt; ready for the next loop. &lt;/p&gt;

&lt;p&gt;We now have a function that accepts a string representation of a binary number, starts at the right-most column and&lt;br&gt;
works out the decimal representation for each column. The last thing to do is to calculate each column, and add the&lt;br&gt;
result together to get our decimal representation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"math"&lt;/span&gt;
    &lt;span class="s"&gt;"strconv"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;binaryToDecimal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"1000101"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  &lt;span class="c"&gt;// 69&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;binaryToDecimal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"10100101"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c"&gt;// 165&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;binaryToDecimal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;binary&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;int64&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="kt"&gt;int64&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pow&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;binary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pow&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;strconv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ParseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;binary&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="kt"&gt;int64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;

        &lt;span class="n"&gt;pow&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We've now added a &lt;code&gt;result&lt;/code&gt; variable, which we increment based on the result of &lt;code&gt;r * i&lt;/code&gt; where &lt;code&gt;r&lt;/code&gt; is the result of our power calculation and &lt;code&gt;i&lt;/code&gt; is the result of converting our character (0 or 1) to an int. &lt;/p&gt;

&lt;p&gt;And that's how to create a binary to decimal converter in Go. Feel free to visit our handy &lt;a href="https://www.codetips.co.uk/binary-to-decimal-converter-tool" rel="noopener noreferrer"&gt;binary to decimal converter&lt;/a&gt;, which uses the JavaScript logic, if you'd like to test out some numbers. &lt;/p&gt;




&lt;p&gt;&lt;a href="https://www.codetips.co.uk" rel="noopener noreferrer"&gt;CodeTips&lt;/a&gt; strives to help beginners, with zero or very little experience, learn to code.&lt;/p&gt;

&lt;p&gt;We do cross-post to other sites to reach a wider audience, but why not &lt;a href="https://mailchi.mp/92cccf7024b2/codetips" rel="noopener noreferrer"&gt;subscribe to our newsletter&lt;/a&gt; and get the newest articles straight to your mailbox? &lt;/p&gt;

&lt;p&gt;The original source for this content is &lt;a href="https://www.codetips.co.uk" rel="noopener noreferrer"&gt;CodeTips&lt;/a&gt;. The original content is kept up-to-date, but other sources may not be the latest version. &lt;/p&gt;




</description>
      <category>learning</category>
      <category>go</category>
      <category>binary</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Writing for CodeTips</title>
      <dc:creator>Si</dc:creator>
      <pubDate>Fri, 10 Jan 2020 16:32:13 +0000</pubDate>
      <link>https://forem.com/codetips/writing-for-codetips-2o7o</link>
      <guid>https://forem.com/codetips/writing-for-codetips-2o7o</guid>
      <description>&lt;p&gt;&lt;a href="https://www.codetips.co.uk"&gt;CodeTips&lt;/a&gt; is not a Social Media platform like Dev, it's not an "open for everyone/everything" writing experience like Medium.&lt;/p&gt;

&lt;p&gt;I like to see CodeTips as between a personal blog and everything else out there.&lt;/p&gt;

&lt;p&gt;We're never going to have hundreds of writers, nor do we want to, that can write whatever they want like FreeCodeCamp. We want a handful of regular writers, that decide what to write about.&lt;/p&gt;

&lt;p&gt;If you are interested in writing for &lt;a href="https://www.codetips.co.uk"&gt;CodeTips&lt;/a&gt; please leave a comment, or get in &lt;a href="https://www.codetips.co.uk/contact-us/"&gt;Contact&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>watercooler</category>
      <category>codetips</category>
      <category>writing</category>
    </item>
    <item>
      <title>Merry Christmas to all</title>
      <dc:creator>Si</dc:creator>
      <pubDate>Wed, 25 Dec 2019 14:09:27 +0000</pubDate>
      <link>https://forem.com/devdrake0/merry-christmas-to-all-mp7</link>
      <guid>https://forem.com/devdrake0/merry-christmas-to-all-mp7</guid>
      <description>

</description>
      <category>meta</category>
    </item>
    <item>
      <title>How To create a CRUD API, using Node.js and Express, on Ubuntu 18.04</title>
      <dc:creator>Si</dc:creator>
      <pubDate>Thu, 19 Dec 2019 12:25:51 +0000</pubDate>
      <link>https://forem.com/codetips/how-to-create-a-crud-api-using-node-js-and-express-on-ubuntu-18-04-24h8</link>
      <guid>https://forem.com/codetips/how-to-create-a-crud-api-using-node-js-and-express-on-ubuntu-18-04-24h8</guid>
      <description>&lt;p&gt;&lt;a href="https://www.codetips.co.uk" rel="noopener noreferrer"&gt;CodeTips&lt;/a&gt; strives to help beginners, with zero or very little experience, learn to code.&lt;/p&gt;

&lt;p&gt;We do cross-post to other sites to reach a wider audience, but why not &lt;a href="https://mailchi.mp/92cccf7024b2/codetips" rel="noopener noreferrer"&gt;subscribe to our newsletter&lt;/a&gt; and get the newest articles straight to your mailbox? &lt;/p&gt;

&lt;p&gt;The original source for this content is &lt;a href="https://www.codetips.co.uk" rel="noopener noreferrer"&gt;CodeTips&lt;/a&gt;. The original content is kept up-to-date, but other sources may not be the latest version. &lt;/p&gt;




&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.codetips.co.uk%2Fcontent%2Fimages%2F2019%2F12%2FWebp.net-compress-image--1-.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.codetips.co.uk%2Fcontent%2Fimages%2F2019%2F12%2FWebp.net-compress-image--1-.jpg" alt="How To create a CRUD API, using Node.js and Express, on Ubuntu 18.04"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;An API (Application Programming Interface) is a way of interacting with a service, through a series of predefined requests.&lt;/p&gt;

&lt;p&gt;Express is an open source web framework, for Node.js, designed to make developing websites, web apps, and API's easier.&lt;/p&gt;

&lt;p&gt;In this tutorial, you will create a simple CRUD API on a single Ubuntu 18.04 server. The API will be accessible through a public IP address, allowing you to access it from anywhere with an internet connection.&lt;/p&gt;

&lt;p&gt;To get started, sign-up for Digital Ocean using &lt;a href="https://m.do.co/c/5a7b87513ab0" rel="noopener noreferrer"&gt;this&lt;/a&gt; referral link and get $100 credit!&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;An Ubuntu 18.04 server setup, as described in the &lt;a href="https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-18-04" rel="noopener noreferrer"&gt;initial server setup guide for Ubuntu 18.04&lt;/a&gt;. You should have a non-root user with sudo privileges and an active firewall.&lt;/li&gt;
&lt;li&gt;Node.js and PM2 installed on your Ubuntu 18.04 server, as described in &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-set-up-a-node-js-application-for-production-on-ubuntu-18-04" rel="noopener noreferrer"&gt;How To Set Up a Node.js Application for Production on Ubuntu 18.04&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;A basic understanding of CURL&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 1 — Create a simple Express App that serves "Hello World"
&lt;/h2&gt;

&lt;p&gt;In this step, we’ll create a very simple API, with one endpoint, that we’ll then build on in future steps.&lt;/p&gt;

&lt;p&gt;To begin, create a new directory in a location of your choosing, and create a default &lt;code&gt;package.json&lt;/code&gt; file, by running the following command in a terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm init -y

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the same terminal, install the &lt;code&gt;express&lt;/code&gt; dependency:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i express

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, open the project in a code editor of your choice and create a new &lt;code&gt;server.js&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Within the new file, add the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require('express')
const app = express()
const port = 3000

app.get('/hello', (req, res) =&amp;gt; res.send('Hello World!'))

app.listen(port, () =&amp;gt; console.log(`App listening on port ${port}!`))

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using the &lt;code&gt;express&lt;/code&gt; application, we define a &lt;code&gt;/hello&lt;/code&gt; endpoint, that will return the text &lt;code&gt;Hello World!&lt;/code&gt;, and run our application on port &lt;code&gt;3000&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Note that the &lt;code&gt;/hello&lt;/code&gt; endpoint will only match for GET requests, as we've defined it using the &lt;code&gt;app.get&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;In your terminal, run the following command to start the application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node index.js

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see the following output as a result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ node index.js
App listening on port 3000!

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now open your favourite browser, and navigate to &lt;code&gt;localhost:3000/hello&lt;/code&gt;. If everything worked successfully, &lt;code&gt;Hello World!&lt;/code&gt; should be displayed in your browser.&lt;/p&gt;

&lt;p&gt;Congratulations - you have created an API, and you can communicate with it via the &lt;code&gt;/hello&lt;/code&gt; endpoint. We’ll build on this structure in the following steps, and make our API even better!&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2 — Extend the application to get a property from in-memory state.
&lt;/h2&gt;

&lt;p&gt;At this point we have one endpoint, &lt;code&gt;/hello&lt;/code&gt;, that returns the text &lt;code&gt;Hello World!&lt;/code&gt;. While it’s awesome that we’ve created an API, as far as functionality goes it’s not that helpful.&lt;/p&gt;

&lt;p&gt;In this step we’ll take our API and have it return some useful data. We’ll be using an example of employee details.&lt;/p&gt;

&lt;p&gt;First, let's add another endpoint to our application that will retrieve a record.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require('express')
const app = express()
const port = 3000

app.get('/hello', (req, res) =&amp;gt; res.send('Hello World!'))

app.get('/employee/:id', (req, res) =&amp;gt; {
  console.log(req.params.id)
  res.sendStatus(200)
})

app.listen(port, () =&amp;gt; console.log(`App listening on port ${port}!`))

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We define a new &lt;code&gt;/employee&lt;/code&gt; endpoint, just like we did for the &lt;code&gt;/hello&lt;/code&gt; endpoint, but we're also using a query parameter.&lt;/p&gt;

&lt;p&gt;Query parameters are defined using a colon, and the preceding text is used to reference that parameter. In our &lt;code&gt;/employee&lt;/code&gt; endpoint, we've defined a query parameter called &lt;code&gt;id&lt;/code&gt;, and our &lt;code&gt;console.log&lt;/code&gt; statement shows how we reference the value.&lt;/p&gt;

&lt;p&gt;Stop and start the application, so the new code changes take effect, open your browser and navigate to &lt;code&gt;http://localhost:3000/employee/wiggly&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You should see the following output in your terminal, as a result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ node index.js
App listening on port 3000!
wiggly

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice how &lt;code&gt;wiggly&lt;/code&gt; was printed to the terminal, which is what we used in the URL (&lt;code&gt;/employee/wiggly&lt;/code&gt;). Change &lt;code&gt;wiggly&lt;/code&gt; to anything you like, and you should see that printed in the terminal.&lt;/p&gt;

&lt;p&gt;The power of this technique enables us to define one route, which can be used for many different scenarios. For example, an endpoint that can retrieve an employees details using a unique identifier, which is exactly what we're going to do now!&lt;/p&gt;

&lt;p&gt;Let's create an Object, to act as in-memory state for our application, and add some fictional employees:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/**  
We'll use the Object key as the unique identifier, made up of the
first letter of the employees first name and whole of their last name.
*/
const employees = {
  'sbrown': {
    firstName: 'Steve',
    lastName: 'Brown',
    department: 'Engineering'      
  },
  'jsmith': {
    firstName: 'Janine',
    lastName: 'Smith',
    department: 'Marketing'      
  },
  'kjones': {
    firstName: 'Karen',
    lastName: 'Jones',
    department: 'Sales'      
  },
  'bwilliams': {
    firstName: 'Ben',
    lastName: 'Williams',
    department: 'Administration'
  }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, instead of logging out the &lt;code&gt;id&lt;/code&gt; parameter value, let's return the employee details from our Object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app.get('/employee/:id', (req, res) =&amp;gt; {
  res.json(employees[req.params.id])
})

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we'll be returning a JSON object we're using the &lt;code&gt;res.json&lt;/code&gt; method which, among other things, sets all of the correct headers and returns the response in JSON.&lt;/p&gt;

&lt;p&gt;Restart the application and navigate to &lt;code&gt;http://localhost:3000/employee/kjones&lt;/code&gt; in your browser.&lt;/p&gt;

&lt;p&gt;You should see the following response in your browser:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{"firstName":"Karen","lastName":"Jones","department":"Sales"}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Try changing &lt;code&gt;kjones&lt;/code&gt; to any of the other unique identifiers, in the &lt;code&gt;employees&lt;/code&gt; object, and see the returned values change.&lt;/p&gt;

&lt;p&gt;Now, try changing the &lt;code&gt;id&lt;/code&gt; to something non-existent (e.g. &lt;code&gt;http://localhost:3000/employee/wiggly&lt;/code&gt;) in the browser. Nothing is returned, which is correct, but we're not giving the user any indication why; did something go wrong, or does the employee just not exist?&lt;/p&gt;

&lt;p&gt;Let's update the endpoint to check if the given employee &lt;code&gt;id&lt;/code&gt; exists and, if not, we'll return a &lt;code&gt;404 Not Found&lt;/code&gt; response, otherwise we'll return the employee details.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app.get('/employee/:id', (req, res) =&amp;gt; {
  const employee = employees[req.params.id]

  if (!employee) {
    return res.sendStatus(404)
  }

  res.json(employee)
})

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart your application, and try the same URL in the browser. The response should now be &lt;code&gt;Not Found&lt;/code&gt;, which is a lot more informative to the user.&lt;/p&gt;

&lt;p&gt;In this step, we took a very simple and not very helpful API and transformed it into one that queries data using query parameters. We also learnt how to handle situations where a non-existent employee is queried.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2 — Extend the application to add/delete a property from in-memory state.
&lt;/h2&gt;

&lt;p&gt;We now have an API that can retrieve an employee, based on the employee id, but what if an employee joins/leaves the company? We need a way to add/remove them from our employees list, which is what we’ll achieve in this step.&lt;/p&gt;

&lt;p&gt;Let’s focus on people joining the company first. When someone joins, we want to add them to our &lt;code&gt;employees&lt;/code&gt; object so they can be queried later on.&lt;/p&gt;

&lt;p&gt;To do this we will use a &lt;code&gt;POST&lt;/code&gt; request, which we declare in the same way as our &lt;code&gt;GET&lt;/code&gt; requests above.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app.post('/employee', (req, res) =&amp;gt; {
  res.sendStatus(200)
})

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart your application to apply our code changes.&lt;/p&gt;

&lt;p&gt;Our new route doesn’t do anything, other than return a &lt;code&gt;200 OK&lt;/code&gt; status because, before we get into writing the logic, I want to talk a bit about how we can make a &lt;code&gt;POST&lt;/code&gt; request.&lt;/p&gt;

&lt;p&gt;When you enter an address into a browser, like we did in the previous steps ( e.g. &lt;code&gt;http://localhost:3000/hello&lt;/code&gt; ), we are requesting a resource by making a &lt;code&gt;GET&lt;/code&gt; request.&lt;/p&gt;

&lt;p&gt;We can’t use the same mechanism to make any other type of request (&lt;code&gt;POST&lt;/code&gt;, &lt;code&gt;PUT&lt;/code&gt;, &lt;code&gt;DELETE&lt;/code&gt; etc), so how do we reach these endpoints? There are quite a few different methods, but we’re only going to focus on one - CURL.&lt;/p&gt;

&lt;p&gt;To make a &lt;code&gt;POST&lt;/code&gt; request, to our new endpoint, using CURL, run the following command in a terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -X POST 'http://localhost:3000/employee'

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The only functionality we added to our new endpoint was to return a &lt;code&gt;200 OK&lt;/code&gt; status, which is what you should see as a response in your terminal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ curl -X POST 'http://localhost:3000/employee'
OK

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s build this logic out to add an employee to our &lt;code&gt;employees&lt;/code&gt; object.&lt;/p&gt;

&lt;p&gt;The first thing we need to do is to get the new employees details. If we look at our existing employees, we need three pieces of information - &lt;code&gt;firstName&lt;/code&gt;, &lt;code&gt;lastName&lt;/code&gt; and &lt;code&gt;department&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In the last section we used the &lt;code&gt;req.params&lt;/code&gt; property to extract the &lt;code&gt;id&lt;/code&gt; URL parameter. When dealing with a &lt;code&gt;POST&lt;/code&gt; request, we have the ability to use a request body.&lt;/p&gt;

&lt;p&gt;Using CURL, we can combine the Header (&lt;code&gt;-H&lt;/code&gt;) flag to specify a content type, which informs the server what format the request content is in, and the Data (&lt;code&gt;--data&lt;/code&gt;) flag to pass through a JSON object.&lt;/p&gt;

&lt;p&gt;We’ll sending a JSON object so we’ll set a &lt;code&gt;Content-Type&lt;/code&gt; header or &lt;code&gt;application/json&lt;/code&gt;, to tell the server we’re sending JSON, and we’ll specify our new employee as data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CURL -X POST 'http://localhost:3000/employee' -H 'content-type: application/json' --data '{"firstName": "John", "lastName": "Doe", "department": "engineering"}'

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are now making a &lt;code&gt;POST&lt;/code&gt; request, to &lt;code&gt;http://localhost:3000/employee&lt;/code&gt;, with the above JSON object as our Request Body.&lt;/p&gt;

&lt;p&gt;By default, our Express application won’t parse this JSON object, so we need to enable some middleware to enable it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require('express')
const app = express()
const port = 3000

/**
-- Employee object
*/

/** 
Middleware that looks at requests with an application/json 
Content-Type header and stores the request body, as JSON,
in req.body
*/
app.use(express.json())

/**
-- Other endpoints
*/

app.post('/employee', (req, res) =&amp;gt; {
  console.log(req.body)
  res.sendStatus(200)
})

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before defining any of your routes, tell your &lt;code&gt;app&lt;/code&gt; to use the &lt;code&gt;express.json&lt;/code&gt; middleware. Then, in our new endpoint, log the Request Body.&lt;/p&gt;

&lt;p&gt;Restart the application and make the request, with the JSON request body, using CURL. You should see the following output in the terminal running your application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ node index.js
App listening on port 3000!
{ firstName: 'John', lastName: 'Doe', department: 'engineering' }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can now receive a new employee object from our new &lt;code&gt;POST&lt;/code&gt; endpoint, so let’s build out our logic to ensure we get all three required fields (&lt;code&gt;firstName&lt;/code&gt;, &lt;code&gt;lastName&lt;/code&gt; and &lt;code&gt;department&lt;/code&gt;), construct the &lt;code&gt;id&lt;/code&gt; from the &lt;code&gt;firstName&lt;/code&gt; and &lt;code&gt;lastName&lt;/code&gt;, and then add it to our &lt;code&gt;employee&lt;/code&gt; object if that &lt;code&gt;id&lt;/code&gt; isn’t already in use.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app.post('/employee', (req, res) =&amp;gt; {
  const { firstName, lastName, department } = req.body

  if (!firstName || !lastName || !department) {
    // 400 = bad request. It indicates to the user that
    // there was something wrong with their request.
    return res.status(400).send('One or more required fields are missing')
  }

  const id = (firstName[0] + lastName).toLowerCase()

  if (employees[id]) {
    // Provide a custom message so the user knows what the
    // problem with the request is.
    return res.status(400).send('A user with that id already exists')
  }

  // We set the employee properties explicitly, just in case
  // the user sends other fields through that we're not interested
  // in storing.
  employees[id] = { firstName, lastName, department }

  res.sendStatus(200)
})

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart the application and try the following scenarios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make a &lt;code&gt;POST&lt;/code&gt; request without one or more of the required fields.&lt;/li&gt;
&lt;li&gt;Make a &lt;code&gt;POST&lt;/code&gt; request with a &lt;code&gt;firstName&lt;/code&gt; and &lt;code&gt;lastName&lt;/code&gt; that makes an &lt;code&gt;id&lt;/code&gt; which already exists (e.g. &lt;code&gt;Sarah Brown&lt;/code&gt; which would conflict with &lt;code&gt;Steve Brown&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Make a &lt;code&gt;POST&lt;/code&gt; request that succeeds and then make a &lt;code&gt;GET&lt;/code&gt; request that retrieves the new employees details.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, let’s use what we’ve learnt so far to create a new &lt;code&gt;DELETE&lt;/code&gt; endpoint that takes an employees &lt;code&gt;id&lt;/code&gt; and removes it from our &lt;code&gt;employees&lt;/code&gt; object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app.delete('/employee/:id', (req, res) =&amp;gt; {
  const employee = employees[req.params.id]

  if (!employee) {
    return res.sendStatus(404)
  }

  delete employees[req.params.id];

  res.sendStatus(200)
})

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’ll notice this is very similar to our &lt;code&gt;GET&lt;/code&gt; employee endpoint; we’re using the URL parameter, checking that the employee exists and returning a &lt;code&gt;200&lt;/code&gt; status if everything succeeds. The only difference is we delete the employee, from the &lt;code&gt;employees&lt;/code&gt; object, by their &lt;code&gt;id&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Making a &lt;code&gt;DELETE&lt;/code&gt; request in CURL is very similar to the &lt;code&gt;POST&lt;/code&gt; request we saw above:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -X DELETE 'http://localhost:3000/employee/sbrown'

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart the application and try the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make a &lt;code&gt;DELETE&lt;/code&gt; request to our new endpoint, with an existing employee &lt;code&gt;id&lt;/code&gt; (e.g. &lt;code&gt;http://localhost:3000/employees/sbrown&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Make a &lt;code&gt;GET&lt;/code&gt; request to our employees endpoint, with the same employee &lt;code&gt;id&lt;/code&gt; (e.g. &lt;code&gt;http://localhost:3000/employees/sbrown&lt;/code&gt;) and see that you now get a &lt;code&gt;404 Not Found&lt;/code&gt; response.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Congratulations - you’ve created a CRUD API!&lt;/p&gt;

&lt;p&gt;In this step we really took our API to the next level, by allowing our users to add and delete employees, and we learnt how to deal with &lt;code&gt;POST&lt;/code&gt; data by enabling the &lt;code&gt;express.json&lt;/code&gt; middleware.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3 — Deploy the API to Digital Ocean
&lt;/h2&gt;

&lt;p&gt;We now have an API that can create, delete and retrieve an employee. What we’ve done so far is awesome, but it only lives on our laptop. To take our application to the next level, we need to host it on a publicly accessible server that we can access it from anywhere in the world.&lt;/p&gt;

&lt;p&gt;As per our prerequisites, you should have a Digital Ocean server. First, make a new directory on your server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mkdir ~/simple-crud

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, using a terminal in your local project directory, copy the necessary files to your server by running the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ scp package-lock.json package.json server.js ubuntu@YOUR_IP:./simple-crud/

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;ubuntu&lt;/code&gt; with the user you created, and &lt;code&gt;YOUR_IP&lt;/code&gt;` with your servers public IP address.&lt;/p&gt;

&lt;p&gt;We’ve now copied our &lt;code&gt;package-lock.json&lt;/code&gt;, &lt;code&gt;package.json&lt;/code&gt; and &lt;code&gt;server.js&lt;/code&gt; file to our new &lt;code&gt;simple-crud&lt;/code&gt; folder on our server.&lt;/p&gt;

&lt;p&gt;Next, while in the &lt;code&gt;simple-crud&lt;/code&gt; folder on your server, install the applications dependencies:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`&lt;br&gt;
$ npm i&lt;/p&gt;

&lt;p&gt;`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Lastly, start the application using PM2:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`&lt;br&gt;
$ pm2 start server.js --name "simple-crud"&lt;/p&gt;

&lt;p&gt;`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To make sure the application has started correctly, you can run &lt;code&gt;pm2 logs&lt;/code&gt; and ensure you see the following log line:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`&lt;br&gt;
$ pm2 logs&lt;br&gt;
0|simple-c | App listening on port 3000!&lt;/p&gt;

&lt;p&gt;`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Next, we’ll amend the default NGINX &lt;code&gt;server&lt;/code&gt; block to forward all requests to our application.&lt;/p&gt;

&lt;p&gt;Use &lt;code&gt;vi&lt;/code&gt; to edit the default configuration:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`&lt;br&gt;
$ sudo vi /etc/nginx/sites-available/default&lt;/p&gt;

&lt;p&gt;`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then, replace the root location (&lt;code&gt;location /&lt;/code&gt;) with the following code, which will forward any HTTP requests to our application.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`&lt;br&gt;
location / {&lt;br&gt;
    proxy_pass &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt;;&lt;br&gt;
    proxy_http_version 1.1;&lt;br&gt;
    proxy_set_header Upgrade $http_upgrade;&lt;br&gt;
    proxy_set_header Connection 'upgrade';&lt;br&gt;
    proxy_set_header Host $host;&lt;br&gt;
    proxy_cache_bypass $&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In this step we took our application from only running on our laptop, to running on a Digital Ocean server, meaning our application can be accessed from anywhere in the world!&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4 — Use our new API, hosted on Digital Ocean, instead of localhost
&lt;/h2&gt;

&lt;p&gt;We now have an application running on a Digital Ocean server, that can be accessed from anywhere in the world. We know how to access our API locally, but how do we interact with it now?&lt;/p&gt;

&lt;p&gt;We just replace &lt;code&gt;localhost&lt;/code&gt; with our public IP address in our CURL commands:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`&lt;br&gt;
$ curl -X GET '&lt;a href="http://157.245.243.1/employee/sbrown" rel="noopener noreferrer"&gt;http://157.245.243.1/employee/sbrown&lt;/a&gt;'&lt;br&gt;
{"firstName":"Steve","lastName":"Brown","department":"Engineering"}&lt;/p&gt;

&lt;p&gt;$ curl -X POST '&lt;a href="http://157.245.243.1/employee" rel="noopener noreferrer"&gt;http://157.245.243.1/employee&lt;/a&gt;' -H 'content-type: application/json' --data '{"firstName": "John", "lastName": "Doe", "department": "engineering"}'&lt;br&gt;
OK&lt;/p&gt;

&lt;p&gt;$ curl -X DELETE '&lt;a href="http://157.245.243.1/employee/jsmith" rel="noopener noreferrer"&gt;http://157.245.243.1/employee/jsmith&lt;/a&gt;'&lt;br&gt;
OK&lt;/p&gt;

&lt;p&gt;`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;You have successfully created a CRUD API, with in-memory state, and you deployed it to a Digital Ocean server meaning you can interact with it from anywhere using a public IP address.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://www.codetips.co.uk" rel="noopener noreferrer"&gt;CodeTips&lt;/a&gt; strives to help beginners, with zero or very little experience, learn to code.&lt;/p&gt;

&lt;p&gt;We do cross-post to other sites to reach a wider audience, but why not &lt;a href="https://mailchi.mp/92cccf7024b2/codetips" rel="noopener noreferrer"&gt;subscribe to our newsletter&lt;/a&gt; and get the newest articles straight to your mailbox? &lt;/p&gt;

&lt;p&gt;The original source for this content is &lt;a href="https://www.codetips.co.uk" rel="noopener noreferrer"&gt;CodeTips&lt;/a&gt;. The original content is kept up-to-date, but other sources may not be the latest version. &lt;/p&gt;

</description>
      <category>beginners</category>
      <category>tutorial</category>
      <category>learning</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Two Sum</title>
      <dc:creator>Si</dc:creator>
      <pubDate>Tue, 17 Dec 2019 18:01:57 +0000</pubDate>
      <link>https://forem.com/codetips/two-sum-37lj</link>
      <guid>https://forem.com/codetips/two-sum-37lj</guid>
      <description>&lt;p&gt;&lt;a href="https://www.codetips.co.uk"&gt;CodeTips&lt;/a&gt; strives to help beginners, with zero or very little experience, learn to code.&lt;/p&gt;

&lt;p&gt;We do cross-post to other sites to reach a wider audience, but why not &lt;a href="https://mailchi.mp/92cccf7024b2/codetips"&gt;subscribe to our newsletter&lt;/a&gt; and get the newest articles straight to your mailbox? &lt;/p&gt;

&lt;p&gt;The original source for this content is &lt;a href="https://www.codetips.co.uk"&gt;CodeTips&lt;/a&gt;. The original content is kept up-to-date, but other sources may not be the latest version. &lt;/p&gt;




&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2_ZWnqKH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.codetips.co.uk/content/images/2019/12/Webp.net-compress-image.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2_ZWnqKH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.codetips.co.uk/content/images/2019/12/Webp.net-compress-image.jpg" alt="Two Sum"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this article, we bring you another challenge from &lt;a href="https://www.algodaily.com"&gt;AlgoDaily&lt;/a&gt; called &lt;a href="https://algodaily.com/challenges/two-sum/javascript"&gt;Two Sum&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We recommend trying to complete the challenge yourself, before reading our explanation, &lt;a href="https://algodaily.com/challenges/two-sum/javascript"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Challenge
&lt;/h2&gt;

&lt;p&gt;Given an array of integers, return the indices of the two numbers in it that add up to a specific goal number.&lt;/p&gt;

&lt;p&gt;So let's say our goal number was 10. Our numbers to sum to it would be 3 and 7, and their indices 1 and 3 respectively.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let arr = [1, 3, 6, 7, 9];
let goal = 10;
twoSum(arr, goal); // [1, 3]

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You may assume that each input would have exactly one solution. Additionally, you may not use the same element twice. For example, if given a slice of &lt;code&gt;[1,3]&lt;/code&gt; and a goal of &lt;code&gt;2&lt;/code&gt;, you cannot use &lt;code&gt;1&lt;/code&gt; twice and return &lt;code&gt;[0,0]&lt;/code&gt; as your answer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test Cases
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Expect &lt;code&gt;twoSum([1,9,13,20,47], 10)&lt;/code&gt; to equal &lt;code&gt;[0,1]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Expect &lt;code&gt;twoSum([3,2,4,1,9], 12)&lt;/code&gt; to equal &lt;code&gt;[0,4]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Expect &lt;code&gt;twoSum([], 10)&lt;/code&gt; to equal &lt;code&gt;[]&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Learn to complete this challenge using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;if you don’t see your favourite language here, feel free to leave a comment and tell us which one you’d like us to cover or check back at another time and see if we’ve added it.&lt;/p&gt;

&lt;p&gt;The solutions and test cases for this challenge can be found on our &lt;a href="https://github.com/realcodetips"&gt;GitHub account&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Go
&lt;/h3&gt;

&lt;p&gt;First, let’s define our test cases in a file called &lt;code&gt;twosum_test.go&lt;/code&gt;. We’ll use a &lt;a href="https://www.codetips.co.uk/table-driven-tests/"&gt;Table Driven Test&lt;/a&gt; to keep our test cases free of unnecessary duplication and keep them easy to read/maintain.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// twosum_test.go

package twosum

import (
    "fmt"
    "reflect"
    "testing"
)

func TestTwoSum(t *testing.T) {
    testCases := []struct {
        nums []int
        goal int
        expected []int
    }{
        {
            nums: []int{1, 9, 13, 20, 47},
            goal: 10,
            expected: []int{0, 1},
        },
        {
            nums: []int{3, 2, 4, 1, 9},
            goal: 12,
            expected: []int{0, 4},
        },
        {
            nums: []int{},
            goal: 10,
            expected: []int{},
        },
    }
    for ix, tC := range testCases {
        t.Run(fmt.Sprintf("test %d - TwoSum should return expected output", ix), func(t *testing.T) {
            output := TwoSum(tC.nums, tC.goal)

            if !reflect.DeepEqual(tC.expected, output) {
                t.Errorf("expected '%+v' to equal '%+v', but it did not", output, tC.expected)
            }

        })
    }
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Next, let’s create our &lt;code&gt;TwoSum&lt;/code&gt; function declaration. We already know from the test description that we expect a slice of indices and a goal, as input, and that we should return a slice of indices that sum up to the goal, or an empty slice if a match isn’t found.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package twosum

// TwoSum takes a slice of ints and an expected goal, and returns the
// indices that sum together to reach that goal, or an empty slice otherwise.
func TwoSum(nums []int, goal int) []int {
    return []int{}
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; going forward we will omit the &lt;code&gt;package&lt;/code&gt; and &lt;code&gt;import&lt;/code&gt; statements, but they can be found on our &lt;a href="https://github.com/realcodetips"&gt;GitHub account&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Running our tests we get two expected failures, and one passing test (because we hardcoded a response of an empty slice).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;go test -v ./...
=== RUN TestTwoSum
=== RUN TestTwoSum/test_0_-_TwoSum_should_return_expected_output
=== RUN TestTwoSum/test_1_-_TwoSum_should_return_expected_output
=== RUN TestTwoSum/test_2_-_TwoSum_should_return_expected_output
--- FAIL: TestTwoSum (0.00s)
    --- FAIL: TestTwoSum/test_0_-_TwoSum_should_return_expected_output (0.00s)
        twosum_test.go:36: expected '[]' to equal '[0 1]', but it did not
    --- FAIL: TestTwoSum/test_1_-_TwoSum_should_return_expected_output (0.00s)
        twosum_test.go:36: expected '[]' to equal '[0 4]', but it did not
    --- PASS: TestTwoSum/test_2_-_TwoSum_should_return_expected_output (0.00s)
FAIL

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We need to compare two indices at a time, to see if they sum up to the goal. For example, when given an input of &lt;code&gt;[0,1,12,20,9]&lt;/code&gt; and &lt;code&gt;10&lt;/code&gt; we could write down the logic like so:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Take the number at index 0 (&lt;code&gt;0&lt;/code&gt;)

&lt;ul&gt;
&lt;li&gt;Take the number at index 1 (&lt;code&gt;1&lt;/code&gt;), do the numbers equal 10? No, continue.&lt;/li&gt;
&lt;li&gt;Take the number at index 2 (&lt;code&gt;12&lt;/code&gt;), do the numbers equal 10? No, continue.&lt;/li&gt;
&lt;li&gt;Take the number at index 3 (&lt;code&gt;20&lt;/code&gt;), do the numbers equal 10? No, continue.&lt;/li&gt;
&lt;li&gt;Take the number at index 4 (&lt;code&gt;9&lt;/code&gt;), do the numbers equal 10? No, continue.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Take the number at index 1 (&lt;code&gt;1&lt;/code&gt;)

&lt;ul&gt;
&lt;li&gt;Take the number at index 2 (&lt;code&gt;12&lt;/code&gt;), do the numbers equal 10? No, continue.&lt;/li&gt;
&lt;li&gt;Take the number at index 3 (&lt;code&gt;20&lt;/code&gt;), do the numbers equal 10? No, continue.&lt;/li&gt;
&lt;li&gt;Take the number at index 4 (&lt;code&gt;9&lt;/code&gt;), do the numbers equal 10? Yes! Return index 1 and index 4 ([1,4]).
&amp;lt;!--kg-card-end: markdown--&amp;gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s print the indices out first, to make sure we’re getting the expected behaviour.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func TwoSum(nums []int, goal int) []int {
    for ix := range nums {
        for i := ix + 1; i &amp;lt; len(nums)-1; i++ {
            fmt.Printf("Outer index: %d, Inner index: %d \n", ix, i)
        }
    }

    return []int{}
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now let’s add another test case to our &lt;a href="https://www.codetips.co.uk/table-driven-tests/"&gt;Table Driven Test&lt;/a&gt; (below).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    nums: []int{0, 1, 12, 20, 9},
    goal: 10,
    expected: []int{1, 4},
},

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And we’ll comment out the rest of the tests just to observe the &lt;code&gt;Printf&lt;/code&gt; statements for our new test case:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;go test -v ./...
=== RUN TestTwoSum
=== RUN TestTwoSum/test_0_-_TwoSum_should_return_expected_output
Outer index: 0, Inner index: 1 
Outer index: 0, Inner index: 2 
Outer index: 0, Inner index: 3 
Outer index: 0, Inner index: 4 
Outer index: 1, Inner index: 2 
Outer index: 1, Inner index: 3 
Outer index: 1, Inner index: 4 
Outer index: 2, Inner index: 3 
Outer index: 2, Inner index: 4 
Outer index: 3, Inner index: 4 

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Excellent, now all we need to do is check to see if the values equal our &lt;code&gt;goal&lt;/code&gt; and, if they do, return the indices. If we never reach our goal (i.e. our loops end), we return an empty slice to signify that a match wasn’t found.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func TwoSum(nums []int, goal int) []int {
    for ix := range nums {
        for i := ix + 1; i &amp;lt; len(nums); i++ {
            if nums[ix]+nums[i] == goal {
                return []int{ix, i}
            }
        }
    }

    return []int{}
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Let’s uncomment and run all of our test cases and make sure they all pass&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;go test -v ./...
=== RUN TestTwoSum
=== RUN TestTwoSum/test_0_-_TwoSum_should_return_expected_output
=== RUN TestTwoSum/test_1_-_TwoSum_should_return_expected_output
=== RUN TestTwoSum/test_2_-_TwoSum_should_return_expected_output
=== RUN TestTwoSum/test_3_-_TwoSum_should_return_expected_output
--- PASS: TestTwoSum (0.00s)
    --- PASS: TestTwoSum/test_0_-_TwoSum_should_return_expected_output (0.00s)
    --- PASS: TestTwoSum/test_1_-_TwoSum_should_return_expected_output (0.00s)
    --- PASS: TestTwoSum/test_2_-_TwoSum_should_return_expected_output (0.00s)

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Four passing test cases! But we’re not done yet! Although this solution works, we need to consider if it’s a “good” solution.&lt;/p&gt;

&lt;p&gt;Because we’re using two loops, we’ve introduced the possibility that our code will need to process every element in our &lt;code&gt;nums&lt;/code&gt; slice &lt;code&gt;n&lt;/code&gt; number of times (where &lt;code&gt;n&lt;/code&gt; is the length of the slice)!&lt;/p&gt;

&lt;p&gt;Imagine if someone passed in a slice with a million elements, and how many loops we’d be running! We can characterise this &lt;a href="https://algodaily.com/lessons/understanding-big-o-and-algorithmic-complexity"&gt;Algorithmic Complexity&lt;/a&gt; as Quadratic or &lt;code&gt;O(n^2)&lt;/code&gt;, which is very well described &lt;a href="https://algodaily.com/lessons/understanding-big-o-and-algorithmic-complexity"&gt;here&lt;/a&gt;.  Luckily, there is a better way!&lt;/p&gt;

&lt;p&gt;First, let’s comment out all of our tests, like we did before, apart from the one below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    nums: []int{0, 1, 12, 20, 9},
    goal: 10,
    expected: []int{1, 4},
},

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Next, we’re going to make a &lt;code&gt;map&lt;/code&gt; of processed elements and will be constructed of the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Our &lt;code&gt;key&lt;/code&gt; will be the result of the &lt;code&gt;goal&lt;/code&gt; minus the current element.&lt;/li&gt;
&lt;li&gt;Out &lt;code&gt;value&lt;/code&gt; will be the index of the current element.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func TwoSum(nums []int, goal int) []int {
    processed := make(map[int]int)

    for index, currentValue := range nums {
        currentSubtraction := goal - currentValue

        processed[currentSubtraction] = index
    }

    fmt.Printf("%+v", processed)

    return []int{}
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Running our tests again will fail, because we’ve not implemented all of our logic yet, but we should see the output of our &lt;code&gt;processed&lt;/code&gt; map.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;=== RUN TestTwoSum/test_0_-_TwoSum_should_return_expected_output
map[-10:3 -2:2 1:4 9:1 10:0]--- FAIL: TestTwoSum (0.00s)

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Here we see the outputs of the goal (&lt;code&gt;10&lt;/code&gt;) minus each element (&lt;code&gt;0&lt;/code&gt;, &lt;code&gt;1&lt;/code&gt;, &lt;code&gt;12&lt;/code&gt;, &lt;code&gt;20&lt;/code&gt; and &lt;code&gt;9&lt;/code&gt;) as the keys and their index positions as the values.&lt;/p&gt;

&lt;p&gt;So how does this actually help us? Well, we know what the subtraction is of the current element, therefore we know what value we need in order to make the goal, we also know the subtractions of the elements that have come before it, so we can work out if we have an index that satisfies the &lt;code&gt;TwoSum&lt;/code&gt; requirement.&lt;/p&gt;

&lt;p&gt;That’s a really confusing statement, so let’s break it down step-by-step. First, let’s define what we mean by these statements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Current subtraction - &lt;code&gt;goal - currentValue&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Required value to satisfy requirement - &lt;code&gt;goal - currentSubtraction&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, let’s go through the slice we’re using in our test case (&lt;code&gt;[0, 1, 12, 20, 9]&lt;/code&gt; step-by-step:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Index &lt;code&gt;0&lt;/code&gt;, Value &lt;code&gt;0&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;Current subtraction ( &lt;code&gt;10 - 0&lt;/code&gt;) = &lt;code&gt;10&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Required value to satisfy requirement (&lt;code&gt;10 - 10&lt;/code&gt;) = &lt;code&gt;0&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Do we have an element in our map with a key of &lt;code&gt;0&lt;/code&gt;? No.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Index &lt;code&gt;1&lt;/code&gt;, Value &lt;code&gt;1&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;Current subtraction (&lt;code&gt;10 - 1&lt;/code&gt;) = &lt;code&gt;9&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Required value to satisfy requirement (&lt;code&gt;10 - 9&lt;/code&gt;) = &lt;code&gt;1&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Do we have an element in our map with a key of &lt;code&gt;1&lt;/code&gt;? No.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Index &lt;code&gt;2&lt;/code&gt;, Value &lt;code&gt;12&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;Current subtraction (&lt;code&gt;10 - 12&lt;/code&gt;) = &lt;code&gt;-2&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Required value to satisfy requirement (&lt;code&gt;10 - -2&lt;/code&gt;) = &lt;code&gt;12&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Do we have an element in our map with a key of &lt;code&gt;12&lt;/code&gt;? No.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Index &lt;code&gt;3&lt;/code&gt;, Value &lt;code&gt;20&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;Current subtraction (&lt;code&gt;10 - 20&lt;/code&gt;) = &lt;code&gt;-10&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Required value to satisfy requirement (&lt;code&gt;10 - -10&lt;/code&gt;) = &lt;code&gt;20&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Do we have an element in our map with a key of &lt;code&gt;20&lt;/code&gt;? No.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Index &lt;code&gt;4&lt;/code&gt;, Value &lt;code&gt;9&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;Current subtraction (&lt;code&gt;10 - 9&lt;/code&gt;) = &lt;code&gt;1&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Required value to satisfy requirement (&lt;code&gt;10 - 1&lt;/code&gt;) = &lt;code&gt;9&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Do we have an element in our map with a key of &lt;code&gt;9&lt;/code&gt;? Yes! So we return &lt;code&gt;[1,4]&lt;/code&gt; which represents the index of the found item (&lt;code&gt;1&lt;/code&gt;) and the current index (&lt;code&gt;4&lt;/code&gt;).
&amp;lt;!--kg-card-end: markdown--&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And we can write this in code, using exactly the same logic, like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func TwoSum(nums []int, goal int) []int {
    processed := make(map[int]int)

    for index, currentValue := range nums {
        currentSubtraction := goal - currentValue
        requiredValue := goal - currentSubtraction

        ix, ok := processed[requiredValue]
        if ok {
            return []int{ix, index}
        }

        processed[currentSubtraction] = index
    }

    return []int{}
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, let’s uncomment all of our test cases and run them one final time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ go test -v ./...
=== RUN TestTwoSum
=== RUN TestTwoSum/test_0_-_TwoSum_should_return_expected_output
=== RUN TestTwoSum/test_1_-_TwoSum_should_return_expected_output
=== RUN TestTwoSum/test_2_-_TwoSum_should_return_expected_output
map[]=== RUN TestTwoSum/test_3_-_TwoSum_should_return_expected_output
=== RUN TestTwoSum/test_4_-_TwoSum_should_return_expected_output
=== RUN TestTwoSum/test_5_-_TwoSum_should_return_expected_output
--- PASS: TestTwoSum (0.00s)
    --- PASS: TestTwoSum/test_0_-_TwoSum_should_return_expected_output (0.00s)
    --- PASS: TestTwoSum/test_1_-_TwoSum_should_return_expected_output (0.00s)
    --- PASS: TestTwoSum/test_2_-_TwoSum_should_return_expected_output (0.00s)
    --- PASS: TestTwoSum/test_3_-_TwoSum_should_return_expected_output (0.00s)
    --- PASS: TestTwoSum/test_4_-_TwoSum_should_return_expected_output (0.00s)
    --- PASS: TestTwoSum/test_5_-_TwoSum_should_return_expected_output (0.00s)
PASS

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And now, we only ever loop through our &lt;code&gt;nums&lt;/code&gt; slice once! We can characterise this &lt;a href="https://algodaily.com/lessons/understanding-big-o-and-algorithmic-complexity"&gt;Algorithmic Complexity&lt;/a&gt; as Linear or &lt;code&gt;O(n)&lt;/code&gt;, which is a much better solution.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://www.codetips.co.uk"&gt;CodeTips&lt;/a&gt; strives to help beginners, with zero or very little experience, learn to code.&lt;/p&gt;

&lt;p&gt;We do cross-post to other sites to reach a wider audience, but why not &lt;a href="https://mailchi.mp/92cccf7024b2/codetips"&gt;subscribe to our newsletter&lt;/a&gt; and get the newest articles straight to your mailbox? &lt;/p&gt;

&lt;p&gt;The original source for this content is &lt;a href="https://www.codetips.co.uk"&gt;CodeTips&lt;/a&gt;. The original content is kept up-to-date, but other sources may not be the latest version. &lt;/p&gt;

</description>
      <category>beginners</category>
      <category>tutorial</category>
      <category>learning</category>
      <category>go</category>
    </item>
    <item>
      <title>Table Driven Tests</title>
      <dc:creator>Si</dc:creator>
      <pubDate>Tue, 03 Dec 2019 15:48:30 +0000</pubDate>
      <link>https://forem.com/codetips/table-driven-tests-416l</link>
      <guid>https://forem.com/codetips/table-driven-tests-416l</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ohxDeIf_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.codetips.co.uk/content/images/2019/12/table-driven-tests.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ohxDeIf_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.codetips.co.uk/content/images/2019/12/table-driven-tests.jpg" alt="Table Driven Tests"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this article, we’re going to discuss the table-driven test strategy in Go, although this could easily be applied to other languages. Before reading, you should have an understanding of what &lt;a href="https://www.codetips.co.uk/beginner/what-is-testing/"&gt;Testing&lt;/a&gt; is.&lt;/p&gt;

&lt;p&gt;Let’s start by creating a function that takes a string, and returns the reverse of it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// ReverseString takes an input string and returns it reversed&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;ReverseString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;runes&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;rune&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;runes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;runes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;runes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;runes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;runes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;runes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As is common practice when we want to ensure a function does what we expect it to do, we'll add some tests.&lt;/p&gt;

&lt;p&gt;If we weren't going to use the table-driven test approach, we might write our tests like the below (using subtests to break each test up into its own section):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;TestReverseString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"abiglongsentence should return ecnetnesgnolgiba"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"abiglongsentence"&lt;/span&gt;
        &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"ecnetnesgnolgiba"&lt;/span&gt;

        &lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ReverseString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Expected %s to return %s, but got %s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"word should return drow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"word"&lt;/span&gt;
        &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"drow"&lt;/span&gt;

        &lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ReverseString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Expected %s to return %s, but got %s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"山上的人 should return 人的上山"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"山上的人"&lt;/span&gt;
        &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"人的上山"&lt;/span&gt;

        &lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ReverseString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Expected %s to return %s, but got %s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The quick brown 狐 jumped over the lazy 犬 should return 犬 yzal eht revo depmuj 狐 nworb kciuq ehT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"The quick brown 狐 jumped over the lazy 犬"&lt;/span&gt;
        &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"犬 yzal eht revo depmuj 狐 nworb kciuq ehT"&lt;/span&gt;

        &lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ReverseString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Expected %s to return %s, but got %s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This doesn’t look great; we’re duplicating a lot of code and it’s not exactly easy to see all of our test cases in one glance. If we extended this test to 100 different permutations, we’d have to scroll down the entire test looking for the different &lt;code&gt;input&lt;/code&gt; strings.&lt;/p&gt;

&lt;p&gt;Luckily, our &lt;code&gt;ReverseString&lt;/code&gt; method is small and simple so our tests are also simple, even if we are duplicating a lot of code.&lt;/p&gt;

&lt;p&gt;Adding additional tests is straightforward, but we’ll be adding at least eleven lines of code for each new test case. Let’s look at how we can utilise the table-driven test approach to reduce the duplication and make it more readable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;TestReverseString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;testCases&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
        &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="p"&gt;}{&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"abiglongsentence"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"ecnetnesgnolgiba"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"word"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"drow"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"山上的人"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"人的上山"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"The quick brown 狐 jumped over the lazy 犬"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"犬 yzal eht revo depmuj 狐 nworb kciuq ehT"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tC&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;testCases&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"'%s' should return '%s'"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tC&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tC&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ReverseString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tC&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;tC&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Expected %s to return %s, but got %s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tC&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tC&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;First, we make a slice of structs, that specify the &lt;code&gt;input&lt;/code&gt; into our &lt;code&gt;ReverseString&lt;/code&gt; function, and the &lt;code&gt;expected&lt;/code&gt; result. Then, we loop over the items in the slice and run the same test logic we had before, except this time we only need to define it once.&lt;/p&gt;

&lt;p&gt;Adding a new test is as simple as creating a new item in our slice, and our &lt;code&gt;for range&lt;/code&gt; loop will handle the rest.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>tutorial</category>
      <category>learning</category>
      <category>go</category>
    </item>
    <item>
      <title>CodeTips is Changing</title>
      <dc:creator>Si</dc:creator>
      <pubDate>Mon, 02 Dec 2019 18:02:04 +0000</pubDate>
      <link>https://forem.com/codetips/codetips-is-changing-4603</link>
      <guid>https://forem.com/codetips/codetips-is-changing-4603</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--g5AcvE4P--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.codetips.co.uk/content/images/2019/12/CodeTips-Is-Changing.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--g5AcvE4P--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.codetips.co.uk/content/images/2019/12/CodeTips-Is-Changing.jpg" alt="CodeTips is Changing"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Today, we're happy to announce three important changes to CodeTips.&lt;/p&gt;




&lt;h2&gt;
  
  
  No More Ads
&lt;/h2&gt;

&lt;p&gt;We've come to the decision to remove all the Ads from CodeTips. Although we received no negative feedback, we feel they were getting in the way and we didn't think there was enough benefits to keeping them.&lt;/p&gt;

&lt;p&gt;Instead, we've launched a &lt;a href="https://www.patreon.com/realcodetips"&gt;Patreon&lt;/a&gt; page. If you'd like to contribute, we'd be very grateful, but there is no pressure whatsoever.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comment Integration
&lt;/h2&gt;

&lt;p&gt;We've added Disqus integration, so you'll be able to interact with the CodeTips writers directly through their articles.&lt;/p&gt;

&lt;h2&gt;
  
  
  No More Journeys
&lt;/h2&gt;

&lt;p&gt;When CodeTips started, we wanted to provide a place for absolute beginners to come and learn the fundamentals of programming.&lt;/p&gt;

&lt;p&gt;Originally, we thought the best way to do this was to create a specific "journey" that each programming language would follow. That meant that learning Go and JavaScript would follow a very similar path, and should help our readers understanding.&lt;/p&gt;

&lt;p&gt;We are now changing that plan. We believe the articles we have already created provide a solid foundation for anybody wanting to pick up the basics, and now we're going to focus on each language individually. Our writers will now be able to create the content they want to create, for the language(s) they want to create it for. This means that our Go articles will move at a completely different pace to our Python articles, and may be on completely different topics, but we believe we'll be able to provide more quality articles this way.&lt;/p&gt;

&lt;p&gt;Basically, we're moving towards a more traditional "blog" approach. This week you might read about Go pointers, next week you might learn the difference between the double equals (&lt;code&gt;==&lt;/code&gt;) and triple equals (&lt;code&gt;===&lt;/code&gt;) operators in JavaScript.&lt;/p&gt;

&lt;p&gt;What does this mean for our readers? Hopefully this means more quality articles, on topics that you want to read about.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://www.codetips.co.uk"&gt;CodeTips&lt;/a&gt; strives to help beginners, with zero or very little experience, learn to code.&lt;/p&gt;

&lt;p&gt;We do cross-post to other sites to reach a wider audience, but why not &lt;a href="https://mailchi.mp/92cccf7024b2/codetips"&gt;subscribe to our newsletter&lt;/a&gt; and get the newest articles straight to your mailbox? &lt;/p&gt;

&lt;p&gt;The original source for this content is &lt;a href="https://www.codetips.co.uk"&gt;CodeTips&lt;/a&gt;. The original content is kept up-to-date, but other sources may not be the latest version. &lt;/p&gt;

</description>
      <category>meta</category>
      <category>beginners</category>
      <category>motivation</category>
    </item>
    <item>
      <title>I don't code outside of work</title>
      <dc:creator>Si</dc:creator>
      <pubDate>Sat, 30 Nov 2019 08:52:24 +0000</pubDate>
      <link>https://forem.com/codetips/i-don-t-code-outside-of-work-1lk3</link>
      <guid>https://forem.com/codetips/i-don-t-code-outside-of-work-1lk3</guid>
      <description>&lt;p&gt;I've been a developer for about 6 years now, and I love my job. I've found a decent company, an awesome working environment, and I actually enjoy being a software engineer.&lt;/p&gt;

&lt;p&gt;Unfortunately, in this industry, there can be an expectation that you'll be doing it in your own time, on your own projects, to keep up with new technologies.&lt;/p&gt;

&lt;p&gt;Well, I'm here to tell you it's not a requirement to being successful.&lt;/p&gt;

&lt;p&gt;Sure I've done my own projects, with varying levels of success, but they were born out of interest not requirement.&lt;/p&gt;

&lt;p&gt;I have a young family, so any time not spent working goes on them. I could have probably learnt {insert newest JavaScript framework here}, but personal life is important.&lt;/p&gt;

&lt;p&gt;Put whatever time you can into it, and don't feel guilty if you can't give more.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://www.codetips.co.uk"&gt;CodeTips&lt;/a&gt; strives to help beginners, with zero or very little experience, learn to code.&lt;/p&gt;

&lt;p&gt;We do cross-post to other sites to reach a wider audience, but why not &lt;a href="https://mailchi.mp/92cccf7024b2/codetips"&gt;subscribe to our newsletter&lt;/a&gt; and get the newest articles straight to your mailbox? &lt;/p&gt;

&lt;p&gt;The original source for this content is &lt;a href="https://www.codetips.co.uk"&gt;CodeTips&lt;/a&gt;. The original content is kept up-to-date, but other sources may not be the latest version. &lt;/p&gt;

</description>
      <category>beginners</category>
      <category>career</category>
      <category>motivation</category>
    </item>
    <item>
      <title>3065 followers</title>
      <dc:creator>Si</dc:creator>
      <pubDate>Sat, 23 Nov 2019 15:20:20 +0000</pubDate>
      <link>https://forem.com/devdrake0/3065-followers-1fip</link>
      <guid>https://forem.com/devdrake0/3065-followers-1fip</guid>
      <description>&lt;p&gt;The last time I properly checked, I was on ~1000 followers, and I've just realised I've now surpassed 3,000.&lt;/p&gt;

&lt;p&gt;Firstly, thanks to everyone that has hit the follow button. &lt;/p&gt;

&lt;p&gt;Secondly, Dev is clearly helping people reach wider audiences; I don't think I got higher than ~50 followers on medium. &lt;/p&gt;

&lt;p&gt;Thirdly, to those that are following me, I know I've not really blogging for a while. I recently had a child and started a new job, so have really struggled with finding the time. But, is there anything specific you'd like to see from me next?&lt;/p&gt;

&lt;p&gt;Fourthly,and lastly, a shameful plug -you can also find me on Twitter at &lt;a href="https://mobile.twitter.com/devdrake0"&gt;devdrake0&lt;/a&gt; and check out &lt;a href="//HTTPS://www.codetips.co.uk"&gt;CodeTips&lt;/a&gt; (&lt;a href="https://mobile.twitter.com/realcodetips"&gt;@realcodetips&lt;/a&gt;)&lt;/p&gt;

</description>
      <category>meta</category>
      <category>writing</category>
    </item>
  </channel>
</rss>
