<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://anydata.uk/feed.xml" rel="self" type="application/atom+xml" /><link href="https://anydata.uk/" rel="alternate" type="text/html" /><updated>2026-03-17T21:49:32+00:00</updated><id>https://anydata.uk/feed.xml</id><title type="html">Fred Youhanaie</title><subtitle>Blog posts and project notes.</subtitle><author><name>fy</name></author><entry><title type="html">Visualizing XOR swap</title><link href="https://anydata.uk/general/2024/07/31/xor-swap.html" rel="alternate" type="text/html" title="Visualizing XOR swap" /><published>2024-07-31T00:00:00+01:00</published><updated>2024-07-31T00:00:00+01:00</updated><id>https://anydata.uk/general/2024/07/31/xor-swap</id><content type="html" xml:base="https://anydata.uk/general/2024/07/31/xor-swap.html"><![CDATA[<h1 id="introduction">Introduction</h1>

<p>In programming, we often need to swap (exchange) the contents of two
variables, say <code class="language-plaintext highlighter-rouge">x</code> and <code class="language-plaintext highlighter-rouge">y</code>. This is normally achieved using a
temporary variable, say <code class="language-plaintext highlighter-rouge">t</code>, as follows:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>t := x
x := y
y := t
</code></pre></div></div>

<p>The <em>XOR swap</em> technique achieves the above for binary values without
using a third variable, here \(\oplus\) is the XOR operation:</p>

<ul>
  <li>(1) \(x := x \oplus y\)</li>
  <li>(2) \(y := x \oplus y\)</li>
  <li>(3) \(x := x \oplus y\)</li>
</ul>

<p>I first came across the algorithm (technique) in the mid 80s, and set
about convincing myself how and why it works. My first attempt was to
use a truth table, shown below. The second was to use simple algebra,
which is described in the <a href="https://en.wikipedia.org/wiki/XOR_swap_algorithm#Proof_of_correctness">Wikipedia
article</a>,
so I won’t cover it here. Many years later I discovered that the
technique can be explained graphically using a triangle.</p>

<p>The Wikipedia page for <a href="https://en.wikipedia.org/wiki/XOR_swap_algorithm">XOR
swap</a> is very
extensive and covers a lot of ground. Here, I will cover a couple of
additional explanations that are not included on the Wikipedia page.</p>

<hr />
<p><br /></p>
<h1 id="using-a-truth-table">Using a truth table</h1>

<p>Interestingly, the Wikipedia page, while extensive, does not include
an explanation using a truth table, so here’s my version:</p>

<table>
  <thead>
    <tr>
      <th style="text-align: center">\(x\)</th>
      <th style="text-align: center">\(y\)</th>
      <th style="text-align: center">(1) \(x\)</th>
      <th style="text-align: center">(2) \(y\)</th>
      <th style="text-align: center">(3) \(x\)</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: center">0</td>
      <td style="text-align: center">0</td>
      <td style="text-align: center">0</td>
      <td style="text-align: center">0</td>
      <td style="text-align: center">0</td>
    </tr>
    <tr>
      <td style="text-align: center">0</td>
      <td style="text-align: center">1</td>
      <td style="text-align: center">1</td>
      <td style="text-align: center">0</td>
      <td style="text-align: center">1</td>
    </tr>
    <tr>
      <td style="text-align: center">1</td>
      <td style="text-align: center">0</td>
      <td style="text-align: center">1</td>
      <td style="text-align: center">1</td>
      <td style="text-align: center">0</td>
    </tr>
    <tr>
      <td style="text-align: center">1</td>
      <td style="text-align: center">1</td>
      <td style="text-align: center">0</td>
      <td style="text-align: center">1</td>
      <td style="text-align: center">1</td>
    </tr>
  </tbody>
</table>

<p>In the above, the columns \(x\) and \(y\) represent the initial values
of the two variables, and columns (1), (2) and (3) represent the
values of the left hand sides of the three assignments after each of
the respective operations. So, column (2) shows the final value of
\(y\), which matches the original column for \(x\), and, column (3)
shows the final value of \(x\), which matches the original column for
\(y\).</p>

<p>The truth table above applies to single bit values, however, since the
application of the XOR operation to larger integers is performed
bit-wise, the XOR-swap is valid for integers of any size. Basically,
the same truth table applies to each pair of bits independently.</p>

<hr />
<p><br /></p>
<h1 id="the-triangle">The triangle</h1>

<p>The XOR operation can be visualized as a triangle with the two
operands at two of the vertices and their exclusive-or at the third.
That is, if \(A\) and \(B\) are two arbitrary binary values at two of
the vertices, then \((A \oplus B)\) will be at the third vertex.</p>

<p>The most interesting, and useful, property of XOR is that from the
values at any two vertices we can derive the third by applying the XOR
operation to the two values at those vertices. So,</p>

<p>\(A = B \oplus (A \oplus B)\), and</p>

<p>\(B = A \oplus (A \oplus B)\).</p>

<p><img alt="XOR triangle" src="https://anydata.uk/assets/xor-triangle.svg" width="300" /></p>

<p>Now, let’s say \(x\) and \(y\) have the values \(A\) and \(B\),
respectively, then the three assignments will move the two variables
around the triangle one vertex at a time, which will result in \(x\)
and \(y\) containing the new values \(B\) and \(A\), respectively.</p>

<p><img alt="XOR swap" src="https://anydata.uk/assets/xor-swap.svg" width="1200" /></p>

<hr />]]></content><author><name>Fred Youhanaie</name></author><category term="general" /><summary type="html"><![CDATA[Visualizing XOR swap]]></summary></entry><entry><title type="html">Spawnfest 2023</title><link href="https://anydata.uk/general/2024/04/07/spawnfest-2023.html" rel="alternate" type="text/html" title="Spawnfest 2023" /><published>2024-04-07T00:00:00+01:00</published><updated>2024-04-07T00:00:00+01:00</updated><id>https://anydata.uk/general/2024/04/07/spawnfest-2023</id><content type="html" xml:base="https://anydata.uk/general/2024/04/07/spawnfest-2023.html"><![CDATA[<h1 id="introduction">Introduction</h1>

<p><a href="https://spawnfest.org/">Spawnfest</a> is a programming contest for the
Erlang and associated languages. From the
<a href="https://spawnfest.org/#about">description</a>:</p>

<blockquote>
  <p>SpawnFest is an annual 48 hour online software development contest
in which teams from around the world get exactly one weekend to
create the best BEAM-based applications they can.</p>
</blockquote>

<p>My first participation in the contest was in 2017 (December 9-10). At
the time, I used the weekend to kick start the <code class="language-plaintext highlighter-rouge">espace</code> project. This
was an application that I had been intending to develop for a very
long time. Following the contest, I continued developing and improving
the application. The project is currently hosted on my <a href="https://github.com/fredyouhanaie/espace">GitHub
account</a>.</p>

<p>For the following year, 2018 (Nov. 24-25), I attempted the same plan
for another project idea on my list, <code class="language-plaintext highlighter-rouge">wfnet</code>. But unfortunately, I was
unable to spend any time on the project during the Saturday. With only
the Sunday available to me, I didn’t have enough time to produce
anything presentable, so I aborted my attempt.</p>

