<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Dev on The Final Artefact</title><link>https://www.thefinalartefact.xyz/categories/dev/</link><description>Recent content in Dev on The Final Artefact</description><generator>Hugo</generator><language>en-gb</language><lastBuildDate>Mon, 24 Nov 2025 16:01:56 +0000</lastBuildDate><atom:link href="https://www.thefinalartefact.xyz/categories/dev/index.xml" rel="self" type="application/rss+xml"/><item><title>Using Xcode Pre- and Post-actions to Observe Changes to Defaults</title><link>https://www.thefinalartefact.xyz/post/build-pre-post-actions-observe-default/</link><pubDate>Mon, 24 Nov 2025 16:01:56 +0000</pubDate><guid>https://www.thefinalartefact.xyz/post/build-pre-post-actions-observe-default/</guid><description>Because UserDefaults persistence is opportunistic, it’s often hard to tell when values truly flush and what changed between runs. In the article I set up an app group prefs watcher with fswatch, convert the binary plist to XML via plutil, and log a timestamped diff for every write—no breakpoints, no in-app logging. If you’ve ever wondered “what did my app really persist?”, this workflow makes it obvious.</description></item><item><title>Automatically Refreshing NVim plugins</title><link>https://www.thefinalartefact.xyz/post/nvim-autoupdate/</link><pubDate>Fri, 28 Mar 2025 00:00:00 +0000</pubDate><guid>https://www.thefinalartefact.xyz/post/nvim-autoupdate/</guid><description>&lt;p&gt;One of the key benefits of modern editors like NVim, Vim, or Emacs is the rich plugin ecosystem. After years with Vim, I switched to NVim and was immediately impressed by its plugin landscape. The &lt;a href="https://github.com/folke/lazy.nvim"&gt;Lazy&lt;/a&gt; plugin manager—available for NVim &amp;gt; 0.8—quickly became my favourite. &lt;a href="https://github.com/folke/lazy.nvim"&gt;Lazy&lt;/a&gt; simplifies plugin discovery and management. It offers an intuitive interface and powerful commands that make it easy to add, remove, or update plugins.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.thefinalartefact.xyz/post/nvim-autoupdate/images/lazy_image.png" target="_blank" rel="noopener noreferrer"&gt;
&lt;img alt="Lazy Plugin in Actions" loading="lazy" src="https://www.thefinalartefact.xyz/post/nvim-autoupdate/images/lazy_image.png"&gt;
&lt;/a&gt;&lt;/p&gt;</description></item><item><title>On Structuring Python Projects</title><link>https://www.thefinalartefact.xyz/post/python-project-structure/</link><pubDate>Wed, 16 Mar 2022 00:00:00 +0000</pubDate><guid>https://www.thefinalartefact.xyz/post/python-project-structure/</guid><description>&lt;h2 id="types-of-projects"&gt;Types of Projects&lt;/h2&gt;
&lt;p&gt;The term &lt;em&gt;Python project&lt;/em&gt; can be somewhat misleading. While languages like Swift are designed for specific purposes such as generating macOS/iOS apps, components, and frameworks, Python is used in a much more versatile manner. A &lt;em&gt;Python project&lt;/em&gt; might range from an analytical solution developed across multiple Jupyter notebooks to a standalone script querying a database API and extracting results to an application or package facilitating the deployment of models. Each of these projects has its own key usability requirements. For instance, if end-users will utilize our project through a command-line interface, we will focus on argument parsing and other elements facilitating user-friendly execution.&lt;/p&gt;</description></item><item><title>Poor Man's Robust Shiny App Deployment (Part II)</title><link>https://www.thefinalartefact.xyz/post/sample-analytical-app-with-shiny/</link><pubDate>Fri, 12 Feb 2021 00:00:00 +0000</pubDate><guid>https://www.thefinalartefact.xyz/post/sample-analytical-app-with-shiny/</guid><description>&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;
&lt;p&gt;This article draws on the past post concerned with utilisation of &lt;a href="https://github.com/ThinkR-open/golem"&gt;&lt;code&gt;golem&lt;/code&gt;&lt;/a&gt; for robust deployment of analytical and reporting solutions. For this article, we will assume that we are working with defined working requirements that utilise some of the Labour Market Statistics disseminated through the &lt;a href="https://www.nomisweb.co.uk"&gt;&lt;em&gt;nomis&lt;/em&gt;&lt;/a&gt; portal.&lt;/p&gt;
&lt;h2 id="change-plan"&gt;Change Plan&lt;/h2&gt;
&lt;h3 id="what-we-have"&gt;What we have&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Reporting requirements&lt;/li&gt;
&lt;li&gt;Past scriptts we used to create reports with accompanying instructions&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="what-we-want"&gt;What we want&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Stronger business continuity&lt;/em&gt; - we want to be able to give some access to this project and don&amp;rsquo;t be concerned with missing files, outdated unavailable documentation and questions on how to produce updated reports. We want self-encompassing entity that takes of care of its technical requirements and user-interaction^[Good parallel can be drawn between this approach and manuals available with life-saving equipment. Equipment delivers technical capacity and manual ensures operational capacity. In case of an inexperienced user one is not useful without the other. We want to ensure that user with minimum required capacity can use the tools correctly.]&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Better reproducibility&lt;/em&gt; - Easier way to re-run reports on custom parameters&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Improved efficiency&lt;/em&gt; - We want to have a possibility of quickly creating updated and re-running past reports using the app.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Better development:&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;We want to ensure that any change requests to our reporting/analytical stack won&amp;rsquo;t break crucial functionalities.&lt;/li&gt;
&lt;li&gt;We want to modularise development so new corporate branding or visualisation requirements can be applied with no (or minimal) integration in analytical function&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="framework"&gt;Framework&lt;/h2&gt;
&lt;h2 id="package"&gt;Package&lt;/h2&gt;
&lt;p&gt;Future robust development owes a lot to solid foundations. As the aim is to capitalise on the robust R package architecture, we will look to leverage available supporting packages. As a first step, we will construct a new Shiny/R package infrastructure using &lt;code&gt;golem&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Three-Way Operator in R</title><link>https://www.thefinalartefact.xyz/post/three-way-operator-in-r/</link><pubDate>Fri, 08 May 2020 00:00:00 +0000</pubDate><guid>https://www.thefinalartefact.xyz/post/three-way-operator-in-r/</guid><description>&lt;p&gt;Is there a merit for a three-way operator in R?&lt;/p&gt;
&lt;h2 id="background"&gt;Background&lt;/h2&gt;
&lt;p&gt;In C++20 revision added &amp;ldquo;spaceship operator&amp;rdquo;, &lt;a href="https://en.cppreference.com/w/cpp/language/operator_comparison#Three-way_comparison"&gt;which is defined as follows&lt;/a&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-r" data-lang="r"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="c1"&gt;# if lhs &amp;lt; rhs&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&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="c1"&gt;# if lhs &amp;gt; rhs&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="c1"&gt;# if lhs and rhs are equal/equivalent.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="r-implementation"&gt;R implementation&lt;/h2&gt;
&lt;p&gt;The behaviour can be achieved in R in multiple ways. A one straightforward approach would involve making use of the &lt;code&gt;ifelse&lt;/code&gt; statement&lt;/p&gt;
&lt;h2 id="ifelse-implementation"&gt;&lt;code&gt;ifelse&lt;/code&gt; implementation&lt;/h2&gt;
&lt;p&gt;Basic approach would involve comparing the two figures and respectively returning &lt;code&gt;-1&lt;/code&gt; or &lt;code&gt;1&lt;/code&gt; consistently with the definition above.&lt;/p&gt;</description></item></channel></rss>