<p>Fast forward to 2023, I decided to have another attempt at the <code class="language-plaintext highlighter-rouge">wfnet</code>
project. During the past five years I’ve had fresh ideas about how to
go about implementing it. So, I was effectively starting the
implementation from scratch.</p>

<p>At some point I will write a separate technical article about
<code class="language-plaintext highlighter-rouge">wfnet</code>. In the meantime here is a short summary of the project:</p>

<blockquote>
  <p><code class="language-plaintext highlighter-rouge">wfnet</code> provides a configuration based workflow enactment engine
within an Erlang application.</p>
</blockquote>

<blockquote>
  <p>Here, a workflow is an arrangement of tasks (activities) where each
task is only activated when, depending on the task type, one or all
of its predecessor(s) have [successfully] terminated.</p>
</blockquote>

<blockquote>
  <p>The concept, and implementation, of workflows here follows those
described on the <a href="http://workflowpatterns.com/">Workflow patterns</a>
web site, more specifically the <a href="http://workflowpatterns.com/patterns/control/">Basic Control Flow
Patterns</a>.</p>
</blockquote>

<p>Below is an account of the weekend activities. But, since I left the
writing of the article too late, and I didn’t keep a detailed, in fact
any, diary of activities during the weekend, some of the recollections
that follow are going to be vague and blurry <code class="language-plaintext highlighter-rouge">:-(</code></p>

<hr />
<p><br /></p>
<h1 id="preparation">Preparation</h1>

<p>Before the start of the contest, [I thought] I had a fair idea of the
overall architecture of the application, and I would have preferred to
have experimented with one or two alternative designs. However, in
order to comply with the rules of the contest, no code should be
produced, and none was!</p>

<p>This created a challenging situation where I would have wanted to
experiment with some implementation patterns, but I couldn’t do so
without breaking the rules. So, as it had been the case with the
previous years, I found myself experimenting with some design choices
during the early part of the weekend.</p>

<p>With hindsight, I could have started with some experimental code
before the contest. However, anything carried over to the submitted
project would need to be clearly marked as pre-contest code, which can
be achieved by attaching a tag to the last pre-contest git commit.</p>

<hr />
<p><br /></p>
<h1 id="the-start">The start</h1>

<p>For me, the contest started at 1am on Saturday, 00:00 UTC. Not being
as energetic as my younger self, I decided not to start the weekend
with an all-nighter.</p>

<p>I carried out some basic house keeping tasks, before retiring to bed
at 2am-ish:</p>

<ul>
  <li>The empty repo on GitHub had already been created by the organisers.</li>
  <li>Created the local repo and the corresponding remote branch.</li>
  <li>Generated the basic set of skeleton files, <code class="language-plaintext highlighter-rouge">rebar3 new ...</code></li>
  <li>Added some basic text to the <code class="language-plaintext highlighter-rouge">README</code> file.</li>
  <li>Updated the local repo and pushed it to GitHub.</li>
</ul>

<hr />
<p><br /></p>
<h1 id="saturday-october-28">Saturday October 28</h1>

<p>I started at about 8:30 in the morning and worked through the day,
stopping for the usual things such as cooking, eating and going for a
walk, as well as making [almost endless] cups of coffee and tea <code class="language-plaintext highlighter-rouge">;-)</code></p>

<p>The initial coding activity included a couple of throwaway modules.</p>

<p>The original intention was to create the simplest workflow engine
possible, with minimal feature set and without any of the usual OTP
behaviours, basically a lightweight server. I would then move on to an
additional more elaborate engine, i.e. <code class="language-plaintext highlighter-rouge">gen_server</code>+<code class="language-plaintext highlighter-rouge">supervisor</code>,
based on the <a href="https://www.erlang.org/doc/design_principles/users_guide">OTP Design
Principles</a>. Both
designs have their own merits and use cases.</p>

<p>The justification for the simple engine is to cater for very
short-lived workflows where the start up and shutdown of the
supervisor/server processes would be relatively long compared to the
entire workflow run. This is similar to the situations where, for
example, we may maintain temporary key/value data in maps instead of
an ETS table, or in an ETS table instead of opting for a full blown
database server.</p>

<p>During the day I wasn’t happy with the way the simple engine was
progressing, so I switched to experimenting with the <code class="language-plaintext highlighter-rouge">gen_server</code>
based solution. Sometimes creating a simple and effective solution
takes more effort than a more complex one, especially when the complex
solution already has a stable foundation in place that is ready to be
taken advantage of.</p>

<p>In the evening I went for a long walk, had dinner, then continued with
more coding!</p>

<p>This was the last weekend of October, so, as is usual for UK and
Europe, the clocks went back by one hour. I went to bed sometime
before 2am, but I’m not sure if it was on the old time or the new one
<code class="language-plaintext highlighter-rouge">:-()</code></p>

<p>By the way, for anyone who considers 2am as late, they should have
seen me in 2017, when I was sitting in bed with my laptop, well past
3am, and trying to get my head around the <code class="language-plaintext highlighter-rouge">ETS</code> matchspec expressions
<code class="language-plaintext highlighter-rouge">:-(</code></p>

<hr />
<p><br /></p>
<h1 id="sunday-october-29">Sunday October 29</h1>

<p>After a good night’s rest I was ready for some more coding in the
morning.</p>

<p>Originally, I was going to submit both engine types and throughout the
morning I continued going back and forth between the simple engine and
the <code class="language-plaintext highlighter-rouge">gen_server</code> one.</p>

<p>It soon became clear that there was only enough time for one type, so
I eventually settled for the <code class="language-plaintext highlighter-rouge">gen_server</code>. Simply because it already
comes with the API for the workflow clients and the facilities for
maintaining the application state.</p>

<p>Committing to the <code class="language-plaintext highlighter-rouge">gen_server</code> variant enabled me to focus better. It
was then a matter of scribbling on the whiteboard and transcribing the
pseudo code from the whiteboard into the emacs editor. Eventually, I
got a working application – for some definition of working <code class="language-plaintext highlighter-rouge">;-)</code></p>

<p>During the last hour of the contest I switched my efforts to updating
the documentation and the <code class="language-plaintext highlighter-rouge">README</code> file. Judging by the traffic on
the Slack channel, the other contestants were also busy updating their
project documentation!</p>

<p>The last commit was at 23:41 UTC. This was followed by a nice cool
beer from the fridge, feet up, and watched the highlights of the F1
Mexico GP <code class="language-plaintext highlighter-rouge">:-)</code></p>

<hr />
<p><br /></p>
<h1 id="post-spawnfest">Post-Spawnfest</h1>

<p>The <code class="language-plaintext highlighter-rouge">wfnet</code> project now has a new
<a href="https://github.com/fredyouhanaie/wfnet">home</a> in my personal
repository.</p>

<p>For me, the Spawnfest weekend is an opportunity to kick start an idea
that may have been sitting on a todo list for a while. The pressure of
the deadline is a good incentive for putting all the <em>nonessential
distractions</em> on hold for the duration of the weekend. It has helped
me produce a <em>good enough</em> baseline application for further
incremental development later, as and when time permits.</p>

<p>For anyone who has a project idea in need of a kick start, the
Spawnfest weekend is a good opportunity to help them along. Of course,
assuming the project is based on Erlang or one of the BEAM related
languages.</p>

<p>The <a href="https://spawnfest.org/2023.html">results of the contest</a> are
out. I was hoping to publish this article before the announcement,
then follow it up with an update. My submission has been awarded the
second place in the <em>correctness category</em>. This is a very pleasant
surprise <code class="language-plaintext highlighter-rouge">:-)</code> I have also received very helpful comments from the
judges, as has been the case on my previous attempts. When I get a
chance I’ll post a short wrap up article.</p>

<hr />
<p><br /></p>
<h1 id="acknowledgements">Acknowledgements</h1>

<p>It is very important to acknowledge the efforts of the
<a href="https://spawnfest.org/#organizers">organisers</a>, <a href="https://github.com/paulo-ferraz-oliveira">Paulo
F. Oliveira</a> and <a href="https://github.com/starbelly">Bryan
Paxton</a>, and <a href="https://spawnfest.org/#judges">the
judges</a> who have volunteered their time
with no rewards, financial or otherwise, in return. They have done
this on top of their normal daily work and family activity.</p>

<p>Just as importantly, <a href="https://spawnfest.org/#sponsors">the sponsors</a>
have always played a big role in supporting the contest.  The first
edition of the contest was in 2011 and, with the exception of
2013-2016, it has run every year since then. Throughout, there has
always been support from the community in the form of sponsorship. You
can see the list of the sponsors for each edition by following the
relevant links for the corresponding years on the
<a href="https://spawnfest.org/#about">“about”</a> page of the Spawnfest web
site.</p>

<hr />]]></content><author><name>Fred Youhanaie</name></author><category term="general" /><summary type="html"><![CDATA[Spawnfest 2023]]></summary></entry><entry><title type="html">The GCHQ Christmas challenge</title><link href="https://anydata.uk/general/2024/01/04/gchq-challenge-2023.html" rel="alternate" type="text/html" title="The GCHQ Christmas challenge" /><published>2024-01-04T00:00:00+00:00</published><updated>2024-01-04T00:00:00+00:00</updated><id>https://anydata.uk/general/2024/01/04/gchq-challenge-2023</id><content type="html" xml:base="https://anydata.uk/general/2024/01/04/gchq-challenge-2023.html"><![CDATA[<h1 id="introduction">Introduction</h1>

<p>A few weeks ago I came across an
<a href="https://www.bbc.co.uk/news/uk-67707647">article</a> on the BBC news web
site. It describes the Christmas challenge set by the UK Government
Communications Headquarters (GCHQ) during the run up to
Christmas 2023. The challenge was for school children aged 11-18
years.</p>

<p>The complete details can be found on the GCHQ’s <a href="https://www.gchq.gov.uk/news/schoolsxmaschallenge2023">challenge
page</a>.</p>

<p>The fourth puzzle (of seven) caught my eye, since it involves numbers.
So I thought I’ll have a go, even though I don’t fit the age range
<code class="language-plaintext highlighter-rouge">;-)</code></p>

<hr />
<p><br /></p>
<h1 id="the-challenge">The challenge</h1>

<p>Here is the fourth puzzle:</p>

\[MI \times MI = MAA\]

\[TI + TI = RA\]

\[DO - SO + TI - MI = RE\]

\[RE \times RE = \, ??\]

<p>Where, <em>Each letter represents a different digit</em>. We are asked to
find a <em>one-word answer which can follow Christmas</em>.</p>

<hr />
<p><br /></p>
<h1 id="an-example-solution">An example solution</h1>

<p>What follows is the tidied up version of my scribbles on the
whiteboard. Of course, there are other ways of solving the puzzle.</p>

<p>From the second equation we can see that \(2 \times TI = RA\), so
\(RA\) is an even number, and hence \(A \in \{ 0,2,4,6,8 \}\)</p>

<p>The third equation can be rewritten as follows:</p>

\[(10D + O) - (10S + O) + (10T + I) - (10M + I) = RE\]

<p>rearranging the above, with each of the pairs of \(O\)s and \(I\)s
cancelling themselves, we end up with the following equation:</p>

\[10(D - S + T - M) = RE\]

<p>so, \(E=0\), and hence \(A\) is reduced to the set \(\{2,4,6,8\}\).</p>

<p>Now, back to the first equation, the one that I could have started
with!</p>

\[(MI)^2 = MAA\]

<p>So, \(MAA\) is a 3-digit square number with repeated digits on the
right. This restricts the \(MI\) to the range \([10 .. 31]\), so we
have four possibilities: 100, 144, 400 and 900.</p>

<p>We can exclude \(100\), \(400\) and \(900\), since they would imply
that \(A=0\), but \(0\) already belongs to \(E\).</p>

<p>This leaves us with \(MI=12\) and \(MAA=144\).</p>

<p>We now have \(E=0\), \(M=1\), \(I=2\) and \(A=4\).</p>

<p>The second equation can now be written as \(T2+T2=R4\), so \(2T=R\),
making \(R\) an even number, and hence \(R\in\{6,8\}\). This leads to
\(T\in\{3,4\}\), but \(4\) belongs to \(A\), and so \(T=3\), and
\(R=6\).</p>

<p>Now, \(RE=60\), which leads to the answer as follows:</p>

\[RE \times RE = 60 \times 60 = 3600 = TREE\]

<p>So, <strong>TREE</strong> is the <em>one-word answer which can follow Christmas</em>.</p>

<hr />
<p><br /></p>
<h1 id="carrying-on-">Carrying on …</h1>

<p>The puzzle is solved, but I’m on a roll, so let’s solve for the rest
of the letters.</p>

<p>So far we have \(E=0\), \(M=1\), \(I=2\), \(T=3\), \(A=4\) and
\(R=6\).</p>

<p>From the simplified version of the third equation:</p>

\[10(D - S + T - M) = RE\]

\[D - S + 3 - 1 = 6\]

\[D - S = 4\]

<p>From the list of unassigned digits, \(D,S \in \{ 5, 7, 8, 9 \}\), and
the only pair of digits satisfying the above equation are \(5\) and
\(9\), i.e.</p>

\[D=9, S=5\]

<p>But, what about \(O\)? Well, we can start with
\(O\in\{7,8\}\). However, since \(O\) is only mentioned in the third
equation, in a self-cancelling manner, and with only 9 letters
incorporated in the puzzle, we cannot narrow it down any further!</p>

<p>Have a successful and enjoyable 2024 :-)</p>

<hr />]]></content><author><name>Fred Youhanaie</name></author><category term="general" /><summary type="html"><![CDATA[The GCHQ Christmas challenge]]></summary></entry><entry><title type="html">GitHub 2FA using a CLI</title><link href="https://anydata.uk/general/2023/09/19/github-2fa.html" rel="alternate" type="text/html" title="GitHub 2FA using a CLI" /><published>2023-09-19T00:00:00+01:00</published><updated>2023-09-19T00:00:00+01:00</updated><id>https://anydata.uk/general/2023/09/19/github-2fa</id><content type="html" xml:base="https://anydata.uk/general/2023/09/19/github-2fa.html"><![CDATA[<h1 id="the-problem">The problem</h1>

<p>For some time now GitHub have started requiring account owners to use
two factor authentication (2FA) when signing in to the GitHub web site
using a browser.</p>

<p>A few weeks ago I received notification from GitHub that I should
enable two factor authintication (2FA) for my account. This meant
that, in addition to the usual username/password, I will also need a
second method of authentication.</p>

<p>The GitHub help page on <a href="https://docs.github.com/en/authentication/securing-your-account-with-two-factor-authentication-2fa/configuring-two-factor-authentication">Configuring two-factor
authentication</a>
provides various options for configuring the second source of the 2FA
authentication. These include installing an app on my phone, use the
SMS on my mobile phone, or use a third party authenticator.</p>

<p>I was not keen on installing yet another mobile app on my phone, or
rely on the SMS service. While the SMS option works fine most of the
time, it does not work if there are roaming issues when away from
home! GitHub does not offer the option of email as the second
authentication method, which is often offered by others as an
alternative for, or in addition to, SMS based authentication.</p>

<p>After searching around, I came across a number of web-based and/or GUI
alternatives, such as <a href="https://authy.com/">Authy</a> and
<a href="https://keepassxc.org/">KeePassXC</a>.</p>

<p>However, since my first preference in such situations is always a CLI
based solution, I searched further and eventually came across the
<a href="https://www.nongnu.org/oath-toolkit/">OATH Toolkit</a>, which provides
exactly what GitHub requires - Time-based One Time Password (TOTP).</p>

<hr />
<p><br /></p>
<h1 id="the-cli-based-solution">The CLI based solution</h1>

<p>The OATH Toolkit can be obtained from the
<a href="https://www.nongnu.org/oath-toolkit/download.html">Download</a> page. It
is also available as a package on various Linux distros. Once
installed, you will have the main command available to you –
<code class="language-plaintext highlighter-rouge">oathtool</code>.</p>

<p>When enabling the 2FA, the GitHub page will display a QR code that you
are expected to scan using your mobile app. As an alternative to the
QR code, there is also a <code class="language-plaintext highlighter-rouge">setup key</code> link near the QR code that will
show a 16 character code. This is a base-32 representation of the
secret information needed for the generation of the TOTP specific to
your GitHub account. Copy the code and keep it in a very safe place!</p>

<p>When asked by GitHub, use the following command to generate the TOTP:</p>

<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>oathtool <span class="nt">-b</span> <span class="nt">--totp</span> KEY
123456
</code></pre></div></div>

<p>This will print a 6 digit number, e.g. <code class="language-plaintext highlighter-rouge">123456</code>, that should be typed
in the entry box.</p>

<p><strong>BEWARE</strong>: If you are running the above command on a shared host, the
<code class="language-plaintext highlighter-rouge">KEY</code> will be momentarily visible to others. To be safe, you can ask
<code class="language-plaintext highlighter-rouge">oathtool</code> to read the <code class="language-plaintext highlighter-rouge">KEY</code> from the standard input:</p>

<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>oathtool <span class="nt">-b</span> <span class="nt">--totp</span> -
KEY
ctrl-D
123456
</code></pre></div></div>

<p>You will also be asked to download and save the recovery codes, copy
these codes and keep them in a safe and secure place! Once you confirm
that you have saved the recovery codes, your account will have 2FA
enabled.</p>

<p>From now on in addition to the username/password you will also be
asked for the 2FA key, which you can generate using the <code class="language-plaintext highlighter-rouge">oathtool</code>
command above.</p>

<hr />
<p><br /></p>
<h1 id="using-password-store">Using password-store</h1>

<p>For those using the <a href="https://www.passwordstore.org/">pass</a> command to
manage their passwords, there is a companion extension command
(<a href="https://github.com/tadfisher/pass-otp">pass-otp</a>) that will enable
you to keep the GitHub secret key (the 16 character key) in the
password store along with your other passwords.</p>

<p>To start using <code class="language-plaintext highlighter-rouge">pass-otp</code>, add your GitHub <code class="language-plaintext highlighter-rouge">secret key</code> to the
password store:</p>

<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pass otp insert <span class="nt">-s</span> <span class="nt">--issuer</span> GitHub
Enter secret <span class="k">for </span>this token:
...
</code></pre></div></div>

<p>This will create a password-store entry and print the PASSWORD-NAME.</p>

<p>To obtain the TOTP during sign-in, use:</p>

<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pass otp PASSWORD-NAME
123456
</code></pre></div></div>

<p>and type, or copy-paste, the 6 digit number in the entry box on the
GitHub web page.</p>

<p>Or, to have it copied to the clipboard for you, use:</p>

<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pass otp <span class="nt">-c</span> PASSWORD-NAME
Copied OTP code <span class="k">for </span>PASSWORD-NAME to clipboard. Will clear <span class="k">in </span>45 seconds.
</code></pre></div></div>

<p>Now, it’s just a matter of pasting the code in the browser entry box.</p>

<hr />
<p><br /></p>
<h1 id="to-read-further">To read further</h1>

<p>In addition to the descriptions on the GitHub help page on
<a href="https://docs.github.com/en/authentication/securing-your-account-with-two-factor-authentication-2fa/configuring-two-factor-authentication">Configuring two-factor
authentication</a>,
you can learn further about the OATH and TOTP from the section under
<em>External Resources and Applications</em> on the <a href="https://www.nongnu.org/oath-toolkit/">OATH
Toolkit</a> web site. It lists the
relevant RFCs describing OATH and TOTP.</p>

<hr />
<p><br /></p>
<h1 id="epilogue">Epilogue</h1>

<p>I have described above the minimal steps needed to enable 2FA for my
own use. This should probably be sufficient for most use cases.</p>

<p>This solution works for me because I access my GitHub account via the
browser on my laptop/PC, and never on a phone or tablet. It has worked
fine so far :-)</p>

<hr />]]></content><author><name>Fred Youhanaie</name></author><category term="general" /><summary type="html"><![CDATA[GitHub 2FA using a CLI]]></summary></entry><entry><title type="html">Setting up github pages for Erlang module docs</title><link href="https://anydata.uk/general/2022/10/25/gh-erlang-edoc-1.html" rel="alternate" type="text/html" title="Setting up github pages for Erlang module docs" /><published>2022-10-25T00:00:00+01:00</published><updated>2022-10-25T00:00:00+01:00</updated><id>https://anydata.uk/general/2022/10/25/gh-erlang-edoc-1</id><content type="html" xml:base="https://anydata.uk/general/2022/10/25/gh-erlang-edoc-1.html"><![CDATA[<p>While I was working on this web site with github pages and jekyll, I thought I
should revisit another “problem” I had been meaning to address. Which is the
online availability of the erlang module documentation for my own projects.</p>

<h2 id="about-the-erlang-documentation-system">About the Erlang documentation system</h2>

<p>The <a href="https://erlang.org">Erlang</a> library has a set of modules,
<a href="https://www.erlang.org/doc/apps/edoc/chapter.html">edoc</a>, for extracting the
documentation from the module source files and converting them to a set of html
files. It was inspired by Javadoc.</p>

<p>For applications that use <code class="language-plaintext highlighter-rouge">rebar3</code> the documentation can be generated easily
using the <code class="language-plaintext highlighter-rouge">rebar3 edoc</code> command, which produces the entire set of html pages and
stores them in the <code class="language-plaintext highlighter-rouge">doc/</code> directory. This is pretty common in most erlang
projects. All that one needs to do is to point the web browser to the index
page, <code class="language-plaintext highlighter-rouge">doc/index.html</code>. While this is simple for those working on the project,
it is very tedious for anyone who may want to inspect the documentation without
having to download the source code.</p>

<p>Some projects use <a href="https://hex.pm/">https://hex.pm/</a> for packaging and publishing their
applications. Hex, in addition to hosting the source code, also caters for
publishing the documentation, and provides links for browsing the documentation.
These can be found at <a href="https://hexdocs.pm/">https://hexdocs.pm/</a>.</p>

<p>This is fine for the versions of the packages that have been published on hex,
but not for the latest versions under development, say, on github.</p>

<p>What I wanted to have was the automatic generation of the docs for the latest
version of the application, so that anyone curious about the project can inspect
the latest docs online.</p>

<p>And this is where github pages comes in.</p>

<p>With a bit of configuration, which involved some initial trial and error
activity, I was able to have the module docs auto-generated with every push to
the github repo.</p>

<h2 id="the-per-repo-github-pages">The per-repo github pages</h2>

<p>Each project repository hosted on github can have its own set of web pages –
<code class="language-plaintext highlighter-rouge">github pages</code>.</p>

<p>This can be configured using the settings pages. The instructions can be found
here:
<a href="https://docs.github.com/en/pages/getting-started-with-github-pages/creating-a-github-pages-site#creating-your-site">Creating your site</a>.</p>

<p>The above link, as well as <a href="https://pages.github.com/">https://pages.github.com/</a>, should be sufficient for
anyone wishing to have manually maintained web pages. However, for the module
docs we need to (re)generate the online pages automatically as and when the
source code is modified. For this I needed some additional configuration.</p>

<h2 id="the-additional-workflow-tasks">The additional workflow tasks</h2>

<p>My additional configuration can be summed up as follows:</p>

<ol>
  <li>Logged in to github and followed the link to the repository.</li>
  <li>From the <strong>Settings</strong> page followed the <strong>Pages</strong> link on the left of the page.</li>
  <li>Under <strong>Build and deployment</strong> and <strong>Source</strong> selected <strong>Github Actions</strong>.</li>
  <li>Selected the <strong>Configure</strong> button, this showed an editor with a basic
workflow file loaded. This acted as a template, which saved me from having to
create one from scratch.</li>
  <li>The above YAML file, <code class="language-plaintext highlighter-rouge">.github/workflow/pages.yml</code>, was saved and then used as
the starting point for my own configuration.</li>
</ol>

<p>The main changes from the default file supplied by github are as follows:</p>

<ul>
  <li>
    <p>The source directory for the main github pages is <code class="language-plaintext highlighter-rouge">./gh_pages</code>. This is used
as container for any front matter for the module docs. Currently it contains
the file <code class="language-plaintext highlighter-rouge">index.md</code>, which in turn contains links to the module docs.</p>
  </li>
  <li>
    <p>The jekyl pages are generated in a container that is run as user <code class="language-plaintext highlighter-rouge">root</code>, while
everything else is executed as user <code class="language-plaintext highlighter-rouge">runner</code>. I added a task to change the
owner of the jekyll generated files in the <code class="language-plaintext highlighter-rouge">_site</code> directory to user <code class="language-plaintext highlighter-rouge">runner</code>,
so that we can drop our own files in the <code class="language-plaintext highlighter-rouge">_site</code> directory:</p>
  </li>
</ul>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>- name: take ownership of the site files
  run: sudo chown -R runner _site
</code></pre></div></div>

<ul>
  <li>Two tasks contain the commands to generate the module docs and copy them to
the <code class="language-plaintext highlighter-rouge">_site</code> directory. I generate two sets of docs, one for the exported
(public) functions:</li>
</ul>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>- name: generate the public edoc
  run: rebar3 edoc
- name: copy the doc files
  run: cp -r ./doc ./_site/edoc
</code></pre></div></div>

<p>and, the other covering ALL the functions, public and private:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>- name: generate the full edoc
  run: rebar3 as dev edoc
- name: copy the doc files
  run: cp -r ./doc ./_site/edoc_dev
</code></pre></div></div>

<p>Once the modified workflow file was pushed to github the web pages were
generated automatically. And, from there on each <code class="language-plaintext highlighter-rouge">git push</code> kicked off a new
edoc run.</p>

<p>For an example see the <a href="https://github.com/fredyouhanaie/espace"><code class="language-plaintext highlighter-rouge">espace
project</code></a>. The main files of interest
are
<a href="https://github.com/fredyouhanaie/espace/blob/master/gh_pages/index.md"><code class="language-plaintext highlighter-rouge">gh_pages/index.md</code></a>
and
<a href="https://github.com/fredyouhanaie/espace/blob/master/.github/workflows/pages.yml"><code class="language-plaintext highlighter-rouge">.github/workflows/pages.yml</code></a>.
The auto-generated web pages can be seen
<a href="https://fredyouhanaie.github.io/espace">here</a>.</p>

<p>One last addition to the workflow file was to stop <code class="language-plaintext highlighter-rouge">yamllint</code> complaining about
the <code class="language-plaintext highlighter-rouge">on:</code> keyword not being a <code class="language-plaintext highlighter-rouge">truthy</code> value. This was fixed by replacing the
<code class="language-plaintext highlighter-rouge">on:</code> line with</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>on: # yamllint disable-line rule:truthy
</code></pre></div></div>

<hr />]]></content><author><name>Fred Youhanaie</name></author><category term="general" /><summary type="html"><![CDATA[Setting up github pages for Erlang module docs]]></summary></entry><entry><title type="html">Setting up github pages with jekyll</title><link href="https://anydata.uk/general/2022/09/23/gh-jekyll-1.html" rel="alternate" type="text/html" title="Setting up github pages with jekyll" /><published>2022-09-23T00:00:00+01:00</published><updated>2022-09-23T00:00:00+01:00</updated><id>https://anydata.uk/general/2022/09/23/gh-jekyll-1</id><content type="html" xml:base="https://anydata.uk/general/2022/09/23/gh-jekyll-1.html"><![CDATA[<p>This is an account of my experience setting up this web site using <code class="language-plaintext highlighter-rouge">github
pages</code> and <code class="language-plaintext highlighter-rouge">jekyll</code>.</p>

<p>It is not a tutorial on the subject, but rather a list of what I did, and why.</p>

<p>At first the intention was to have a set of simple pages summarising some of my
projects. The usual github based address <a href="https://fredyouhanaie.github.io">https://fredyouhanaie.github.io</a> was
sufficient. However, once I took a closer look at the features provided by
github pages and jekyll, it was clear that this combination would also be
suitable for publishing blog posts.</p>

<p>The
<a href="https://docs.github.com/en/pages/setting-up-a-github-pages-site-with-jekyll/about-github-pages-and-jekyll">github documentation</a>
provides instructions on various scenarios for creating a web site, depending on
one’s needs. This article shows <em>one particular path</em> that covers the following
personal requirements:</p>

<ul>
  <li>
    <p>It should cater for use of plain text for all content, so that they can be
version controlled.</p>
  </li>
  <li>
    <p>It should allow use of own domain name with <code class="language-plaintext highlighter-rouge">https</code> access.</p>
  </li>
  <li>
    <p>It should be possible to preview the rendered pages locally before deployment
to github.</p>
  </li>
</ul>

<h3 id="about-github-pages-and-jekyll">About github pages and jekyll</h3>

<ul>
  <li>
    <p>The contents of the web site (github pages) are kept in a git repository that
is hosted on github.</p>
  </li>
  <li>
    <p>Github uses jekyll to generate the static web pages.</p>
  </li>
  <li>
    <p>The static web pages are generated from text files (YAML+markdown) that follow
a specific format, see <a href="https://jekyllrb.com/docs/front-matter/">https://jekyllrb.com/docs/front-matter/</a>.</p>
  </li>
  <li>
    <p>The html files are generated automatically, through <code class="language-plaintext highlighter-rouge">github actions</code>, whenever
new changes are pushed to the repository.</p>
  </li>
</ul>

<h3 id="creation-and-the-initial-setup-of-the-github-pages">Creation and the initial setup of the github pages</h3>

<p>This was the first step. It was pretty straightforward. I just followed the
instructions <a href="https://docs.github.com/en/pages/quickstart">here</a>.</p>

<p>After the set up and creation of a simple <code class="language-plaintext highlighter-rouge">index.html</code> file, the web
site was up and running.</p>

<h3 id="installing-jekyll-on-a-local-host-laptop">Installing jekyll on a local host (laptop)</h3>

<p><code class="language-plaintext highlighter-rouge">jekyll</code>, a ruby based application (a <code class="language-plaintext highlighter-rouge">gem</code>), is needed so that we can update
and preview the web pages locally. The github docs for installing and
configuring jekyll can be found
<a href="https://docs.github.com/en/pages/setting-up-a-github-pages-site-with-jekyll/about-github-pages-and-jekyll">here</a></p>

<p>I already had ruby installed, so it was just a matter of installing jekyll:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gem install jekyll
</code></pre></div></div>

<p>I ran the above command as a non-root user (there is no need for root here),
this resulted in the files being installed in:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$HOME/.local/share/gem/ruby/3.0.0/gems/jekyll-4.2.2
</code></pre></div></div>

<p>Rather than adding yet another directory to my <code class="language-plaintext highlighter-rouge">$PATH</code> for the <code class="language-plaintext highlighter-rouge">jekyll</code> command,
I used a symlink as follows:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cd $HOME/.local/bin
ln -sv ../share/gem/ruby/3.0.0/bin/jekyll jekyll
</code></pre></div></div>

<h3 id="creation-of-the-basic-web-pages">Creation of the basic web pages</h3>

<p>Once jekyll was installed, the site scaffold was created within the local repo
of the github pages:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>jekyll new --skip-bundle .
</code></pre></div></div>

<p>Next, the <code class="language-plaintext highlighter-rouge">Gemfile</code> needed customization, as per the github docs, which
consisted of the following two changes:</p>

<ul>
  <li>comment out the <code class="language-plaintext highlighter-rouge">gem "jekyll" ...</code> line</li>
  <li>uncomment the <code class="language-plaintext highlighter-rouge">gem "github-pages"</code> line, and add the version</li>
</ul>

<p>Once updated, all the necessary packages were installed by running the bundler,
the ruby package/dependency manager:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>bundle config set --local path 'vendor/bundle'
bundle install
</code></pre></div></div>

<p>The <code class="language-plaintext highlighter-rouge">bundle config ...</code> command is to force the downloaded gems to be installed
locally, rather than in the system directories. The command is what was
suggested by the bundler when <code class="language-plaintext highlighter-rouge">bundle install</code> was run as a non-root user. The
<code class="language-plaintext highlighter-rouge">vendor/</code> directory is not tracked by git – a <code class="language-plaintext highlighter-rouge">.gitignore</code> file was generated
when <code class="language-plaintext highlighter-rouge">jekyll new ...</code> was run.</p>

<p>Normally, we would run <code class="language-plaintext highlighter-rouge">bundle exec jekyll serve</code> to generate and preview the
web pages, however, since I am using ruby 3.0.x, I also needed an additional
package:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>bundle add webrick
</code></pre></div></div>

<p>The above added another entry, <code class="language-plaintext highlighter-rouge">gem "webrick" ...</code>, to the <code class="language-plaintext highlighter-rouge">Gemfile</code>. Bundler
was run again for the new gem:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>bundle install
</code></pre></div></div>

<h3 id="local-preview-of-the-web-site">Local preview of the web site</h3>

<p>We are now ready to preview the, currently empty, web site:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>bundle exec jekyll serve
</code></pre></div></div>

<p>While the server is running, the web site can be viewed at
<a href="http://localhost:4000">http://localhost:4000</a>. If we modify any of the contents, such as
<code class="language-plaintext highlighter-rouge">index.markdown</code>, the modification will be reflected in the web page, of course
the browser tab will need a refresh/reload.</p>

<h3 id="customization">Customization</h3>

<p>The main configuration of the web site is kept in the <code class="language-plaintext highlighter-rouge">_config.yml</code> file. Some
of the initial settings are sample site title and author names and email. These
needed to be changed.</p>

<p>I configured my own title, name, email etc, followed by a restart of the server.</p>

<p>It should be noted that changes to <code class="language-plaintext highlighter-rouge">_config.yml</code> will only take effect when the
server is restarted.</p>

<h3 id="blog-posts">Blog posts</h3>

<p>Once the web site was operational, the initial base pages, <code class="language-plaintext highlighter-rouge">index.markdown</code> and
<code class="language-plaintext highlighter-rouge">about.markdown</code>, were personalized.</p>

<p>Next, it was just a matter of creating the blog posts in the <code class="language-plaintext highlighter-rouge">_posts</code> directory.</p>

<h3 id="setting-up-my-own-hostname-and-https">Setting up my own hostname and https</h3>

<p>I wanted the web site to be accessed through my own domain name, <code class="language-plaintext highlighter-rouge">anydata.uk</code>.
Again, this was achieved on the github web site, following the instructions
<a href="https://docs.github.com/en/pages/configuring-a-custom-domain-for-your-github-pages-site/about-custom-domains-and-github-pages">here</a></p>

<p>It required creating two <code class="language-plaintext highlighter-rouge">ANAME</code> records, <code class="language-plaintext highlighter-rouge">anydata.uk</code> and <code class="language-plaintext highlighter-rouge">www.anydata.uk</code>,
through my domain name service provider. Both <code class="language-plaintext highlighter-rouge">ANAME</code> and <code class="language-plaintext highlighter-rouge">CNAME</code> records serve
the same purpose, an explanation of the differences can be found on
<a href="https://en.wikipedia.org/wiki/CNAME_record#ANAME_record">Wikipedia</a>.</p>

<p>When configuring the hostname on Github, a new file, <code class="language-plaintext highlighter-rouge">CNAME</code>, was created and
committed to the repo by github. Withih the github settings page the box for
<code class="language-plaintext highlighter-rouge">https</code> was also selected. Naturally, there was a delay before the complete
https based web site was available.</p>

<p>The web site is still accessible through the original github address,
<a href="https://fredyouhanaie.github.io">https://fredyouhanaie.github.io</a>.</p>

<h4 id="other-domain-names">Other domain names</h4>

<p>I also needed my old hostnames, <code class="language-plaintext highlighter-rouge">anydata.co.uk</code> and <code class="language-plaintext highlighter-rouge">www.anydata.co.uk</code>, to
point to the new web site. However, since github only allows one <code class="language-plaintext highlighter-rouge">CNAME</code> per web
site, this could only be achieved with an html redirection on the original
server.</p>

<h3 id="the-_drafts-directory-and-the-drafts-git-branch">The <code class="language-plaintext highlighter-rouge">_drafts</code> directory and the <code class="language-plaintext highlighter-rouge">drafts</code> git branch</h3>

<p>Jekyll expects the blog articles to be files in the <code class="language-plaintext highlighter-rouge">_posts</code> directory. It will
also check for articles in the <code class="language-plaintext highlighter-rouge">_drafts</code> directory, provided that the web pages
are generated with the <code class="language-plaintext highlighter-rouge">--drafts</code> command line option, for example:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>bundle exec jekyll serve --drafts
</code></pre></div></div>

<p>This feature combined with a local/private git branch called <code class="language-plaintext highlighter-rouge">drafts</code> (actually
any name would suffice here) has enabled me to adopt the following process:</p>

<ol>
  <li>Take new blog ideas (good or bad) and write them in files in the <code class="language-plaintext highlighter-rouge">_drafts</code>
folder</li>
  <li>Track the changes/revisions made to the files with git (<code class="language-plaintext highlighter-rouge">drafts</code> branch)</li>
  <li>Review the rendered pages locally, edit/update as necessary</li>
  <li>Repeat the above until something worth publishing emerges</li>
  <li>Copy (not move) the finished article to the <code class="language-plaintext highlighter-rouge">_posts</code> directory, ready for
publication</li>
</ol>

<p>The last step involves creating a new file on the <code class="language-plaintext highlighter-rouge">main</code> branch, and pushing the
changes to github.</p>

<h3 id="epilogue">Epilogue</h3>

<p>For anyone considering a similar project, the supporting documentation provided
by Github and Jekyll are pretty good, even for the impatient! The occasional
internet search also helps ;-)</p>

<p>So, what’s the point of this article? Well, it provides one specific scenario
for anyone in a similar position. And, more specifically, it has allowed me to
aquaint myself with the toolset :-)</p>

<hr />]]></content><author><name>Fred Youhanaie</name></author><category term="general" /><summary type="html"><![CDATA[Setting up github pages with jekyll]]></summary></entry><entry><title type="html">First post</title><link href="https://anydata.uk/general/2022/08/30/first-post.html" rel="alternate" type="text/html" title="First post" /><published>2022-08-30T20:55:00+01:00</published><updated>2022-08-30T20:55:00+01:00</updated><id>https://anydata.uk/general/2022/08/30/first-post</id><content type="html" xml:base="https://anydata.uk/general/2022/08/30/first-post.html"><![CDATA[<p>Hopefully, this is the first of many :-)</p>]]></content><author><name>Fred Youhanaie</name></author><category term="general" /><summary type="html"><![CDATA[.]]></summary></entry><entry><title type="html">Book review: Learning MCollective</title><link href="https://anydata.uk/general/2014/11/21/book-learning-mcollective.html" rel="alternate" type="text/html" title="Book review: Learning MCollective" /><published>2014-11-21T00:00:00+00:00</published><updated>2014-11-21T00:00:00+00:00</updated><id>https://anydata.uk/general/2014/11/21/book-learning-mcollective</id><content type="html" xml:base="https://anydata.uk/general/2014/11/21/book-learning-mcollective.html"><![CDATA[<p><strong>Update 2022-10-17:</strong> <em>This is a copy of the review of a book that was kindly
made available by UKUUG.</em></p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Learning MCollective
Jo Rhett
O'Reilly Media
ISBN: 978-1-491-94567-4
264pp.
£25.99
Published: August 2014
</code></pre></div></div>

<p>MCollective (M for Marionette, as in puppet!) is a Ruby based software framework
from Puppet Labs for orchestrating configuration changes across Puppet or Chef
based groups of servers.</p>

<p>MCollective communicates with the servers under its control through a message
broker, currently only ActiveMQ and RabbitMQ are supported. The main text along
with the examples only covers ActiveMQ, however, those who prefer RabbitMQ are
provided with guidance in the appendix.</p>

<p>The book is divided into four parts that take the reader from initial
installation of the base software to writing custom plugins.</p>

<p>Part I, Getting Started, takes the reader through the basic installation and
configuration of the software, MCollective and ActiveMQ. It then proceeds to
introduce, with examples, the main command line interface, mco. Although, there
are web clients for the software, we are urged to stay with the command line.</p>

<p>Moving along, we are introduced to the basic workings of MCollective plugins and
agents, as well as brief tips on system level maintenance, such as time sync,
log files, monitoring etc. We are then shown how to configure MCollective with
puppet and chef, yes it does sound like a chicken and egg situation, but the
modules are there for us to use.</p>

<p>Those with a large enterprise installation are catered for in part II, Complex
Installations. The message broker plays a very critical role in an MCollective
based environment. In the next five chapters the reader is given guidance on how
to create broker networks to aid scalability and resilience, as well as using
certificates to make the message broker(s) more secure. Admittedly, I only
skimmed over this part, but I am planning on a more through read at a later
date.</p>

<p>As one can expect with any framework these days, MCollective comes equipped with
the ability to create and use plugins. Part III, Custom Plugins, provides
various examples of plugins and walks the reader through creating and deploying
them.</p>

<p>Finally part IV, Putting It All Together, sums up the preceding chapters,
provides a set of best practices and gives guidance on expanding the MCollective
deployment.</p>

<p>I had a play with the command line examples on a Vagrant/VirtualBox based demo
environment that is provided by Puppet Labs, all good fun, and no surprises
there. The example codes and related data files used in the book have been made
available on Rhett’s github repository.</p>

<p>Throughout the book, there are numerous hyperlinks for additional material,
however, they are all Bit.ly shortcuts, which means the reader of the paper copy
of the book will need to type in the links manually. It would be nice if the
author could include these on a web page, or somewhere on the book’s github
repository.</p>

<p>Overall, this book covers a lot of ground, going beyond a mere introduction to
the basics of the framework. Although, its main focus is on Puppet and ActiveMQ,
those who prefer Chef and/or RabbitMQ can still benefit from the text.</p>

<hr />]]></content><author><name>Fred Youhanaie</name></author><category term="general" /><summary type="html"><![CDATA[Book review: Learning MCollective]]></summary></entry><entry><title type="html">Book review: Functional Thinking</title><link href="https://anydata.uk/general/2014/11/20/book-functional-thinking.html" rel="alternate" type="text/html" title="Book review: Functional Thinking" /><published>2014-11-20T00:00:00+00:00</published><updated>2014-11-20T00:00:00+00:00</updated><id>https://anydata.uk/general/2014/11/20/book-functional-thinking</id><content type="html" xml:base="https://anydata.uk/general/2014/11/20/book-functional-thinking.html"><![CDATA[<p><strong>Update 2022-10-17:</strong> <em>This is a copy of the review of a book that was kindly
made available by UKUUG.</em></p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Functional Thinking
Neal Ford
O'Reilly Media
ISBN: 978-1-449-36551-6
164pp.
£25.99
Published: July 2014
</code></pre></div></div>

<p>The preface starts with a history of the book. The author tells us how his
learning process culminated into a series of talks and articles, which now form
the basis of the chapters of the book. Ford also tells us that his “… goal in
the talk, the article series, and this book is to present the core ideas of
functional programming in a way that is accessible to developers steeped in
imperative, object-oriented languages.”</p>

<p>Throughout the book we are treated to many examples of functional code snippets,
written in the three JVM (Java Virtual Machine) based languages, Clojure, Groovy
and Scala.</p>

<p>Chapter 1, Why, gently sets the scene for the functional programming concepts
that are to follow. It introduces the virtues of functional programming by
showing some long Java code snippets for solving simple problems, these will
suit the developers steeped in imperative, object-oriented languages.</p>

<p>Chapter 2, Shift, shows us how to shift our thinking from imperative programming
to functional programming. Ford demonstrates this by means of a simple case
study, number classification, deciding if a given integer is a perfect number
not. We are first introduced to a solution in Java (not Java 8), followed by a
much shorter one written in Java 8. We are then introduced to a few common
building blocks that are “ubiquitous” in functional programming. These “Useful
things” are filter, map and fold/reduce, and they are demonstrated using
numerous examples in Clojure, Groovy and Scala.</p>

<p>In chapter 3, Cede, we are shown how to cede control of the low level details
(such as author’s least favourite, garbage-collection) to the underlying
run-time system. We are introduced to five ways of ceding control so that we can
spend more time thinking about the main problems. These methods are higher order
functions; closures; currying and partial applications; recursion and streams.
For each of these we are treated to a number of concise examples using the
familiar trio of languages.</p>

<p>As we move through the chapters, Ford delves deeper into the functional
programming paradigm. In chapter 4, Smarter, Not Harder, we learn about
memoization (caching) and lazy evaluation. As usual, there are plenty of
examples to help us work smarter.</p>

<p>Chapter 5, Evolve, demonstrates how one can bend the language so that it fits
the problem being solved, rather than the converse. The main topics covered are
operator overloading and functional data structure. The latter includes pattern
matching and Either/Options classes.</p>

<p>The main theme of chapter 6, Advance, is design patterns. Here we learn more
advanced techniques when programming in functional languages.</p>

<p>In chapter 7, Practical Thinking, Ford covers Java 8, the latest version of Java
that understands concepts of functional programming, as well as some real world
examples such as web frameworks and databases, although not in detail.</p>

<p>The book is concluded with chapter 8, Polyglot and Polyparadigm, where the
author discusses functional programming within the wider world of languages and
programming paradigms.</p>

<p>Overall the book is well written and worth a read for anyone interested in
learning the underlying concepts of functional programming. The presence of Java
examples does suggest that the book is aimed at Java programmers, however, the
non-Java developer should still be able to understand the main message of the
book – “Paradigm over Syntax”. Additionally, one also gets a fair exposure to
the trio of the JVM functional languages used in the text.</p>

<hr />]]></content><author><name>Fred Youhanaie</name></author><category term="general" /><summary type="html"><![CDATA[Book review: Functional Thinking]]></summary></entry><entry><title type="html">Book review: Becoming Functional</title><link href="https://anydata.uk/general/2014/11/18/book-becoming-functional.html" rel="alternate" type="text/html" title="Book review: Becoming Functional" /><published>2014-11-18T00:00:00+00:00</published><updated>2014-11-18T00:00:00+00:00</updated><id>https://anydata.uk/general/2014/11/18/book-becoming-functional</id><content type="html" xml:base="https://anydata.uk/general/2014/11/18/book-becoming-functional.html"><![CDATA[<p><strong>Update 2022-10-17:</strong> <em>This is a copy of the review of a book that was kindly
made available by UKUUG.</em></p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Becoming Functional
Joshua Backfield
O'Reilly Media
ISBN: 978-1-449-36817-3
134pp.
£19.50
Published: July 2014
</code></pre></div></div>

<p>The subtitle of the book is “steps for transforming into a functional
programmer”, however, from the start one realises that the object of this
transformation is “a Java programmer”.</p>

<p>The entire book is based on an example which is the legacy Java code of a
fictional company named XXY, and the reader is gradually introduced to the
elements of functional programming by way of transforming the Java code into the
Scala and/or Groovy equivalents.</p>

<p>Chapter 1 gives an overview of functional programming in terms of the seven
concepts: First-Class Functions; Pure Functions; Recursion; Immutable Variables;
Strict and Nonstrict Evaluation; Statements; Pattern Matching. These concepts
are then described, using Java examples, in the seven chapters that follow the
overview.</p>

<p>In chapters 2 and 3, first-class and pure functions are introduced by means of
transforming Java examples into more functional looking variants. In chapter 2
we learn about lambdas and closures, while chapter 3 demonstrates how to avoid
side effects in order to create Pure Functions. Here, we encounter some Groovy
(the language) examples.</p>

<p>Chapter 4 demonstrates how immutable variables can be implemented using a series
of transformations of the standard example Java codes. This is followed by a
chapter on recursion. Tail recursion, an important concept in functional
programming, is also covered here. This is the chapter where we start learning
about Scala.</p>

<p>Chapter 6 is about strict and non-strict (lazy) evaluation. The concepts are
explained using examples in Groovy and Scala. The advantages and disadvantages
of each of the methods is also covered.</p>

<p>In chapters 7 (Statements) and 8 (Pattern Matching) we are treated to more Scala
code. Chapter 7 shows how one can obtain a more concise code since every
statement in a functional language returns some value. This is demonstrated by
means of transforming the example Java code to its Scala equivalent. This leads
nicely to the chapter on pattern matching, which contains plenty of example
codes in Scala (and no Java!)</p>

<p>In chapter 9, Functional OOP, we are treated to more examples in Scala and shown
how we can got about taking advantage of both worlds.</p>

<p>The book is short and concise. The text is well written and the structure makes
it easy to get the gist of the contents. Most of the chapters have a conclusion
section that sums up what has been covered in the chapter, including the
“Conclusion” chapter, but the recursion stops there!</p>

<p>If you are a Java programmer and have not had any exposure to functional
programming, then you can benefit from this book. On the other hand, if you have
had some exposure to functional programming, but programming in Java is not
second nature to you, then you may find the Java examples rather distracting.</p>

<hr />]]></content><author><name>Fred Youhanaie</name></author><category term="general" /><summary type="html"><![CDATA[Book review: Becoming Functional]]></summary></entry></feed>