<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

 <title>Dorktips</title>
 <link href="https://nsbruce.github.io/dorktips/atom.xml" rel="self"/>
 <link href="https://nsbruce.github.io/dorktips/"/>
 <updated>2025-10-20T22:11:42+00:00</updated>
 <id>https://nsbruce.github.io/dorktips</id>
 <author>
   <name>Nicholas Bruce</name>
   <email>nicholas@nicholasbruce.ca</email>
 </author>

 
 <entry>
   <title>SVGs, OpenCLI, finished software, and reframing technical debt</title>
   <link href="https://nsbruce.github.io/dorktips/2025/10/20/svgs-opencli-finishing-sw-technical-debt/"/>
   <updated>2025-10-20T00:00:00+00:00</updated>
   <id>https://nsbruce.github.io/dorktips/2025/10/20/svgs-opencli-finishing-sw-technical-debt</id>
   <content type="html">&lt;h2 id=&quot;svg-tutorial&quot;&gt;SVG tutorial&lt;/h2&gt;

&lt;p&gt;Vector graphics are cool! I do a lot of work using LaTeX/TikZ for vector graphics but in the web and for a more modern experience, SVG exists. This tutorial is a really friendly intro with lots of clickable examples and good explanations of high-level elements.&lt;/p&gt;

&lt;p&gt;Link: &lt;a href=&quot;https://www.joshwcomeau.com/svg/friendly-introduction-to-svg&quot;&gt;https://www.joshwcomeau.com/svg/friendly-introduction-to-svg&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;opencli&quot;&gt;OpenCLI&lt;/h2&gt;

&lt;p&gt;Following in the footsteps of the popular OpenAPI, this effort to provide a standard for interfacing with CLI applications is interesting. It’s still very much in an “alpha” stage of development but the idea is appealing. As somebody who spends a lot of time working with CLI tools, it’s easy to imagine the utility of having standard interfaces for making things like automation easier.&lt;/p&gt;

&lt;p&gt;Link: &lt;a href=&quot;https://opencli.org/&quot;&gt;https://opencli.org/&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;software-can-be-finished&quot;&gt;Software can be finished&lt;/h2&gt;

&lt;p&gt;I have been party to many discussions (especially with management and external stakeholders) about how software is never really “finished” and as an owner of said software one must consider ongoing maintenance. Often that maintenance is just dependency updates, but regularly having eyes on deployed code keeps it from stagnating. This article is not directly arguing with this, but points out that &lt;em&gt;some&lt;/em&gt; software can be finished and we should sometimes strive for that. I understood this as a “limit” (in the sense of calculus). We may never reach finished software but we can and maybe should try to approach it.&lt;/p&gt;

&lt;p&gt;Link: &lt;a href=&quot;https://rosswintle.uk/2025/10/software-can-be-finished&quot;&gt;https://rosswintle.uk/2025/10/software-can-be-finished&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;can-we-frame-technical-debt-positively&quot;&gt;Can we frame technical debt positively?&lt;/h2&gt;

&lt;p&gt;I really loved this short article, which frames technical debt as a knowledge gain. Basically, you either learn something or a new technology is released and in both cases your existing code could now be improved. In these cases, the “technical debt” is actually just a gain in knowledge, and a failure it do the improvement work is now an opportunity cost.&lt;/p&gt;

&lt;p&gt;Link: &lt;a href=&quot;https://lukeplant.me.uk/blog/posts/knowledge-creates-technical-debt&quot;&gt;https://lukeplant.me.uk/blog/posts/knowledge-creates-technical-debt&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Reference sheets, xan, nala, and duf</title>
   <link href="https://nsbruce.github.io/dorktips/2025/04/29/quickref-xan-nala-duf/"/>
   <updated>2025-04-29T00:00:00+00:00</updated>
   <id>https://nsbruce.github.io/dorktips/2025/04/29/quickref-xan-nala-duf</id>
   <content type="html">&lt;h2 id=&quot;quickrefme&quot;&gt;QuickRef.ME&lt;/h2&gt;

&lt;p&gt;A collection of cheatsheets for various computing tools and languages. I’ve used the ones for RegEX and Sed and they’re good! I think the Linux Command section is the most interesting. There is also a list of keyboard shortcuts for various apps and websites. Oh and everything is community contributed! Similar to &lt;a href=&quot;https://devdocs.io&quot;&gt;devdocs.io&lt;/a&gt; from the &lt;a href=&quot;2025-04-04-apis-ubuntu-packages-database-logs-gum&quot;&gt;last post&lt;/a&gt;, this is basically a bunch of documentation in a unified format.&lt;/p&gt;

&lt;p&gt;Link: &lt;a href=&quot;https://quickref.me&quot;&gt;https://quickref.me&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;xan&quot;&gt;xan&lt;/h2&gt;

&lt;p&gt;A command line tool for inspecting and processing csv files which is YARR (Yet Another Rust Rewrite). The neat part here (for me) is that it lets you plot the contents directly in the terminal.&lt;/p&gt;

&lt;p&gt;Given a csv:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-csv&quot;&gt;X,Y
1,1
2,2
3,4
4,8
5,4
6,1
7,1
8,10
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;xan plot --line X Y test.csv&lt;/code&gt; will yield the following plot in the terminal emulator. It also handles timestamps well for the x values.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/2025-04-29-xan-plot.png&quot; alt=&quot;xan plot&quot; /&gt;&lt;/p&gt;

&lt;p&gt;One mark against &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;xan&lt;/code&gt; is that it didn’t install flawlessly on my system. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cargo install xan&lt;/code&gt; resulted in an error about some badly written dependency code, but installing from the git repo worked with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CARGO_BUILD_RUSTFLAGS=&apos;-C target-cpu=native&apos; cargo install --git https://github.com/medialab/xan&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href=&quot;https://github.com/medialab/xan&quot;&gt;https://github.com/medialab/xan&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;nala&quot;&gt;nala&lt;/h2&gt;

&lt;p&gt;This is an improved &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apt&lt;/code&gt; experience for those on Debian based systems. I’ve just started using it and so far so good. Highlights for me are: colorized and nicely formatted output, parallel downloads. The speed up is nice and it seems like a drop-in replacement for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apt&lt;/code&gt; in terms of my typical use (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apt update&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nala update&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apt install xan&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nala install xan&lt;/code&gt;, …).&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href=&quot;https://github.com/volitank/nala&quot;&gt;https://github.com/volitank/nala&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;duf&quot;&gt;duf&lt;/h2&gt;

&lt;p&gt;This is an improved disk usage utility meant to replace &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;df&lt;/code&gt;. I started using it at the same time as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nala&lt;/code&gt; and have had a similarly “harmless upgrade” experience. There isn’t much to write about - the default &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;df&lt;/code&gt; output isn’t the easiest to interpret while the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;duf&lt;/code&gt; default output is well organized and colorized.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href=&quot;https://github.com/muesli/duf&quot;&gt;https://github.com/muesli/duf&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>One stop API docs, speed up Ubuntu packages, put logs in a database, and gUM</title>
   <link href="https://nsbruce.github.io/dorktips/2025/04/04/apis-ubuntu-packages-database-logs-gum/"/>
   <updated>2025-04-04T00:00:00+00:00</updated>
   <id>https://nsbruce.github.io/dorktips/2025/04/04/apis-ubuntu-packages-database-logs-gum</id>
   <content type="html">&lt;h2 id=&quot;the-one-api-documentation-site-to-rule-them-all&quot;&gt;The one API documentation site to rule them all&lt;/h2&gt;

&lt;p&gt;This website has plugged in the API documentation for many languages and tools, and formatted it all the same. So rather than switch from the Python docs site to the NumPy docs site to the Ansible docs site, you can access them all in one place. It has a huge number of languages and tools available.&lt;/p&gt;

&lt;p&gt;Link: &lt;a href=&quot;https://devdocs.io&quot;&gt;https://devdocs.io&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;19x-speedup-for-ubuntu-packages-via-recompilation&quot;&gt;1.9x speedup for Ubuntu packages via recompilation&lt;/h2&gt;

&lt;p&gt;This person did a short investigation into whether they could speed up the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jq&lt;/code&gt; binary available via Ubuntu. They tested a number of build settings and eventually realized a large speed-up was available by swapping out the memory allocator. Mostly what’s cool about this short read is the authors well documented investigation process. I learned several things about how compilers work just by following along!&lt;/p&gt;

&lt;p&gt;Link: &lt;a href=&quot;https://gist.github.com/jwbee/7e8b27e298de8bbbf8abfa4c232db097&quot;&gt;https://gist.github.com/jwbee/7e8b27e298de8bbbf8abfa4c232db097&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;put-your-logs-in-a-database&quot;&gt;Put your logs in a database&lt;/h2&gt;

&lt;p&gt;The author reminds everyone that databases were invented for a reason - parsing raw data is slow and terrible. Similarly, log databases exist because it is much faster to query a database than it is to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;grep&lt;/code&gt; text files. As well, you can “do all kinds of other database-y stuff”. To showcase their point, they compare querying a log database on an old underpowered computer vs querying a repository of text files on a new overpowered computer.&lt;/p&gt;

&lt;p&gt;Article: &lt;a href=&quot;https://chronicles.mad-scientist.club/tales/grepping-logs-remains-terrible&quot;&gt;https://chronicles.mad-scientist.club/tales/grepping-logs-remains-terrible&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;mozilla-gum&quot;&gt;Mozilla gUM&lt;/h2&gt;

&lt;p&gt;A handy tool for testing the interface between your browser and computers hardware. I use this to check whether my screen sharing and mic/video should be working when I have video calls to make (rather than starting and sitting alone in an actual call). It’s a good troubleshooting tool!&lt;/p&gt;

&lt;p&gt;Link: &lt;a href=&quot;https://mozilla.github.io/webrtc-landing/gum_test.html&quot;&gt;https://mozilla.github.io/webrtc-landing/gum_test.html&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Cognitive load, lab, txt calendars, and coding managers</title>
   <link href="https://nsbruce.github.io/dorktips/2025/03/07/cognitive-load-lab-txt-calendars-manager-coding/"/>
   <updated>2025-03-07T00:00:00+00:00</updated>
   <id>https://nsbruce.github.io/dorktips/2025/03/07/cognitive-load-lab-txt-calendars-manager-coding</id>
   <content type="html">&lt;h2 id=&quot;cognitive-load-is-all-that-matters&quot;&gt;Cognitive load is all that matters&lt;/h2&gt;

&lt;p&gt;This is an argument that the cognitive load for a new developer to interface with your software project should be the guiding design principle for that project. Instead of focusing on abstraction, or modularity, or anyother architectural element, only consider how easy it is to understand what is going on.&lt;/p&gt;

&lt;p&gt;This is the latest in the list of articles I’ve been reading recently which make explicit the complaint that new language features shouldn’t be adopted unless they’re easy to understand, and there are big downsides to coding as a “smart developer” since these things increase cognitive load for others.&lt;/p&gt;

&lt;p&gt;Article: &lt;a href=&quot;https://minds.md/zakirullin/cognitive&quot;&gt;https://minds.md/zakirullin/cognitive&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;lab&quot;&gt;Lab&lt;/h2&gt;

&lt;p&gt;I’ve been using this for a week now and am finding it useful. It’s typical in my day-to-day to write lots of single-use code. I have a directory on my computer somewhere that I write these little scripts and occasionally wipe them from my system. It’s a bit of an annoying workflow. Lab solves this by letting you create, edit and run files from anywhere on your computer, then clearing them out every 7 days. You create a file with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lab &amp;lt;ext&amp;gt;&lt;/code&gt; where ext is the file extension. It will open in your terminal editor of choice, and save it with a timestamp filename somewhere in your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/tmp&lt;/code&gt; directory. Running &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lab&lt;/code&gt; with no arguments lists the files (each with an index), and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lab -r &amp;lt;index&amp;gt; &amp;lt;executable&amp;gt;&lt;/code&gt; will run the file at some index with some executable. For example, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lab -r 3 python3&lt;/code&gt; with effectively do &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;python3 /tmp/path/to/my/index3file.py&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href=&quot;https://github.com/lugenx/lab&quot;&gt;https://github.com/lugenx/lab&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;replace-your-calendar-with-a-text-file&quot;&gt;Replace your calendar with a… text file?&lt;/h2&gt;

&lt;p&gt;I’m big on plain text notes, but this person is selling taking things a step further. They have established a standard for plain text calendars. The idea is to use any editor to add/edit, and standard UNIX CLI tools to search, sort and inspect entries.&lt;/p&gt;

&lt;p&gt;Article: &lt;a href=&quot;https://terokarvinen.com/2021/calendar-txt/&quot;&gt;https://terokarvinen.com/2021/calendar-txt/&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;should-managers-write-code&quot;&gt;Should managers write code?&lt;/h2&gt;

&lt;p&gt;This is an opinion piece by an engineering leader on whether technical managers should write code or not. It’s well thought out set of ideas from the author of three related books. The gist of the article is that managers should be involved in the details, but only in certain cases should they write code themselves.&lt;/p&gt;

&lt;p&gt;Article: &lt;a href=&quot;https://theengineeringmanager.substack.com/p/should-managers-still-code&quot;&gt;https://theengineeringmanager.substack.com/p/should-managers-still-code&lt;/a&gt;&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Design docs, logging defaults, unix philosophy, and POSIX time</title>
   <link href="https://nsbruce.github.io/dorktips/2024/12/26/design-docs-logging-unix-philosophy-posix/"/>
   <updated>2024-12-26T00:00:00+00:00</updated>
   <id>https://nsbruce.github.io/dorktips/2024/12/26/design-docs-logging-unix-philosophy-posix</id>
   <content type="html">&lt;h2 id=&quot;design-docs--throwaway-code&quot;&gt;Design docs &amp;lt; throwaway code&lt;/h2&gt;

&lt;p&gt;Design docs make for bad documentation because they get outdated so quickly. They also claim to answer questions that can’t actually be answered before code is written. However they can be used to solicit early feedback on ideas and write down long-term focuses.&lt;/p&gt;

&lt;p&gt;These are some of the pros and cons that the author gives for design documents which they then contrast with using draft pull requests to organize ideas and solicit feedback.&lt;/p&gt;

&lt;p&gt;Article: &lt;a href=&quot;https://softwaredoug.com/blog/2024/12/14/throwaway-prs-not-design-docs&quot;&gt;https://softwaredoug.com/blog/2024/12/14/throwaway-prs-not-design-docs&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;sensible-logging-defaults&quot;&gt;Sensible logging defaults&lt;/h2&gt;

&lt;p&gt;This article lists the good and the bad traits for logging. It’s specifically about cloud native applications, but I think the majority are valid for non-cloud apps. I think that cloud native is the most difficult logging scenario, where you’re expecting (possibly many) users to be emitting logs to some central node, and you obviously have to deal with “the” network. Applying cloud native logging practices to all logging situations will only help.&lt;/p&gt;

&lt;p&gt;My favourite listed trait is the unix philosophies “Rule of Silence”:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;When a program has nothing surprising to say, it should say nothing&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Article: &lt;a href=&quot;https://gerlacdt.github.io/blog/posts/logging&quot;&gt;https://gerlacdt.github.io/blog/posts/logging&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;unix-philosophy&quot;&gt;unix philosophy&lt;/h2&gt;

&lt;p&gt;A follow on from the last entry on sensible logging, here is the unix philosophy captured in 17 rules. I’ve read variants of this list many times, but it’s good to remind yourself of the ones which are your “natural weaknesses”. One that I find slippery is the “Rule of Clarity”:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Clarity is better than cleverness&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In my experience programmers (myself included) love to be smart while writing code. This “rule” says that we should write programs for the humans that will read and maintain them, not for the computer that injests their output or runs them.&lt;/p&gt;

&lt;p&gt;Article: &lt;a href=&quot;http://www.catb.org/esr/writings/taoup/html/ch01s06.html&quot;&gt;http://www.catb.org/esr/writings/taoup/html/ch01s06.html&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;seconds-since-the-epoch&quot;&gt;Seconds Since the Epoch&lt;/h2&gt;

&lt;p&gt;A reminder that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;now.time() - before.time()&lt;/code&gt; does not necessarily represent the duration in seconds between &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;now&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;before&lt;/code&gt; if you mean seconds on a clock, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;time()&lt;/code&gt; returns seconds since the epoch. Seconds since the epoch is defined using exactly 86,400 seconds per day, and ignores leap seconds. When the author wrote this article, UTC time was 29 seconds away from POSIX time.&lt;/p&gt;

&lt;p&gt;I love reading software documentation on these things because you can tell there was a lot of thought put into any decent implementations for time management libraries. My favourite quote that the author pulls from IEEE 1003.1 is&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Most systems’ notion of “time” is that of a continuously-increasing value, so this value should increase even during leap seconds.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Article: &lt;a href=&quot;https://aphyr.com/posts/378-seconds-since-the-epoch&quot;&gt;https://aphyr.com/posts/378-seconds-since-the-epoch&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Chaining Python, bat, gopass, and JSON sucks</title>
   <link href="https://nsbruce.github.io/dorktips/2024/12/19/chaining-python-bat-gopass-json-sucks/"/>
   <updated>2024-12-19T00:00:00+00:00</updated>
   <id>https://nsbruce.github.io/dorktips/2024/12/19/chaining-python-bat-gopass-json-sucks</id>
   <content type="html">&lt;h2 id=&quot;python-chained-expressions&quot;&gt;Python chained expressions&lt;/h2&gt;

&lt;p&gt;This quick write up discusses an interview question that a candidate got &lt;em&gt;right&lt;/em&gt; but the interviewer thought was wrong. It’s not uncommon in Python to assign variables like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x = y = 5&lt;/code&gt;, and check multiple conditions at once like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if x == y == z:&lt;/code&gt;. In the condition check, imagine &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;y&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;z&lt;/code&gt; are strings. It is reasonable to think that this expression would first evaluate &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x == y&lt;/code&gt; and get a bool (say &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;True&lt;/code&gt;), then evaluate &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;True == z&lt;/code&gt; which will be &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;False&lt;/code&gt;. So no matter the values of your three variables, the result is always &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;False&lt;/code&gt;. However, in Python chained expressions are transformed and the condition becomes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if (x == y) and (y == z):&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Article: &lt;a href=&quot;https://www.ashu1461.com/interview-gone-wrong/&quot;&gt;https://www.ashu1461.com/interview-gone-wrong/&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;bat&quot;&gt;bat&lt;/h2&gt;

&lt;p&gt;From the project README: “A &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cat&lt;/code&gt; clone with syntax highlighting and Git integration”. I call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cat&lt;/code&gt; many times per day and I’ve just aliased &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cat=bat&lt;/code&gt;. It seems to work in the exact same way but with syntax highlighting for a bunch of languages, shows line numbers, and indicates changes if it’s a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git&lt;/code&gt; managed file. The only use case I regularly have that this screws up is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cat&lt;/code&gt;-ing something then copying out a section of the file. I can get rid of the line numbers and such by doing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cat --style plain &amp;lt;myfile&amp;gt;&lt;/code&gt; and I’ll see if this gets annoying.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; It’s been a few weeks and I’m enjoying it. It does make regular &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cat&lt;/code&gt; seem more bland. Syntax highlighting is nice!&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href=&quot;https://github.com/sharkdp/bat&quot;&gt;https://github.com/sharkdp/bat&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;gopass&quot;&gt;gopass&lt;/h2&gt;

&lt;p&gt;I have been using Keepass (and the keepassxc client) to manage my passwords for more than a decade. At work we needed to have a shared password manager and a coworker did some research on the options, eventually settling us on gopass. I’m now switching all of my personal password management to gopass too, since it’s just better for me. It’s got a great CLI, the passwords are all stored as separate encrypted files in a basic directory structure, and authentication is offloaded to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gpg&lt;/code&gt;. It’s by default git managed, and if you set up a remote for the repo, it will automatically push/pull after you make changes. The thing I really like is that it’s simple and easy to understand! It’s pretty developer focused though - getting it setup does require an understanding of things like git and gpg. I would not call it “friendly” for the general public.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href=&quot;https://github.com/gopasspw/gopass&quot;&gt;https://github.com/gopasspw/gopass&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;nobody-gets-fired-for-picking-json-but-maybe-they-should&quot;&gt;Nobody Gets Fired for Picking JSON, but Maybe They Should?&lt;/h2&gt;

&lt;p&gt;Even if this article was bad (it’s great) it would probably make it onto dorktips purely thanks to the article title. I have written about several JSON alternatives in previous dorktips articles, but never about ProtoBuf. This article steps through a number of the biggest JSON issues, most of which stem from too vague a specification. This means that each parser/tool has to make decisions which often don’t agree. One particularly egregious example that stood out to me is that Python will serve invalid JSON (per RFC8259) for non-finite values. Wacky.&lt;/p&gt;

&lt;p&gt;Article: &lt;a href=&quot;https://mcyoung.xyz/2024/12/10/json-sucks&quot;&gt;https://mcyoung.xyz/2024/12/10/json-sucks&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Greater good, value gap, Viking, and a solar powered website</title>
   <link href="https://nsbruce.github.io/dorktips/2024/09/03/greater-good-value-gap-viking-solar/"/>
   <updated>2024-09-03T00:00:00+00:00</updated>
   <id>https://nsbruce.github.io/dorktips/2024/09/03/greater-good-value-gap-viking-solar</id>
   <content type="html">&lt;h2 id=&quot;greater-good-vs-individual-autonomy&quot;&gt;Greater good vs. individual autonomy&lt;/h2&gt;

&lt;p&gt;This article discusses the tradeoffs between global optimization and individual optimization as it applies it a workplace. It’s particularly interesting to me since I work on a small team in a large bureaucracy. In my experience, being on a small team leads to a relatively individualistic sense of “I’ll just do what is best for me”, and attempts to standardize efforts can feel like overkill. It’s an interesting discussion every time when deciding on whether reducing individual autonomy is worthwhile for the greater good of the team.&lt;/p&gt;

&lt;p&gt;Article: &lt;a href=&quot;https://longform.asmartbear.com/tension-autonomy-admin/&quot;&gt;https://longform.asmartbear.com/tension-autonomy-admin/&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;differing-values-within-a-team-causes-tension&quot;&gt;Differing values within a team causes tension&lt;/h2&gt;

&lt;p&gt;Interesting, this talks about situations where members of a software development team (probably any team) have differing values. Differing values doesn’t mean different skills, or that person A &lt;em&gt;doesn’t value&lt;/em&gt; person B’s main value, it means that they just have different main values. While on the surface everyone might agrees that valueA and valueB are both important, in practice each person is spending energy and effort on different things. Depending on the severity of the “value gap”, this can cause team tension and dysfunction. On large teams this is mitigated by sheer numbers. On small teams it’s important to recognize these differences and work on value alignment.&lt;/p&gt;

&lt;p&gt;Article: &lt;a href=&quot;https://rtpg.co/2024/08/31/cost-of-a-values-gap&quot;&gt;https://rtpg.co/2024/08/31/cost-of-a-values-gap&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;viking&quot;&gt;Viking&lt;/h2&gt;

&lt;p&gt;Viking handles software deployment to multiple machines. It lets you save a configuration for multiple machines (including ssh keys), they copy files between the local machine and the viking managed machines in parallel, or execute commands on those machines in parallel. The readme has a good “usage” section.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href=&quot;https://github.com/d3witt/viking&quot;&gt;https://github.com/d3witt/viking&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;solar-powered-website&quot;&gt;Solar powered website&lt;/h2&gt;

&lt;p&gt;Pretty self explanatory - this website is solar powered! It’s pretty cool. They talk about hardware and software optimizations they’ve made (it’s self hosted), as well as how much downtime they have from the batteries not getting charged well enough. I’m particularly interested in some of the software tweaks they made to really minimize energy consumption.&lt;/p&gt;

&lt;p&gt;Website: &lt;a href=&quot;https://solar.lowtechmagazine.com/about/the-solar-website/&quot;&gt;https://solar.lowtechmagazine.com/about/the-solar-website/&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Ly, documentation isn't communication, sgrep, and AGPL</title>
   <link href="https://nsbruce.github.io/dorktips/2024/08/08/ly-documentation-sgrep-agpl/"/>
   <updated>2024-08-08T00:00:00+00:00</updated>
   <id>https://nsbruce.github.io/dorktips/2024/08/08/ly-documentation-sgrep-agpl</id>
   <content type="html">&lt;h2 id=&quot;ly&quot;&gt;Ly&lt;/h2&gt;

&lt;p&gt;This is a simple TUI display manager. Works with a bunch of desktop environments (both X and Wayland). I don’t use a display manager and just launch my window manager manually after startup but was tempted by the pretty TUI in this case. In other news, I always thought TUI meant “terminal user interface” because I’m a dufus but it’s actually “textual user interface”.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href=&quot;https://github.com/fairyglade/ly&quot;&gt;https://github.com/fairyglade/ly&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;to-document-or-not-to-document&quot;&gt;To document or not to document&lt;/h2&gt;

&lt;p&gt;This article from the author of Javadoc for JUnit talks about his stance that, respective to software, documentation is not as important as communication and the two are not synonymous. A good quote from the article:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;the superior programmer exercises superior design skills to avoid having to exercise superior communication skills&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The gist of the article is that self-documenting code isn’t the answer, and neither is writing a ton of documentation if that documentation is for unstable software, read by only a few, or done at the cost of other more beneficial work. Emphasis is placed on simplifying code such that less documentation is needed, writing tests, and using a whiteboard to communicate with other developers.&lt;/p&gt;

&lt;p&gt;Article: &lt;a href=&quot;https://tidyfirst.substack.com/p/the-documentation-tradeoff&quot;&gt;https://tidyfirst.substack.com/p/the-documentation-tradeoff&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;sgrep&quot;&gt;sgrep&lt;/h2&gt;

&lt;p&gt;A semantic grep tool which supports various models (with Google’s Word2Vec being the default). It can be used just like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;grep&lt;/code&gt;, by piping in any text input. Unfortunately, there is another project out there named &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sgrep&lt;/code&gt;, which they use to mean “sorted grep”.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href=&quot;https://github.com/arunsupe/semantic-grep&quot;&gt;https://github.com/arunsupe/semantic-grep&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;agpl&quot;&gt;AGPL&lt;/h2&gt;

&lt;p&gt;This is a license I wasn’t really aware of until checking out a friends project that usesit. Since then I read this short and informative article from ParadeDB about why they use the AGPL license and directly compares it with Apache 2.0, BSL, and ELv2.&lt;/p&gt;

&lt;p&gt;Article: &lt;a href=&quot;https://blog.paradedb.com/pages/agpl&quot;&gt;https://blog.paradedb.com/pages/agpl&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Aerospace, Notepad Tab, Learn X in Y and json.bash</title>
   <link href="https://nsbruce.github.io/dorktips/2024/07/03/aerospace-notepad-learn-x-in-y-json-bash/"/>
   <updated>2024-07-03T00:00:00+00:00</updated>
   <id>https://nsbruce.github.io/dorktips/2024/07/03/aerospace-notepad-learn-x-in-y-json-bash</id>
   <content type="html">&lt;h2 id=&quot;aerospace&quot;&gt;AeroSpace&lt;/h2&gt;

&lt;p&gt;I’ve been planning to do a piece on Dorktips for some time about “my stack”, where I’ll step through the components of my development environment. I use a tiling window manager and since transitioning to it have found stacking window managers (like Windows, GNOME, KDE, macOS, etc) pretty limiting. This is a project that I haven’t tried yet which emulates a proper tiling window manager on macOS. The &lt;a href=&quot;https://www.youtube.com/watch?v=UOl7ErqWbrk&quot;&gt;1:31 long Youtube demo&lt;/a&gt; makes it look pretty good!&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href=&quot;https://github.com/nikitabobko/AeroSpace&quot;&gt;https://github.com/nikitabobko/AeroSpace&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;notepad-tab&quot;&gt;Notepad Tab&lt;/h2&gt;

&lt;p&gt;This simple note-taking tool/website works without a server. You type into the box, and the content is encoded into the URL. So you can copy and paste the URL and it will decode into the original content. Very slick idea which they say was inspired by a similarly featured &lt;a href=&quot;https://mermaid.live&quot;&gt;Mermaid editor&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Website: &lt;a href=&quot;https://notepadtab.com&quot;&gt;https://notepadtab.com&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;learn-x-in-y-minutes&quot;&gt;Learn X in Y minutes&lt;/h2&gt;

&lt;p&gt;This website offers crowd-sourced rapid intros to programming languages. Fun for quickly exploring a language you’ve been curious about!&lt;/p&gt;

&lt;p&gt;Website: &lt;a href=&quot;https://learnxinyminutes.com&quot;&gt;https://learnxinyminutes.com&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;jsonbash&quot;&gt;json.bash&lt;/h2&gt;

&lt;p&gt;This tool generates JSON using a CLI tool. This makes it easy to pipe things like environment variables into json files without fiddling with JSON syntax by hand. Following the UNIX philosophy that each program should do one thing well, json.bash states:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;json.bash&lt;/code&gt;’s one thing is to get shell-native data (environment variables, files, program output) to somewhere else, using JSON encapsulate it robustly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I particularly appreciate that the authors so explicitly outline their “one thing”.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href=&quot;https://github.com/h4l/json.bash&quot;&gt;https://github.com/h4l/json.bash&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Pointless code, dictatorships, 'auth' is overloaded, and Dust</title>
   <link href="https://nsbruce.github.io/dorktips/2024/06/10/pointless-auth-bdfl-dust/"/>
   <updated>2024-06-10T00:00:00+00:00</updated>
   <id>https://nsbruce.github.io/dorktips/2024/06/10/pointless-auth-bdfl-dust</id>
   <content type="html">&lt;h2 id=&quot;useful-pointless-code&quot;&gt;Useful pointless code&lt;/h2&gt;

&lt;p&gt;Read on to realize that the expression &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;False if x is False else x&lt;/code&gt; is actually brillant and not from somebody who missed their morning cup of coffee. It’s a very short read!&lt;/p&gt;

&lt;p&gt;Article: &lt;a href=&quot;https://www.tonymottaz.com/blog/code-for-computers-and-humans/&quot;&gt;https://www.tonymottaz.com/blog/code-for-computers-and-humans/&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;guidelines-for-dictators&quot;&gt;Guidelines for dictators&lt;/h2&gt;

&lt;p&gt;The author is the (BDFL) Benevolent Dictator for Life for the cURL project. These are his guidelines, which I think are applicable to all BDFL’s but the author makes a point of saying that this is just his list.&lt;/p&gt;

&lt;p&gt;Article: &lt;a href=&quot;https://daniel.haxx.se/blog/2024/05/27/my-bdfl-guiding-principles/&quot;&gt;https://daniel.haxx.se/blog/2024/05/27/my-bdfl-guiding-principles/&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;stop-saying-auth&quot;&gt;Stop saying “auth”&lt;/h2&gt;

&lt;p&gt;An argument to break “auth” into “login” and “permissions”.&lt;/p&gt;

&lt;p&gt;Article: &lt;a href=&quot;https://ntietz.com/blog/lets-say-instead-of-auth/&quot;&gt;https://ntietz.com/blog/lets-say-instead-of-auth/&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;dust&quot;&gt;Dust&lt;/h2&gt;

&lt;p&gt;A &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;du&lt;/code&gt; replacement which visualizes disk utilization. In my experience it’s much faster than &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;du&lt;/code&gt; and outputs a nice CLI graphic showing a bar chart of directory and file sizes. Sidenote: I learned of this tool from my friend &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dust&lt;/code&gt;in…&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href=&quot;https://github.com/bootandy/dust&quot;&gt;https://github.com/bootandy/dust&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>OSS maintainer manifesto, visual design rules and open source is not a community</title>
   <link href="https://nsbruce.github.io/dorktips/2024/05/21/oss-visual-design/"/>
   <updated>2024-05-21T00:00:00+00:00</updated>
   <id>https://nsbruce.github.io/dorktips/2024/05/21/oss-visual-design</id>
   <content type="html">&lt;h2 id=&quot;open-source-maintainer-manifesto&quot;&gt;Open source maintainer manifesto&lt;/h2&gt;

&lt;p&gt;This is a manifesto that one OSS maintainer has written in an attempt to head off questions like “Is this project still maintained?”. It’s obviously not suitable for every project but it’s a funny read with a basic stance of “I don’t owe you anything, but you’re welcome to hack on it yourself in a fork”.&lt;/p&gt;

&lt;p&gt;Article: &lt;a href=&quot;https://www.hezmatt.org/~mpalmer/blog/2024/05/14/is-this-project-still-maintained.html&quot;&gt;https://www.hezmatt.org/~mpalmer/blog/2024/05/14/is-this-project-still-maintained.html&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;visual-design-rules&quot;&gt;Visual design rules&lt;/h2&gt;

&lt;p&gt;This is not a cheer from a visual design pep rally, it’s just a list of rules one can follow to make visuals attractive. This one has an example for each and I found a careful read-through enlightening. I’ve always been interested in visual design but have never felt particularly gifted at it. I’m a big fan of trying to offset that lack of artistic gift with well-studied skill.&lt;/p&gt;

&lt;p&gt;Article: &lt;a href=&quot;https://anthonyhobday.com/sideprojects/saferules/&quot;&gt;https://anthonyhobday.com/sideprojects/saferules/&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;open-source-is-neither-community-now-democracy&quot;&gt;Open source is neither community now democracy&lt;/h2&gt;

&lt;p&gt;This shares a similar vein as the above manifesto. The primary argument here is that open source is a tool for collaboration, not a policy for decision-making.&lt;/p&gt;

&lt;p&gt;Article: &lt;a href=&quot;https://world.hey.com/dhh/open-source-is-neither-a-community-nor-a-democracy-606abdab&quot;&gt;https://world.hey.com/dhh/open-source-is-neither-a-community-nor-a-democracy-606abdab&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Pack, superfile, Understanding and Symbolica</title>
   <link href="https://nsbruce.github.io/dorktips/2024/05/10/pack-superfile-understanding-symbolica/"/>
   <updated>2024-05-10T00:00:00+00:00</updated>
   <id>https://nsbruce.github.io/dorktips/2024/05/10/pack-superfile-understanding-symbolica</id>
   <content type="html">&lt;h2 id=&quot;pack&quot;&gt;Pack&lt;/h2&gt;

&lt;p&gt;A modern solution for file compression. On their homepage, they show that compared with Zip, gzip, tar, RAR and 7z, Pack:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;compresses more (other than 7z, which was ~50 times slower),&lt;/li&gt;
  &lt;li&gt;is much faster,&lt;/li&gt;
  &lt;li&gt;uses less memory,&lt;/li&gt;
  &lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Link: &lt;a href=&quot;https://pack.ac&quot;&gt;https://pack.ac&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;superfile&quot;&gt;superfile&lt;/h2&gt;

&lt;p&gt;I posted a while back about &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;walk&lt;/code&gt; which is a terminal-based file manager. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;superfile&lt;/code&gt; is another one, this one written in Go. I haven’t tried it since I’m happy with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;walk&lt;/code&gt; for now, but it looks fast and nicely themeable.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href=&quot;https://github.com/MHNightCat/superfile&quot;&gt;https://github.com/MHNightCat/superfile&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;understanding&quot;&gt;Understanding&lt;/h2&gt;

&lt;p&gt;This essay describes how to understand stuff. There are plenty of anecdotes and some really nice quotes from Fermi, Faraday, and “Zen and the Art of Motorcycle Maintenance”. I particularly like Fermi’s comment on how to be successful at something one must contain “the will to think”.&lt;/p&gt;

&lt;p&gt;Article: &lt;a href=&quot;https://nabeelqu.substack.com/p/understanding&quot;&gt;https://nabeelqu.substack.com/p/understanding&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;symbolica&quot;&gt;Symbolica&lt;/h2&gt;

&lt;p&gt;This is an algebra system, written in Rust, with API’s for Python, Rust and C++. There’s a really cool live demo linked from their website homepage. Along with actually evaluating algebraic equations and doing numerical integration, it lets you print to LaTeX.&lt;/p&gt;

&lt;p&gt;Link: &lt;a href=&quot;https://symbolica.io&quot;&gt;https://symbolica.io&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>jnv, difftastic, Radicle and ludic</title>
   <link href="https://nsbruce.github.io/dorktips/2024/04/05/jnv-difftastic-radicle-ludic/"/>
   <updated>2024-04-05T00:00:00+00:00</updated>
   <id>https://nsbruce.github.io/dorktips/2024/04/05/jnv-difftastic-radicle-ludic</id>
   <content type="html">&lt;h2 id=&quot;jnv&quot;&gt;jnv&lt;/h2&gt;

&lt;p&gt;This is cool! I’ve &lt;a href=&quot;./2023-12-11-jq-jaq-cd-bad-graphs.md&quot;&gt;written before&lt;/a&gt; about &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jq&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jaq&lt;/code&gt; which are CLI tools for parsing JSON files. Well &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jnv&lt;/code&gt; takes a different approach - it’s still a CLI tool but it drops you into a type of shell where you can interact with the JSON file in real-time using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jq&lt;/code&gt; syntax. It’s really neat and pretty much immediately replaced &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jq&lt;/code&gt; for me. I find that the fiddle-y part of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jq&lt;/code&gt; is getting the syntax correct and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jnv&lt;/code&gt; helps by letting you see the results of your queries in real-time as you type.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href=&quot;https://github.com/ynqa/jnv&quot;&gt;https://github.com/ynqa/jnv&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;difftastic&quot;&gt;difftastic&lt;/h2&gt;

&lt;p&gt;I’ve always had a hard time parsing the output of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;diff&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git diff&lt;/code&gt;. To be fair to them, I haven’t taken the time to learn the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@@ -12,7 +12,6 @@&lt;/code&gt;-esque syntax, and to be fair to me, that seems like a highly unintuitive syntax. For complicated diffs I end up using the stock VSCode diff viewer. Difftastic seems like an improvement on even that - it uses treesitter to get a syntactic diff!&lt;/p&gt;

&lt;p&gt;Lets do a comparison. First here’s the output of vanilla git diff for a &lt;a href=&quot;https://github.com/TorchDSP/torchsig/pull/231&quot;&gt;small pull request&lt;/a&gt; I made to a public repo recently.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/2024-04-05-git-diff.png&quot; alt=&quot;git diff&quot; /&gt;&lt;/p&gt;

&lt;p&gt;While here is the output from difftastic (with inline mode enabled).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/2024-04-05-git-difft.png&quot; alt=&quot;difftastic&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I particularly like the way line numbers are shown both before and after the change. The bigger ticket item is that “gone are the days” of hunting for which character changed in a line. If a single variable changes, it’s much more clearly highlighted in the diff.&lt;/p&gt;

&lt;p&gt;The actual CLI command is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;difft&lt;/code&gt;, not &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;difftastic&lt;/code&gt; (luckily).&lt;/p&gt;

&lt;p&gt;Link: &lt;a href=&quot;https://difftastic.wilfred.me.uk/&quot;&gt;https://difftastic.wilfred.me.uk/&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;radicle&quot;&gt;Radicle&lt;/h2&gt;

&lt;p&gt;Decentralized Git! Radicle calls itself a “peer-to-peer collaboration stack build on Git”. That means it includes the concepts of issues and pull requests overlaying the code storage which uses Git. Instead of pushing code to a central Github/Gitlab server, you push it to a network of nodes. If your Gitlab/Github server goes down you’re hooped while with Radicle some number of nodes can go down and you won’t be affected. They have a great FAQ page if you’re interested in the mechanics of how they pull this off. I’m a huge fan of decentralization so I hope this takes off!&lt;/p&gt;

&lt;p&gt;Link: &lt;a href=&quot;https://radicle.xyz&quot;&gt;https://radicle.xyz&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;ludic&quot;&gt;ludic&lt;/h2&gt;

&lt;p&gt;Are you tired of seeing React developers brag about component-based web development and having loads of fun and you can’t participate because all you know is Python? Fear not! There is now a Python framework for component-based web development. Joking aside, for simple sites this may be a reasonable approach. It seems to be bred from the cult of Javascript-haters, but they are closely following the reactive architecture which has become so popular in the Javascript web/native frameworks.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href=&quot;https://github.com/paveldedik/ludic&quot;&gt;https://github.com/paveldedik/ludic&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>frugly, pages, htmz, and flox</title>
   <link href="https://nsbruce.github.io/dorktips/2024/03/18/frugly-pages-htmz-flox/"/>
   <updated>2024-03-18T00:00:00+00:00</updated>
   <id>https://nsbruce.github.io/dorktips/2024/03/18/frugly-pages-htmz-flox</id>
   <content type="html">&lt;h2 id=&quot;frugly-design&quot;&gt;Frugly design&lt;/h2&gt;

&lt;p&gt;This is fun - the author wrote an app and wanted to offer a free version as well as a paid version but wasn’t willing to use ads. So they made the free version look really ugly. The article is a hilarious read and I think this is a great idea for a business model! The app is completely functional when free (there are no paid “features”), but it’s just really ugly. Hilarious.&lt;/p&gt;

&lt;p&gt;Article: &lt;a href=&quot;https://taylor.town/frugly&quot;&gt;https://taylor.town/frugly&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;pages-cms&quot;&gt;Pages CMS&lt;/h2&gt;

&lt;p&gt;A CMS for static sites. Take dorktips for example, how do I add a post? I clone the repo, write a new post in markdown, commit and push it. It’s a Jekyll site which is build using Github’s CI and published using Github Pages. It’s pretty simple but maybe I want to allow other contributors, write posts from a computer where git is not installed, or write posts while I’m on the bus using my phone. Pages CMS gives you an online interface to work with. I think it’s a slick and simple idea.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href=&quot;https://github.com/Eventual-Inc/Daft&quot;&gt;https://github.com/Eventual-Inc/Daft&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;htmz&quot;&gt;htmz&lt;/h2&gt;

&lt;p&gt;This project was created in response to the very-popular-right-now htmx project. The idea with htmz is to “load HTML onto any &lt;em&gt;element&lt;/em&gt; in the page on request”. So you end up writing vanilla html, but can load it into the page on demand.&lt;/p&gt;

&lt;p&gt;As a slight aside, I see more and more projects and NDC talks on “build for the web without Javascript”, or sometimes “build for the web without Javascript frameworks”. As someone who has depended on frameworks for a few projects only to have them sorta-fold (I’m talking about, GatsbyJS) and then had to rewrite the whole thing, I’m really interested in this trend. Obviously frameworks are great for a lot of things but if maintenance time has to remain approximately 0, the appeal of a framework-less site becomes very strong for me.&lt;/p&gt;

&lt;p&gt;Link: &lt;a href=&quot;https://leanrada.com/htmz/&quot;&gt;https://leanrada.com/htmz/&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;flox&quot;&gt;Flox&lt;/h2&gt;

&lt;p&gt;Okay this is basically a package manager + virtual environments but it appears they have done a really good job of making it very-cross-platform. The idea is that you can create either a developer environment or maybe build environment for some software, and push that environment up to their hub. Then pull and activate it when necessary. For software projects I depend on Dockerfiles to do this but sometimes Docker is a lot of overhead for few dependencies. I think this is really interesting for developer environments. Whenever you’re on a new machine you can just &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flox pull my-environment&lt;/code&gt; and you’re ready to go.&lt;/p&gt;

&lt;p&gt;Key points:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;you can nest environments, and&lt;/li&gt;
  &lt;li&gt;the packages that are available to you are from nixpkgs, which &lt;a href=&quot;https://flox.dev/blog/nixpkgs&quot;&gt;this article&lt;/a&gt; points out is by far the biggest package repository available. I had no idea!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Repo: &lt;a href=&quot;https://github.com/flox/flox&quot;&gt;https://github.com/flox/flox&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>avoiding meetings, tbmk, fontimize, and oklch</title>
   <link href="https://nsbruce.github.io/dorktips/2024/03/03/avoiding-meetings-tbmk-fontimize-oklch/"/>
   <updated>2024-03-03T00:00:00+00:00</updated>
   <id>https://nsbruce.github.io/dorktips/2024/03/03/avoiding-meetings-tbmk-fontimize-oklch</id>
   <content type="html">&lt;h2 id=&quot;avoid-meetings&quot;&gt;Avoid meetings&lt;/h2&gt;

&lt;p&gt;This subtly titled article, “How to Keep Engineers Out of Meeting Hell,” is a shorty but a goody. It’s the somewhat usual list of tips for ensuring that meetings are useful to the attendees, but with a particular spin on it for engineers. Some tips for those planning or attending meetings are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Ask “how will we know when this meeting is over?” at the start of the meeting,&lt;/li&gt;
  &lt;li&gt;Remember that a desired &lt;em&gt;outcome&lt;/em&gt; of the meeting is as important as having an agenda,&lt;/li&gt;
  &lt;li&gt;Realize that if someone can attend a meeting and work on something else at the same time, then their attendance is unnecessary.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Article: &lt;a href=&quot;https://morethancoding.com/2024/02/16/how-to-keep-engineers-out-of-meeting-hell/&quot;&gt;https://morethancoding.com/2024/02/16/how-to-keep-engineers-out-of-meeting-hell/&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;tbmk&quot;&gt;Tbmk&lt;/h2&gt;

&lt;p&gt;Tbmk (Terminal bookmarker) is a cli tool for managing terminal commands. The idea is exactly the same as for web browser bookmarks - you probably don’t need to bookmark your corporate email login page but you will want to bookmark the page you have to visit every 9 months to change your password. Similarly, it doesn’t make sense to bookmark your daily-driver commands but that weird firewall rule you have to look up every now and then slots right into Tbmk.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href=&quot;https://github.com/linhx/tbmk&quot;&gt;https://github.com/linhx/tbmk&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;fontimize&quot;&gt;Fontimize&lt;/h2&gt;

&lt;p&gt;This is a Python package that optimizes font files for your website. You pass it a font file and either a directory or HTML file and it generates a new file which is a subset of the original font file, containing only the characters that are actually used on your site. The article is a good read on the why and how of font optimization.&lt;/p&gt;

&lt;p&gt;Article: &lt;a href=&quot;https://daveon.design/introducing-fontimize-subset-fonts-to-exactly-and-only-your-websites-used-characters.html&quot;&gt;https://daveon.design/introducing-fontimize-subset-fonts-to-exactly-and-only-your-websites-used-characters.html&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;oklch&quot;&gt;OKLCH&lt;/h2&gt;

&lt;p&gt;News to me, but there’s a new color specification system (think RGB, Hex, HSL, etc.) called OKLCH.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;L: lightness&lt;/li&gt;
  &lt;li&gt;C: chroma&lt;/li&gt;
  &lt;li&gt;H: hue&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is also an “a” for opacity. The article explains the benefits of OKLCH over other specifications which seems to be mostly about perceptual uniformity, readability, and ease of palette generation.&lt;/p&gt;

&lt;p&gt;Article: &lt;a href=&quot;https://evilmartians.com/chronicles/oklch-in-css-why-quit-rgb-hsl&quot;&gt;https://evilmartians.com/chronicles/oklch-in-css-why-quit-rgb-hsl&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>avoid time, slow computing, dep-tree, and RSS</title>
   <link href="https://nsbruce.github.io/dorktips/2024/02/15/no-time-slow-computing-dep-tree-rss/"/>
   <updated>2024-02-15T00:00:00+00:00</updated>
   <id>https://nsbruce.github.io/dorktips/2024/02/15/no-time-slow-computing-dep-tree-rss</id>
   <content type="html">&lt;h2 id=&quot;avoid-programming-anything-to-do-with-time&quot;&gt;Avoid programming anything to do with time&lt;/h2&gt;

&lt;p&gt;One of the first pieces of advice (related to software development) I read online was that if you’re asked to write a calendar or scheduling tool, or anything in that vein, to quit your job immediately and run screaming in the other direction. I’ve since read a number of articles talking about the many edge-cases that appear when dealing with times and dates in software and this one is quite a good one. It lists 34 misconceptions that the author had about timezones. My personal favourite punchlines (not misconceptions) are:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;there are more timezones than countries, and&lt;/li&gt;
  &lt;li&gt;Amsterdam was once offset from UTC by 19 minutes and 32.13 seconds.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Article: &lt;a href=&quot;https://www.zainrizvi.io/blog/falsehoods-programmers-believe-about-time-zones/&quot;&gt;https://www.zainrizvi.io/blog/falsehoods-programmers-believe-about-time-zones/&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;an-argument-for-slow-computing&quot;&gt;An argument for “Slow computing”&lt;/h2&gt;

&lt;p&gt;Similar to “slow fashion” and “slow food”, this author argues that “slow computing” has a place in our world. Specifically where security and safety are concerned. The argument is framed around adding friction to our digital systems which is antithesis to the trend since forever(?) of making our digital experiences as frictionless and fast as possible.&lt;/p&gt;

&lt;p&gt;Article: &lt;a href=&quot;https://www.theregister.com/2024/02/14/friction_is_good/&quot;&gt;https://www.theregister.com/2024/02/14/friction_is_good/&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;dep-tree&quot;&gt;dep-tree&lt;/h2&gt;

&lt;p&gt;In a recent post I linked to an online tool that you could use to get a security snapshot of your project dependencies. Well this tool visualizes a dependency tree as a 3D interactive force-directed graph. The idea is that projects with clean dependency trees (minimal cross-over between different modules and apps) will appear as separate point clouds while closely coupled dependencies will gravitate together. I think this applies more for monorepos and larger projects than small independent repos but it’s very interesting. Below is a plot from one of the repos at my work. As you can see, while there are some separated clouds they are tied together in some places.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/2024-02-15-dep-tree.png&quot; alt=&quot;dep-tree example plot&quot; /&gt;&lt;/p&gt;

&lt;p&gt;They offer a tool you can run yourself and they also have a cloud offering where you paste a link to a github project and they plot it online for you.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href=&quot;https://github.com/gabotechs/dep-tree&quot;&gt;https://github.com/gabotechs/dep-tree&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;rss&quot;&gt;RSS&lt;/h2&gt;

&lt;p&gt;Old tech, still awesome. That’s the gist of this article. I’ve been interested in RSS feeds for a while but haven’t actually used an aggregator. Do you maintain an RSS feed? I’d be interested to hear. I know at least one friend that does.. shout out to Brave Dave in Kelowna. I know he uses one because he has dorktips in his feed! That’s right, you can subscribe to dorktips by checking out the root &lt;a href=&quot;https://nsbruce.github.io/dorktips/atom.xml&quot;&gt;atom.xml&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Article: &lt;a href=&quot;https://www.pcloadletter.dev/blog/rss/&quot;&gt;https://www.pcloadletter.dev/blog/rss/&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Scriptisto, CLI Guidelines, and NTP is outdated</title>
   <link href="https://nsbruce.github.io/dorktips/2024/02/12/scriptisto-clig-old-ntp/"/>
   <updated>2024-02-12T00:00:00+00:00</updated>
   <id>https://nsbruce.github.io/dorktips/2024/02/12/scriptisto-clig-old-ntp</id>
   <content type="html">&lt;h2 id=&quot;scriptisto&quot;&gt;Scriptisto&lt;/h2&gt;

&lt;p&gt;With this tool installed, you make scripts in compiled languages (C, Rust, whatever you want) executable by using the scriptisto shebang, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#!/usr/bin/env scriptisto&lt;/code&gt;. When loaded it looks through comments near the top of the file (in the language the script is written in) to define build steps. Once built, if the script hasn’t changed, that means the binary can be directly executed, speeding things up. There is a neat demo in the readme where they write a simple C file, add the necessary shebang and comments, then &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;chmod +x script.c &amp;amp;&amp;amp; ./script.c&lt;/code&gt;, which of course looks wacky.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href=&quot;https://github.com/igor-petruk/scriptisto&quot;&gt;https://github.com/igor-petruk/scriptisto&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;cli-guidelines&quot;&gt;CLI Guidelines&lt;/h2&gt;

&lt;p&gt;A set of highly opinionated but well informed and thought out guidelines for writing CLI programs. The introduction is worth a read at a minimum. Plus it’s a beautiful website (which is kind of a must if you’re about to tell people how to design a UI).&lt;/p&gt;

&lt;p&gt;Link: &lt;a href=&quot;https://clig.dev&quot;&gt;https://clig.dev&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;precision-timing&quot;&gt;Precision timing&lt;/h2&gt;

&lt;p&gt;It sucks to find out you’ve been living in the past. Here I was, talking about setting up an NTP (Network Time Protocol) server at work recently when I come across this article talking about how NTP is the predecessor to PTP (Precision Time Protocol) which has now been improved upon with SPTP (Simplified Precision Time Protocol)! Aaah!&lt;/p&gt;

&lt;p&gt;Link: &lt;a href=&quot;https://engineering.fb.com/2024/02/07/production-engineering/simple-precision-time-protocol-sptp-meta/&quot;&gt;https://engineering.fb.com/2024/02/07/production-engineering/simple-precision-time-protocol-sptp-meta/&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>what if you're not smart, the becquerel, Scalene, and generalists</title>
   <link href="https://nsbruce.github.io/dorktips/2024/02/07/not-smart-becquerel-scalene-generalist/"/>
   <updated>2024-02-07T00:00:00+00:00</updated>
   <id>https://nsbruce.github.io/dorktips/2024/02/07/not-smart-becquerel-scalene-generalist</id>
   <content type="html">&lt;h2 id=&quot;how-to-do-things-if-youre-not-that-smart-and-dont-have-any-talent&quot;&gt;How to do things if you’re not that smart and don’t have any talent&lt;/h2&gt;

&lt;p&gt;Doesn’t the title say it all? Lots of good lessons in here, you just have to deal with clicking on the link and wondering what that means about your self perception.&lt;/p&gt;

&lt;p&gt;Article: &lt;a href=&quot;https://adaobi.substack.com/p/how-to-do-things-if-youre-not-that&quot;&gt;https://adaobi.substack.com/p/how-to-do-things-if-youre-not-that&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;adopting-the-becquerel-for-network-requests&quot;&gt;Adopting the becquerel for network requests&lt;/h2&gt;

&lt;p&gt;This author says that the most suitable SI unit for network request rates is the becquerel (Bq), a unit of radioactive decay. I can’t say I’m passionate to take up this mantle but the argument that we should have a &lt;em&gt;general&lt;/em&gt; SI unit for the rate of non-periodic events is interesting.&lt;/p&gt;

&lt;p&gt;Article: &lt;a href=&quot;https://two-wrongs.com/si-units-for-request-rate&quot;&gt;https://two-wrongs.com/si-units-for-request-rate&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;scalene&quot;&gt;Scalene&lt;/h2&gt;

&lt;p&gt;A CPU/GPU/memory profiler for Python code, with an optional (opt-in) OpenAI powered “AI-optimization suggestions” feature. The reviews seem really positive, and the README includes some benchmarks comparing it against other profilers. I haven’t used it yet but I’ll give it a whirl next time I need a profiler!&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href=&quot;https://github.com/plasma-umass/scalene&quot;&gt;https://github.com/plasma-umass/scalene&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;generalist-vs-specialist-software-developers&quot;&gt;Generalist vs specialist software developers&lt;/h2&gt;

&lt;p&gt;This author describes their experience needing to market themselves as a specialist to pick up contract software work, while actually being a generalist. Further, they think that being a generalist is what the projects often actually need, and the desire for a specialist is off-base.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;…in theory all companies like adaptable people. In practice I find most job descriptions prefer specialists (&lt;a href=&quot;https://news.ycombinator.com/item?id=32921907&quot;&gt;source&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Article: &lt;a href=&quot;https://ochagavia.nl/blog/the-undercover-generalist/&quot;&gt;https://ochagavia.nl/blog/the-undercover-generalist/&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>random numbers, dependencies, and Zed</title>
   <link href="https://nsbruce.github.io/dorktips/2024/01/31/random-numbers-dependencies-zed/"/>
   <updated>2024-01-31T00:00:00+00:00</updated>
   <id>https://nsbruce.github.io/dorktips/2024/01/31/random-numbers-dependencies-zed</id>
   <content type="html">&lt;h2 id=&quot;random-number-generator-in-your-head&quot;&gt;Random number generator in your head&lt;/h2&gt;

&lt;p&gt;This article walks through how to generate 2 digit “pretty random” numbers quickly and in your head. The author does over the history of the method, why it works, and alternatives to it.&lt;/p&gt;

&lt;p&gt;In a nutshell:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Pick a seed&lt;/li&gt;
  &lt;li&gt;Add the 10s digit to 6 times the 1s digit&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It’s a pretty math-y article but the explanations of how it works is cool. The only downside is that they explore the algorithm using demo snippets of code in a language called &lt;a href=&quot;https://raku.org/&quot;&gt;Raku&lt;/a&gt;, which I have never heard of and had a hard time reading.&lt;/p&gt;

&lt;p&gt;Article: &lt;a href=&quot;https://www.hillelwayne.com/post/randomness&quot;&gt;https://www.hillelwayne.com/post/randomness&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;understanding-dependencies&quot;&gt;Understanding dependencies&lt;/h2&gt;

&lt;p&gt;This website helps create a dependency tree for a given package, and checks for things like security vulnerabilities and licenses. It supports npm, go, maven, pypi, nuget and cargo, and regenerates the entire dependency structure once per day. I have been using it when reviewing merge requests. Sometimes the developer who’s code I’m reviewing added some new package I’ve never heard of, and I’ll often skim the docs to ensure the package inclusion makes sense, but this is a great tool to quickly check for what else lurks in the packages dependencies.&lt;/p&gt;

&lt;p&gt;There is also a free API for the data that the website is serving but I haven’t used it yet (and probably won’t, the website is slick).&lt;/p&gt;

&lt;p&gt;Link: &lt;a href=&quot;https://www.deps.dev&quot;&gt;https://www.deps.dev&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;zed&quot;&gt;Zed&lt;/h2&gt;

&lt;p&gt;Everyone has their favourite IDE and I’ve tried many of them over the years. I’ve been using VSCode for a few years now and while good it’s definitely not a speed demon. Up next on my try-maybe-plate is Zed, authored by the creators of Atom and Electron.js. The Atom and Electron combo melded into VSCode, and the authors have now written Zed to try and speed things up. Zed is based on a &lt;a href=&quot;https://zed.dev/blog/videogame&quot;&gt;GPU UI framework written in Rust&lt;/a&gt; they wrote for this purpose.&lt;/p&gt;

&lt;p&gt;Their other major selling point is having very fast co-coding baked in. I look forward to trying it but will have to wait for sometone else to install it first!&lt;/p&gt;

&lt;p&gt;Lastly, it was recently open sourced.&lt;/p&gt;

&lt;p&gt;Link: &lt;a href=&quot;https://zed.dev&quot;&gt;https://zed.dev&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>z, practicing, and diátaxis</title>
   <link href="https://nsbruce.github.io/dorktips/2024/01/21/z-practice-diataxis/"/>
   <updated>2024-01-21T00:00:00+00:00</updated>
   <id>https://nsbruce.github.io/dorktips/2024/01/21/z-practice-diataxis</id>
   <content type="html">&lt;h2 id=&quot;z&quot;&gt;z&lt;/h2&gt;

&lt;p&gt;This tool learns your most “frecent” directories. From their README:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Frecency is a portmanteau of ‘recent’ and ‘frequency’. It is a weighted rank  that depends on how often and how recently something occurred. As far as I know, Mozilla came up with the term.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Once trained, the shell command &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;z&lt;/code&gt; lets you &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cd&lt;/code&gt; to a “frecent” directory based on regex. To demo this, I installed it (by simply adding the repos &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;z.sh&lt;/code&gt; file path to my &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.zshrc&lt;/code&gt;), then created a few directories with similar paths, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cd&lt;/code&gt;‘d between one of them, then checked that the regex only grabbed one:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/workspaces &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;mkdir&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; very_used/foo/bar
/workspaces &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;mkdir&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; never_used/foo/bar
/workspaces &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;very_used/foo/bar
/workspaces/very_used/foo/bar &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; -
/workspaces &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;z bar foo  &lt;span class=&quot;c&quot;&gt;# nothing happens here since this regex doesn&apos;t match anything&lt;/span&gt;
/workspaces &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;z foo bar  &lt;span class=&quot;c&quot;&gt;# great success, running this takes us to the correct directory&lt;/span&gt;
/workspaces/very_used/foo/bar &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;z &lt;span class=&quot;nt&quot;&gt;-l&lt;/span&gt;  &lt;span class=&quot;c&quot;&gt;# list the &quot;known&quot; directories&lt;/span&gt;
common:    /workspaces
89784      /workspaces/very_used/foo/bar
209463     /workspaces
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Cool! The repo README goes into some detail about how it works, but the gist is that recent directories get higher weights quickly to overcome old but frequently visited directories.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href=&quot;https://github.com/rupa/z&quot;&gt;https://github.com/rupa/z&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;practice-programming&quot;&gt;Practice programming&lt;/h2&gt;

&lt;p&gt;The author argues that like playing music, or anything else you want to “be good at” (which can either mean maintaining your personal status quo, or improving), you need to practice that skill. Two quotes I liked:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;[Musicians] have to continue spending considerable amounts of time simply to maintain technique, let alone expand it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;… many programmers implicitly finish the bulk of their learning early on, and some stop learning entirely…&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The author talks about his own experience practicing programming by automating tasks and taking on small, real world projects.&lt;/p&gt;

&lt;p&gt;I suppose this is one of the reasons I started dorktips. I enjoy trying to keep up to date on the software world, and this article resonated with me.&lt;/p&gt;

&lt;p&gt;Article: &lt;a href=&quot;https://tratt.net/laurie/blog/2022/practising_programming.html&quot;&gt;https://tratt.net/laurie/blog/2022/practising_programming.html&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;diátaxis&quot;&gt;diátaxis&lt;/h2&gt;

&lt;p&gt;This is a methodology for documentation which I’ve seen referenced a few times with respect to software. It seems well trusted, with Ubuntu, Python, and a number of other big groups committed to forming their documentation in this way. It’s an architecture which outlines what documentation should be written, how it should be written, and how to organize it. The primary principle of the “what” is that everything should fall into one of 4 categories:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Tutorials&lt;/li&gt;
  &lt;li&gt;How-to guides&lt;/li&gt;
  &lt;li&gt;Explanation&lt;/li&gt;
  &lt;li&gt;Reference&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I have plenty of reading left to do on this one, and I’m excited to learn more and perhaps start applying it to my own projects and at work.&lt;/p&gt;

&lt;p&gt;Link: &lt;a href=&quot;https://diataxis.fr/&quot;&gt;https://diataxis.fr/&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Go lessons, SSH-Snake, csvlens, qsv</title>
   <link href="https://nsbruce.github.io/dorktips/2024/01/15/go-ssh-snake-csvlens-qsv/"/>
   <updated>2024-01-15T00:00:00+00:00</updated>
   <id>https://nsbruce.github.io/dorktips/2024/01/15/go-ssh-snake-csvlens-qsv</id>
   <content type="html">&lt;h2 id=&quot;lessons-from-14-years-of-go&quot;&gt;Lessons from 14 years of Go&lt;/h2&gt;

&lt;p&gt;This is a script from a talk given by Rob Pike (one of the creators of Go Lang) where he discusses lessons learned during the Go lifetime. He focuses at one point on the transition from Go being a closed source project at Google to completely open-sourced and community driven and some of the lessons learned. Overall I found it a fun read and gave interesting insight into the process of creating a language.&lt;/p&gt;

&lt;p&gt;Article: &lt;a href=&quot;https://commandcenter.blogspot.com/2024/01/what-we-got-right-what-we-got-wrong.html&quot;&gt;https://commandcenter.blogspot.com/2024/01/what-we-got-right-what-we-got-wrong.html&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;ssh-snake&quot;&gt;SSH-Snake&lt;/h2&gt;

&lt;p&gt;A self-replicating program designed to map a network by running through the following steps (copied directly from their readme):&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;On the current system, find any SSH private keys,&lt;/li&gt;
  &lt;li&gt;On the current system, find any hosts or destinations (user@host) that the private keys may be accepted,&lt;/li&gt;
  &lt;li&gt;Attempt to SSH into all of the destinations using all of the private keys discovered,&lt;/li&gt;
  &lt;li&gt;If a destination is successfully connected to, repeats steps #1 - #4 on the connected-to system.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Spooky! The purpose is to demonstrate how vulnerable a network might be to a single compromised machine.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href=&quot;https://github.com/MegaManSec/SSH-Snake&quot;&gt;https://github.com/MegaManSec/SSH-Snake&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;csvlens&quot;&gt;csvlens&lt;/h2&gt;

&lt;p&gt;A command line CSV viewer. It opens a CSV file and using a TUI lets you scroll around, search, filter, etc.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href=&quot;https://github.com/YS-L/csvlens&quot;&gt;https://github.com/YS-L/csvlens&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;qsv&quot;&gt;qsv&lt;/h2&gt;

&lt;p&gt;Said “quicksilver” this is a CSV viewer like csvlens but also offers editing and joining CSVs. It even has methods for getting a GPT model to describe the data. It is a much heavier lifter than csvlens and of course that comes with added complexity (for the user).&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href=&quot;https://github.com/jqnatividad/qsv&quot;&gt;https://github.com/jqnatividad/qsv&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>copilot cli, inshellisense, slurp and grim</title>
   <link href="https://nsbruce.github.io/dorktips/2023/12/18/copilot-inshellisense-slurp-grim/"/>
   <updated>2023-12-18T00:00:00+00:00</updated>
   <id>https://nsbruce.github.io/dorktips/2023/12/18/copilot-inshellisense-slurp-grim</id>
   <content type="html">&lt;p&gt;In this post I have the usual, being some tools I’m trying out. I also added a small part of &lt;a href=&quot;#slurp-and-grim&quot;&gt;my dotfiles&lt;/a&gt; which still falls under the category of tools I’m using. Enjoy!&lt;/p&gt;

&lt;h2 id=&quot;github-copilot-cli&quot;&gt;Github Copilot CLI&lt;/h2&gt;

&lt;p&gt;One of the things I &lt;em&gt;don’t&lt;/em&gt; like about LLM chat bots is that they often require a context shift to interact with. You have to stop what you’re doing, open a browser, do your ‘chatting’, then go back to the task that prompted it all. One place where the LLM interface is not as annoying is in the IDE (where it acts as autocomplete on steroids). Github Copilot is one such option and they’ve now moved from the IDE into the terminal.&lt;/p&gt;

&lt;p&gt;It has two modes, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;explain&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;suggest&lt;/code&gt; which each take a string argument. Before replying to your prompt it asks whether this pertains to a generic shell command, a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gh&lt;/code&gt; command, or a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git&lt;/code&gt; command. I suppose it sends your prompt to a specifically trained model. It then either suggests or explains the command and gives you options to explain further, revise the command, rate the response, etc.&lt;/p&gt;

&lt;p&gt;Let’s do a quick demo! I’ll ask about some git rebasing since I can see this being a useful tool for un-rats-nesting git garbage fires.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;~ gh copilot suggest &lt;span class=&quot;s2&quot;&gt;&quot;rebase my branch onto main and for every conflict accept main instead of my branch&quot;&lt;/span&gt;

Welcome to GitHub Copilot &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;the CLI!
version 0.5.3-beta &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;2023-11-09&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

I&lt;span class=&quot;s1&quot;&gt;&apos;m powered by AI, so surprises and mistakes are possible. Make sure to verify any generated code or suggestions, and share feedback so that we can learn and improve.

? What kind of command can I help you with?
&amp;gt; git command

Suggestion:                                                                                    
                                                                                               
  git rebase -X theirs main                                                                    

? Select an option
&amp;gt; Explain command

Explanation:                                                                                   
                                                                                               
  • git rebase is used to apply commits from one branch to another.                            
    • -X theirs resolves conflicts by taking the changes from the branch being rebased (main)  
    instead of the current branch.                                                             
    • main: specifies the source branch (main) and the target branch is the current branch.    
                                                                                               

? Select an option  [Use arrows to move, type to filter]
&amp;gt; Exit
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;That looks pretty good. Interestingly I reran the exact same thing and the suggestion was &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git rebase -Xtheirs main&lt;/code&gt; without a space between &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-X&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;theirs&lt;/code&gt;. So as the warning after the prompt indicates, YMMV. It’s also evidently not searching the web because I asked it to explain &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tspin -f&lt;/code&gt; (from my last post) and it didn’t respond. Luckily, it didn’t make up garbage and instead said “try again”.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;~ ❯ gh copilot explain &lt;span class=&quot;s1&quot;&gt;&apos;tspin -f&apos;&lt;/span&gt;

Welcome to GitHub Copilot &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;the CLI!
version 0.5.3-beta &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;2023-11-09&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

I&lt;span class=&quot;s1&quot;&gt;&apos;m powered by AI, so surprises and mistakes are possible. Make sure to verify any generated code or suggestions, and share feedback so that we can learn and improve.

Explanation not readily available. Please revise for better results.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is cool work! I’m keen to try some open-sourced alternatives too, so if anyone out there has specific recommendations let me know!&lt;/p&gt;

&lt;p&gt;Link: &lt;a href=&quot;https://github.com/github/gh-copilot&quot;&gt;https://github.com/github/gh-copilot&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;inshellisense&quot;&gt;Inshellisense&lt;/h2&gt;

&lt;p&gt;Another one from the Microsoft cookbook, we have a shell autocompleter with a zinger of a name. They apparently have maked in autocomplete for 600+ CLI tools but I haven’t been able to find a list of them anywhere. Instead of ML-ing this I think they just parsed man pages to extract the goodies or something similar. You start it up with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;is&lt;/code&gt; and then it hijacks your prompt as you type to offer autocompletions. The gif at the top of their README tells the story.&lt;/p&gt;

&lt;p&gt;I actually haven’t been able to use this yet since &lt;a href=&quot;https://github.com/microsoft/inshellisense/issues/120&quot;&gt;there is an open issue about using handling dynamic prompt detection&lt;/a&gt; and I use powerlevel10k as a prompt. I’ll keep my eyes on it for a bit!&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href=&quot;https://github.com/microsoft/inshellisense&quot;&gt;https://github.com/microsoft/inshellisense&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;slurp-and-grim&quot;&gt;slurp and grim&lt;/h2&gt;

&lt;p&gt;I’m offering these two up as a special combo deal. I switched my compositor from X to Wayland recently and have had to figure out some replacements for basic utilities like screenshotting. To this end, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;slurp&lt;/code&gt; lets you select a region of Wayland-composed screen. When you run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;slurp&lt;/code&gt;, it lets you drag a rectangle on your screen then it outputs the top left coordinate of the rectangle as well as its width and height.&lt;/p&gt;

&lt;p&gt;In this example I selected from the top left of my screen to not-quite the bottom right.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;~ slurp
0,0 1920x1079
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;grim&lt;/code&gt; is a tool that makes images from a Wayland compositor. It has options to grab an entire display or a region, and whether to save to file or clipboard. The region option argument is the same shape as the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;slurp&lt;/code&gt; output. So I have my Print key bound to&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;grim &lt;span class=&quot;nt&quot;&gt;-g&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;slurp&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;which saves my selection to my &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~/Pictures&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;Repo (slurp): &lt;a href=&quot;https://github.com/emersion/slurp&quot;&gt;https://github.com/emersion/slurp&lt;/a&gt;
Repo (grim): &lt;a href=&quot;https://git.sr.ht/~emersion/grim/&quot;&gt;https://git.sr.ht/~emersion/grim/&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>critique, retries, pyapp and tailspin</title>
   <link href="https://nsbruce.github.io/dorktips/2023/12/17/critique-retries-pyapp-tailspin/"/>
   <updated>2023-12-17T00:00:00+00:00</updated>
   <id>https://nsbruce.github.io/dorktips/2023/12/17/critique-retries-pyapp-tailspin</id>
   <content type="html">&lt;h2 id=&quot;critique&quot;&gt;Critique&lt;/h2&gt;

&lt;p&gt;This article describes the internal code-review tool, Critique, used at Google. While the tool itself is interesting, it’s not publically available. What interested me most about this article was the amount of time and energy that Google has put into reducing friction for this process. They have done research on tons of interesting little details like whether anonymizing the process helps (it doesn’t), and how to reduce the sense of defensiveness that many people adopt when their code is criticized. There are links to some of that research in the article too.&lt;/p&gt;

&lt;p&gt;Article: &lt;a href=&quot;https://read.engineerscodex.com/p/how-google-takes-the-pain-out-of&quot;&gt;https://read.engineerscodex.com/p/how-google-takes-the-pain-out-of&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;retries&quot;&gt;Retries&lt;/h2&gt;

&lt;p&gt;An article about request-retry best practices. The visualizations are really fun and informative and not the claimed 11 minutes long! The salient points are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;don’t automatically retry requests too quickly,&lt;/li&gt;
  &lt;li&gt;exponentially increase retry delays on repeated failures,&lt;/li&gt;
  &lt;li&gt;add jittery to the delays to prevent clients synchronizing their requests.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Article: &lt;a href=&quot;https://encore.dev/blog/retries&quot;&gt;https://encore.dev/blog/retries&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;pyapp&quot;&gt;PyApp&lt;/h2&gt;

&lt;p&gt;This wraps a Python application into a stand-alone binary. At first I was having a hard time differentiating PyApp from pipx (which I wrote about in a prior post) but the major difference here is that the result is executable without any surrounding infrastructure. With pipx you run the application with something like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pipx my_app_name&lt;/code&gt; whereas once PyApp has been wrapped around the application you simply run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;./my_app_name&lt;/code&gt;. So it’s a different use case. Neato.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href=&quot;https://github.com/ofek/pyapp&quot;&gt;https://github.com/ofek/pyapp&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;tailspin&quot;&gt;tailspin&lt;/h2&gt;

&lt;p&gt;A log file colorizer (and more, I imagine). You install it, then instead of the typical &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tail mylog.log&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;less mylog.log&lt;/code&gt; or whatever, you use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tspin mylog.log&lt;/code&gt; and it parses and colors “numbers, dates, IP-addresses, UUIDs, URLs and more”. It works with no config but also allows customization.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href=&quot;https://github.com/bensadeh/tailspin&quot;&gt;https://github.com/bensadeh/tailspin&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>time estimates, Typst</title>
   <link href="https://nsbruce.github.io/dorktips/2023/12/12/time-estimates-typst/"/>
   <updated>2023-12-12T00:00:00+00:00</updated>
   <id>https://nsbruce.github.io/dorktips/2023/12/12/time-estimates-typst</id>
   <content type="html">&lt;h2 id=&quot;estimates-are-about-time-not-effort&quot;&gt;Estimates are about time, not effort&lt;/h2&gt;

&lt;p&gt;The author of the linked article argues that there is a time and place where Agile story-points are sensible but that they’re overused. Instead, estimation should be done in time. I’ve been doing story-point related estimation for a number of years now and I agree with many of the points they’re making.&lt;/p&gt;

&lt;p&gt;In the last section, they discuss situations when estimating in time is problematic too. One that stood out to me is that the estimate becomes tied to the person - we don’t all work at the same rate. They say this is a problem if your Agile setup means tasks are shuffled around between workers.&lt;/p&gt;

&lt;p&gt;This article has me thinking about alternative ways to estimate. Shoot me a message if you have any ideas or insight on the matter!&lt;/p&gt;

&lt;p&gt;Article: &lt;a href=&quot;https://ntietz.com/blog/estimate-in-time&quot;&gt;https://ntietz.com/blog/estimate-in-time&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;typst&quot;&gt;Typst&lt;/h2&gt;

&lt;p&gt;I really thought I had written about this a while back but apparently not. Typst (&lt;a href=&quot;https://github.com/typst/typst#pronunciation-and-spelling&quot;&gt;pronunciation&lt;/a&gt;) is offering an alternative to LaTeX.&lt;/p&gt;

&lt;p&gt;I’ve set up a comparison. I wrote up a basic section of text that covers a large percent of my normal use cases (equations, figures and tables) in LaTeX then recreated it in Typst. Lets see how it looks.&lt;/p&gt;

&lt;h3 id=&quot;latex-demo&quot;&gt;LaTeX demo&lt;/h3&gt;

&lt;p&gt;The actual contents, including frontmatter, is:&lt;/p&gt;

&lt;div class=&quot;language-latex highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;\documentclass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;article&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;\usepackage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;graphicx&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;\usepackage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;cleveref&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nt&quot;&gt;\begin{document}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;\section&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;First level heading&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
Some content including an inline equation &lt;span class=&quot;p&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;\phi&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;$&lt;/span&gt; as well as a reference to a numbered equation, &lt;span class=&quot;k&quot;&gt;\cref&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;eq:demo&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;.

&lt;span class=&quot;nt&quot;&gt;\begin{equation}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;\theta&lt;/span&gt; = &lt;span class=&quot;k&quot;&gt;\left&lt;/span&gt;(&lt;span class=&quot;k&quot;&gt;\frac&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;\sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;x&lt;span class=&quot;p&quot;&gt;}}{&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;\sqrt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;z&lt;span class=&quot;p&quot;&gt;}}&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;\right&lt;/span&gt;)&lt;span class=&quot;p&quot;&gt;^&lt;/span&gt;2
    &lt;span class=&quot;k&quot;&gt;\label&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;eq:demo&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;\end{equation}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;\subsection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;Second level heading&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
Here we show a figure, &lt;span class=&quot;k&quot;&gt;\cref&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;fig:demo&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; and a simple table, &lt;span class=&quot;k&quot;&gt;\cref&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;tab:demo&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;.

&lt;span class=&quot;nt&quot;&gt;\begin{figure}&lt;/span&gt;[h]
    &lt;span class=&quot;k&quot;&gt;\centering&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;\includegraphics&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;[width=0.5\linewidth]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;demo.jpg&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;\caption&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;My figure caption&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;\label&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;fig:demo&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;\end{figure}&lt;/span&gt;


&lt;span class=&quot;nt&quot;&gt;\begin{table}&lt;/span&gt;[h]
    &lt;span class=&quot;k&quot;&gt;\centering&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;\begin{tabular}&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;|c|c|&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;\textbf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;x&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;\textbf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;y&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;\\&lt;/span&gt;
         5.0 &lt;span class=&quot;p&quot;&gt;&amp;amp;&lt;/span&gt; 6.1 &lt;span class=&quot;k&quot;&gt;\\&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;\end{tabular}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;\caption&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;My table caption&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;\label&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;tab:demo&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;\end{table}&lt;/span&gt;

&lt;span class=&quot;nt&quot;&gt;\end{document}&lt;/span&gt;

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

&lt;p&gt;Which results in the following page (which I cropped for convenience).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/2023-12-12-latex-demo.png&quot; alt=&quot;latex demo result&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;typst-demo&quot;&gt;Typst demo&lt;/h3&gt;

&lt;p&gt;The roughly equivalent output is obtained in Typst with the following (note that at the time of this writing my syntax highlighter doesn’t support Typst so it’s doing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sh&lt;/code&gt; highlighting).&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#set math.equation(numbering: &quot;1&quot;)&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#set heading(numbering: &quot;1.&quot;)&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; First level heading &amp;lt;first-level-heading&amp;gt;
Some content including an inline equation &lt;span class=&quot;nv&quot;&gt;$x&lt;/span&gt; eq phi.alt plus 1&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;as well as a reference to a numbered equation, @eq:demo.

&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;theta eq lr&lt;span class=&quot;o&quot;&gt;((&lt;/span&gt;frac&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sum &lt;/span&gt;x, sqrt&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;z&lt;span class=&quot;o&quot;&gt;))))&lt;/span&gt;^2 &lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&amp;lt;eq:demo&amp;gt;

&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; Second level heading &amp;lt;second-level-heading&amp;gt;
Here we show a figure, @fig:demo and a simple table,

&lt;span class=&quot;c&quot;&gt;#figure(&lt;/span&gt;
  image&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;demo.jpg&quot;&lt;/span&gt;, width: 50%&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;,
  caption: &lt;span class=&quot;s2&quot;&gt;&quot;My figure caption&quot;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &amp;lt;fig:demo&amp;gt;

&lt;span class=&quot;c&quot;&gt;#figure(&lt;/span&gt;
  table&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
    columns: 2,
    rows: 2,
        &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;x&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;,[&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;y&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;,
        &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;5.0],[6.1],
  &lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;,
  caption: &lt;span class=&quot;s2&quot;&gt;&quot;My table caption&quot;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Which results in the following page (again cropped for convenience).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/2023-12-12-typst-demo.png&quot; alt=&quot;typst demo&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;Typst is pretty slick. It’s really fast since it was written (well, apparently) in Rust. This is evident using their online editor &lt;a href=&quot;https://typst.app&quot;&gt;typst.app&lt;/a&gt; which feels similar to Overleaf but rebuilds the document on each keystroke.&lt;/p&gt;

&lt;p&gt;The obvious downside to Typst is that it doesn’t have all of academia using it. Journals probably aren’t about to start accepting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.typ&lt;/code&gt; files. I hope it gains more traction!&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href=&quot;https://github.com/typst/typst&quot;&gt;https://github.com/typst/typst&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>jq, jaq, cd ., bad plots</title>
   <link href="https://nsbruce.github.io/dorktips/2023/12/11/jq-jaq-cd-bad-graphs/"/>
   <updated>2023-12-11T00:00:00+00:00</updated>
   <id>https://nsbruce.github.io/dorktips/2023/12/11/jq-jaq-cd-bad-graphs</id>
   <content type="html">&lt;p&gt;I’ve fallen behind and not just in terms of timeline - I have a lot of tabs open with dorktips fodder so I will hopefully publish a few of these articles over the next short period.&lt;/p&gt;

&lt;h2 id=&quot;jq&quot;&gt;jq&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jq&lt;/code&gt; is a CLI JSON processor. I assume it stands for “JSON query”.&lt;/p&gt;

&lt;p&gt;The simplest thing it does is pretty-print a JSON structure&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;~ ❯ &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;{&quot;ugly&quot;:63,&quot;doodad&quot;:[{&quot;nested&quot;:&quot;thing&quot;}]}&apos;&lt;/span&gt; | jq &lt;span class=&quot;s1&quot;&gt;&apos;.&apos;&lt;/span&gt;                                                           

  &lt;span class=&quot;s2&quot;&gt;&quot;ugly&quot;&lt;/span&gt;: 63
  &lt;span class=&quot;s2&quot;&gt;&quot;doodad&quot;&lt;/span&gt;: 
    &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&quot;nested&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;thing&quot;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We can also parse the JSON in various ways&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;~ ❯ &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;{&quot;ugly&quot;:63,&quot;doodad&quot;:[{&quot;nested&quot;:&quot;thing&quot;}]}&apos;&lt;/span&gt; | jq &lt;span class=&quot;s1&quot;&gt;&apos;.ugly&apos;&lt;/span&gt;
63
~ ❯ &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;{&quot;ugly&quot;:63,&quot;doodad&quot;:[{&quot;nested&quot;:&quot;thing&quot;}]}&apos;&lt;/span&gt; | jq &lt;span class=&quot;s1&quot;&gt;&apos;.doodad[0].nested&apos;&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;&quot;thing&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you want to try it before you buy it (jk it’s FOSS, albeit with a non-standard license) out check out the &lt;a href=&quot;https://jqplay.org&quot;&gt;online sandbox&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thanks to longtime reader and avid fan, Dustin, for introducing me to this one!&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href=&quot;https://github.com/jqlang/jq&quot;&gt;https://github.com/jqlang/jq&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;jaq&quot;&gt;jaq&lt;/h2&gt;

&lt;p&gt;And now, in a move which I can’t decide whether it’s particularly stupid or a stroke of genius, I’m showing you a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jq&lt;/code&gt; clone, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jaq&lt;/code&gt; (said “Jaques”). It’s a written in Rust and it’s aim is to be a drop in replacement for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jq&lt;/code&gt; but faster and with some bugs fixed.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href=&quot;https://github.com/01mf02/jaq&quot;&gt;https://github.com/01mf02/jaq&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;cd-&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cd .&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;The author of the linked blog post points out that there is a use for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cd .&lt;/code&gt;. In a scenario where you have two terminals open, one is inside a directory and in the second you delete and recreate that directory. In the first you can use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cd .&lt;/code&gt; to refresh the directory.&lt;/p&gt;

&lt;p&gt;I think of the case where you’re mucking around in a cmake build directory and rebuild the project including a teardown.&lt;/p&gt;

&lt;p&gt;Article: &lt;a href=&quot;https://blog.meain.io/2023/navigating-around-in-shell&quot;&gt;https://blog.meain.io/2023/navigating-around-in-shell&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;friends-dont-let-friends-make-bad-graphs&quot;&gt;Friends don’t let friends make bad graphs&lt;/h2&gt;

&lt;p&gt;This is a simple readme with a list of data visualization no-no’s. The ones that stood out to me are the sample-size requirement for violin plots (I’m a recent offender) and heatmap outliers (which comes up frequently when dealing with wideband radio data in time-frequency spectrograms.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href=&quot;https://github.com/cxli233/FriendsDontLetFriends&quot;&gt;https://github.com/cxli233/FriendsDontLetFriends&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>marl, hypothesis, zany</title>
   <link href="https://nsbruce.github.io/dorktips/2023/10/06/marl-hypothesis-zany/"/>
   <updated>2023-10-06T00:00:00+00:00</updated>
   <id>https://nsbruce.github.io/dorktips/2023/10/06/marl-hypothesis-zany</id>
   <content type="html">&lt;h2 id=&quot;are-new-users-the-problem-with-software&quot;&gt;Are new users the problem with software?&lt;/h2&gt;

&lt;p&gt;This article asks the question “why do applications seem &lt;em&gt;worse&lt;/em&gt; than they used to?”. The author argues that since user-base growth is a common metric for the success of an app, companies are incentivized only to keep drawing in new users rather than focusing on existing users. To draw in new users, they simplify the app, generally creating a worse experience for existing users. The author points to websites like Reddit and Craigslist for counter-examples. Neither has changed (meaningfully) in years yet enjoy continuing popularity.&lt;/p&gt;

&lt;p&gt;Article: &lt;a href=&quot;https://nothinghuman.substack.com/p/the-tyranny-of-the-marginal-user&quot;&gt;https://nothinghuman.substack.com/p/the-tyranny-of-the-marginal-user&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;hypothesis&quot;&gt;hypothesis&lt;/h2&gt;

&lt;p&gt;hypothesis is a python library to help with testing. The idea is that you want to test a function which has some arguments. You can use hypothesis to automatically run a bunch of random and likely offending values through the function and see if it breaks. For a real world example, I wrote a simple angle normalization function recently:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;normalize_angle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;angle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;Normalize angle to range [0, 2*pi)&quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;angle&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;which looked pretty solid. I slapped some normal unit tests on it with some values I dreamed up (-pi -&amp;gt; pi, 2pi -&amp;gt; 0, 3pi -&amp;gt; pi, etc) and the tests passed. But I then added hypothesis like so:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;hypothesis&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;given&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;strategies&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;st&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;given&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;angle&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;st&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;floats&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_normalize_any_angle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;angle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;normalize_angle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;angle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;2.0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;which failed with the following error:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    @given&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;angle&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;st.floats&lt;span class=&quot;o&quot;&gt;())&lt;/span&gt;
    def test_normalize_any_angle&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;angle: float&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; -&amp;gt; None:
&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;       assert 0.0 &amp;lt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; normalize_angle&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;angle&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &amp;lt; 2.0 &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; pi
E       assert 0.0 &amp;lt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; nan
E        +  where nan &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; normalize_angle&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;inf&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
E       Falsifying example: test_normalize_any_angle&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
E           &lt;span class=&quot;nv&quot;&gt;angle&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;inf,
E       &lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Right, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;inf&lt;/code&gt; is a float, and one of the default values in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;st.floats()&lt;/code&gt; “test strategy”. I needed to add a catch for nans/infs/etc. In some cases this type of testing may be overkill but the principle at play is: “You said your function would take any float. Does it?”. I particularly like to use it when the tests I’ve written are trivial examples I’ve dreamed up (-pi -&amp;gt; pi, …). It’s preferable in these cases to have hypothesis pressure test your functions. There are a bunch of other test strategies for different data types and you can define more complex ones.&lt;/p&gt;

&lt;p&gt;Link: &lt;a href=&quot;https://hypothesis.readthedocs.io/en/latest/&quot;&gt;https://hypothesis.readthedocs.io/en/latest/&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;zanysh&quot;&gt;zany.sh&lt;/h2&gt;

&lt;p&gt;A easy-to-use favicon server. Instead of generating and serving a favicon.ico file along with your website, you use an html request where the query parameters define the favicon. For example, I switched the favicon of this website to a dork icon! In my header I have:&lt;/p&gt;

&lt;div class=&quot;language-html highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;link&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;rel=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;icon&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;href=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;https://zany.sh/favicon.svg?emoji=🤓&amp;amp;background-color=none&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Link: &lt;a href=&quot;https://zany.sh&quot;&gt;https://zany.sh&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>walk, python meets excel, gitlab meets the fediverse</title>
   <link href="https://nsbruce.github.io/dorktips/2023/08/25/walk-python-excel-gitlab-fediverse/"/>
   <updated>2023-08-25T00:00:00+00:00</updated>
   <id>https://nsbruce.github.io/dorktips/2023/08/25/walk-python-excel-gitlab-fediverse</id>
   <content type="html">&lt;h2 id=&quot;walk&quot;&gt;walk&lt;/h2&gt;

&lt;p&gt;This is a cd/ls replacement lets you travese your filesystem using arrow keys and fuzzy search. It includes a preview option that you can have open while traversing. You can then open a file in your favorite editor (set with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EDITOR&lt;/code&gt; environment variable).&lt;/p&gt;

&lt;p&gt;Note there is &lt;a href=&quot;https://github.com/antonmedv/walk/issues/68&quot;&gt;currently a bug where if installed via snap the open-in-editor feature doesn’t work&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It also doesn’t elegantly handle opening a directory where the user doesn’t have permission to read the contents. I had an error get thrown but I imagine this relatively young project will push support for this soon.&lt;/p&gt;

&lt;p&gt;Overall I see this as a replacement for cd/ls &lt;em&gt;in the scenario&lt;/em&gt; where you’re looking through files. I don’t think I would naturally use it when I was strictly cd/ls-ing to a single known file or directory, but if I was cd/ls-ing through a bunch of files which I was inspecting, I can see using this with the preview enabled.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href=&quot;https://github.com/antonmedv/walk&quot;&gt;https://github.com/antonmedv/walk&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;python-in-excel&quot;&gt;Python in Excel&lt;/h2&gt;

&lt;p&gt;Microsoft is bringing Python into Excel. There are always a lot of haters out there when it comes to Excel, but I think this will help people dip their toes in the world of software development. At some of my previous jobs I had to use Excel a lot and while I’m really glad I don’t have to anymore, I think this would have been a great way to get started programming without angering my corporate overlords.&lt;/p&gt;

&lt;p&gt;Link: &lt;a href=&quot;https://techcommunity.microsoft.com/t5/microsoft-365-blog/introducing-python-in-excel-the-best-of-both-worlds-for-data/ba-p/3905482&quot;&gt;https://techcommunity.microsoft.com/t5/microsoft-365-blog/introducing-python-in-excel-the-best-of-both-worlds-for-data/ba-p/3905482&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Video: &lt;a href=&quot;https://www.youtube.com/watch?v=8ofsE7xiGho&quot;&gt;https://www.youtube.com/watch?v=8ofsE7xiGho&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;gitlab-embraces-the-fediverse&quot;&gt;Gitlab embraces the Fediverse&lt;/h2&gt;

&lt;p&gt;Okay I know this is two “company meets open source” stories in a row but I think this is a really cool development. Gitlab is going to start supporting the ActivityPub protocol (on which Mastodon, Bluesky, Lemmy and Pixelfed are based) in a few different ways. If you search the issues at their &lt;a href=&quot;https://gitlab.com/gitlab-org/gitlab/-/issues&quot;&gt;core repo&lt;/a&gt; you can see a number of relevant issues and discussions. The one I’m specifically linking to below is about leveraging the protocol for &lt;em&gt;cross-server&lt;/em&gt; merge requests. To summarize the idea:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;You have an account on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gitlab.myserver.ca&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;You fork a project hosted on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gitlab.com&lt;/code&gt; &lt;em&gt;using your account from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gitlab.myserver.ca&lt;/code&gt;&lt;/em&gt;.&lt;/li&gt;
  &lt;li&gt;You make edits and make a merge request from your fork to the original project.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you imagine this being implemented on other git hosts like Github, it would allow you to self-host a git account and still contribute to projects hosted on other servers. I’m excited to see where it goes.&lt;/p&gt;

&lt;p&gt;Link: &lt;a href=&quot;https://gitlab.com/gitlab-org/gitlab/-/issues/421930&quot;&gt;https://gitlab.com/gitlab-org/gitlab/-/issues/421930&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>gptoptout, fixit2, continue, typograms, and throwing away your code</title>
   <link href="https://nsbruce.github.io/dorktips/2023/08/14/gptoptout-fixit2-continue-typograms-throw-away-code/"/>
   <updated>2023-08-14T00:00:00+00:00</updated>
   <id>https://nsbruce.github.io/dorktips/2023/08/14/gptoptout-fixit2-continue-typograms-throw-away-code</id>
   <content type="html">&lt;h2 id=&quot;gptbot-opt-out&quot;&gt;GPTBot opt-out&lt;/h2&gt;

&lt;p&gt;OpenAI now offers a method of stopping it’s web crawler from using your website as training material. You can see an example of it running for dorktips here: &lt;a href=&quot;https://nsbruce.github.io/dorktips/robots.txt&quot;&gt;robots.txt&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Documentation: &lt;a href=&quot;https://platform.openai.com/docs/gptbot&quot;&gt;https://platform.openai.com/docs/gptbot&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;fixit2&quot;&gt;Fixit2&lt;/h2&gt;

&lt;p&gt;Meta has published the first(?) auto-fixing linter. It’s a python linter that is heavily based on &lt;a href=&quot;https://flake8.pycqa.org/en/latest/&quot;&gt;flake8&lt;/a&gt; and it will automatically fix some of the issues it finds. It also let you setup custom rules and fixes which they showcase in the release announcement. There is a link to the pypi package at the end of the announcement.&lt;/p&gt;

&lt;p&gt;Release announcement: &lt;a href=&quot;https://engineering.fb.com/2023/08/07/developer-tools/fixit-2-linter-meta/&quot;&gt;https://engineering.fb.com/2023/08/07/developer-tools/fixit-2-linter-meta/&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;continue&quot;&gt;continue&lt;/h2&gt;

&lt;p&gt;For those on the waitlist for the &lt;a href=&quot;https://docs.github.com/en/copilot/github-copilot-chat/using-github-copilot-chat&quot;&gt;VSCode Github Copilot Chat&lt;/a&gt; public beta. There is now an alternative. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;continue&lt;/code&gt; is a VSCode extension that exposes OpenAI’s LLMs as an in-IDE chat window. You can access the gpt-3.5-turbo and gpt-4 models freely at first but then need to use an API key.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href=&quot;https://github.com/continuedev/continue&quot;&gt;https://github.com/continuedev/continue&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;typograms&quot;&gt;Typograms&lt;/h2&gt;

&lt;p&gt;Google’s hat in the ring for typographic images. &lt;a href=&quot;https://mermaid.js.org/&quot;&gt;Mermaid&lt;/a&gt; seems to have been taking the world by storm and while I quite like it, there are some things that are still annoying (I’m looking at you, inability-to-enforce-node-positions). As such I’m excited for some competition in this space. On the documentation what they say about Mermaid is&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Unlike libraries like mermaid, typograms are defined typographically (WYSWYG), rather than semantically (a transformation from a high level description to graphics), which picks a different trade-off: it gives you more control over the rendering (expressivity) at the cost of making you type more (productivity).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let’s try it right now. Here is what I shoved into this post:&lt;/p&gt;

&lt;div class=&quot;language-html highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;script &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;https://google.github.io/typograms/typograms.js&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;script &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;text/typogram&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;+---+&lt;/span&gt;                        &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;---&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;   &lt;span class=&quot;o&quot;&gt;|---&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Welcome&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;dorks&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;--*|&lt;/span&gt;   &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;+---+&lt;/span&gt;                        &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;---&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;and here is the result.&lt;/p&gt;

&lt;script src=&quot;https://google.github.io/typograms/typograms.js&quot;&gt;&lt;/script&gt;

&lt;script type=&quot;text/typogram&quot;&gt;
  +---+                        .---.
  |   |---&gt; Welcome, dorks &lt;--*|   |
  +---+                        &apos;---&apos;
&lt;/script&gt;

&lt;p&gt;Looks pretty good. It’s also available as a node package.&lt;/p&gt;

&lt;p&gt;Link: &lt;a href=&quot;https://google.github.io/typograms&quot;&gt;https://google.github.io/typograms&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;opinion-throw-away-the-first-draft-of-your-code&quot;&gt;Opinion: throw away the first draft of your code&lt;/h2&gt;

&lt;p&gt;This author argues that when starting a new project, it is worth the time investment for engineering teams to:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;prototype for a few days&lt;/li&gt;
  &lt;li&gt;literally delete all of the code&lt;/li&gt;
  &lt;li&gt;actually start building the project&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I won’t try to summarize much further but this is a good (and short) read. Sounds scary but I am interested to try this with one of my projects soon!&lt;/p&gt;

&lt;p&gt;Article: &lt;a href=&quot;https://ntietz.com/blog/throw-away-your-first-draft/&quot;&gt;https://ntietz.com/blog/throw-away-your-first-draft/&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>try, lineselect, pipx, and copier</title>
   <link href="https://nsbruce.github.io/dorktips/2023/07/07/try-lineselect-pipx-copier/"/>
   <updated>2023-07-07T00:00:00+00:00</updated>
   <id>https://nsbruce.github.io/dorktips/2023/07/07/try-lineselect-pipx-copier</id>
   <content type="html">&lt;p&gt;I’m really excited about some of the tools in this issue. Enjoy!&lt;/p&gt;

&lt;h2 id=&quot;try&quot;&gt;try&lt;/h2&gt;

&lt;p&gt;This lets you prefix any command line operation with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;try&lt;/code&gt; and it sandboxes it so you can observe what will happen without actually doing it. It’s essentially a dry-run for any command. Once the sandboxed command is finished running, you can choose to “commit” (actually do) the command outside the sandbox.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href=&quot;https://github.com/binpash/try&quot;&gt;https://github.com/binpash/try&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;lineselect&quot;&gt;LineSelect&lt;/h2&gt;

&lt;p&gt;If you’re familiar with piping and xargs this adds an element of interactivity which I am a fan of. Essentially you pipe a command into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lineselect&lt;/code&gt; and it will print out the output of the command and wait for you to select which lines you want forwarded onto the &lt;em&gt;next&lt;/em&gt; command. Their readme is really good and includes a video showcase but the minimal example is listing files, selecting which ones to delete, and then deleting them:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;ls&lt;/span&gt; | lineselect | xargs &lt;span class=&quot;nb&quot;&gt;rm&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ls&lt;/code&gt; runs and has it’s normal output except that you can select which lines you want piped to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rm&lt;/code&gt;. To enable this it seems to ensure stdout is always in single column mode. I’m not sure how it does this but it’s pretty cool.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/chfritz/lineselect/issues/6&quot;&gt;I’ve offered to package this&lt;/a&gt; for the developer so it can be installed without the end user needing to install node.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href=&quot;https://github.com/chfritz/lineselect&quot;&gt;https://github.com/chfritz/lineselect&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;pipx&quot;&gt;pipx&lt;/h2&gt;

&lt;p&gt;Installs isolated python applications. In the readme they draw the comparison between themselves and other package managers like apt. Another quote from their readme:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;In a way, [pipx] turns Python Package Index (PyPI) into a big app store for Python applications.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I have seen a number of recent cli tools being distributed this way. I have a good example of this just &lt;a href=&quot;#copier&quot;&gt;below&lt;/a&gt;…&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href=&quot;https://github.com/pypa/pipx&quot;&gt;https://github.com/pypa/pipx&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;copier&quot;&gt;Copier&lt;/h2&gt;

&lt;p&gt;This is a slick tool for rendering project templates. I’ve been wanting something like this for quickly spinning up new projects. I’ve always disliked the workflow where you clone a “template” repository which is actually just a collection of files then have to go through and rename a bunch of stuff. Doing this means you inherit the git history (annoying) and the alternative is to clone the repo, delete the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.git&lt;/code&gt; folder, and then re-initialize the repo. This is a pain as well.&lt;/p&gt;

&lt;p&gt;Copier is available as a CLI app via &lt;a href=&quot;#pipx&quot;&gt;pipx&lt;/a&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pipx install copier&lt;/code&gt;) and you can then spin up a new project with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;copier copy &amp;lt;my-template&amp;gt; my/new-project&lt;/code&gt;. Two neat things here:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;the template can be a git url. No more local copy of a template necessary!&lt;/li&gt;
  &lt;li&gt;you can update a project to the latest version of the template with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;copier update&lt;/code&gt;. This is a really nice feature. Say you have a bunch of python projects and you change the CI in the template you no longer have to go manually change it everywhere.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Repo: &lt;a href=&quot;https://github.com/copier-org/copier&quot;&gt;https://github.com/copier-org/copier&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>git, jesth, and mojo</title>
   <link href="https://nsbruce.github.io/dorktips/2023/06/19/git-jesth-mojo/"/>
   <updated>2023-06-19T00:00:00+00:00</updated>
   <id>https://nsbruce.github.io/dorktips/2023/06/19/git-jesth-mojo</id>
   <content type="html">&lt;h2 id=&quot;thoughts-on-github-git-and-microsoft&quot;&gt;Thoughts on Github, git and Microsoft&lt;/h2&gt;

&lt;p&gt;It feels a bit like cheating to simply point you at another article, but I really think this is a great read. It took about 10 minutes for me to fully digest the authors thoughts and open about 30 embedded links.&lt;/p&gt;

&lt;p&gt;Interesting stances that author takes:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;git isn’t &lt;em&gt;that&lt;/em&gt; great. There are real alternatives that don’t solve every problem git has, but solve some. If we don’t give them a chance or at least consider them, we might all end up locked into a piecemeal VCS that is git. The author mentions several and what he likes about them.&lt;/li&gt;
  &lt;li&gt;Pull Requests have become the defacto standard for a coding workflow and are premised on low-trust. This &lt;em&gt;can&lt;/em&gt; be important for large teams, open-source projects, etc. but especially on a small team (even in large organizations) a high-trust environment is required to encourage independence and autonomy. A quote the author cites from a different article by Jessica Kerr is:
    &lt;blockquote&gt;
      &lt;p&gt;Pull requests are an improvement on working alone. But not on working together.&lt;/p&gt;
    &lt;/blockquote&gt;
  &lt;/li&gt;
  &lt;li&gt;there is a piece in there on Copyright vs Copyleft licensing I had to search for on DuckDuckGo. Copilot wrote the following when prompted by the word “copyleft”, and I confirm it’s an exact quote from the cited page:
    &lt;blockquote&gt;
      &lt;p&gt;Copyleft is a general method for making a program (or other work) free (in the sense of freedom, not “zero price”), and requiring all modified and extended versions of the program to be free as well. - &lt;em&gt;&lt;a href=&quot;https://www.gnu.org/copyleft/copyleft.html&quot;&gt;Copyleft: Pragmatic Idealism&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
    &lt;/blockquote&gt;
  &lt;/li&gt;
  &lt;li&gt;There is a bunch in there on Github itself being driven by profits.&lt;/li&gt;
  &lt;li&gt;The author makes several recommendations to avoid homogenization of the developer experience. A quote he makes that resonated with me is:
    &lt;blockquote&gt;
      &lt;p&gt;I learn something from every new tool I use, even if it doesn’t become my new default. It makes me more resilient to change and gives me a holistic understanding what I need to develop software.&lt;/p&gt;
    &lt;/blockquote&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My desire for “Dork tips” is tightly related to this sentiment.&lt;/p&gt;

&lt;p&gt;Article: &lt;a href=&quot;https://blog.edwardloveall.com/lets-make-sure-github-doesnt-become-the-only-option&quot;&gt;https://blog.edwardloveall.com/lets-make-sure-github-doesnt-become-the-only-option&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;jesth&quot;&gt;Jesth&lt;/h2&gt;

&lt;p&gt;Do you regularly use TOML (nesting is hard), YAML (bespoke ambiguity), or JSON (unreadable by humans)? The readme of the repo briefly outlines the shortcomings of each before introducing JESTH (Just Extract Sections Then Hack’em).&lt;/p&gt;

&lt;p&gt;The essence is that the document is split into TOML-like sections but the jesth parser does something like “lazy-parsing” (my phrase, not theirs). After loading in the sections, you can pick how to treat each.&lt;/p&gt;

&lt;p&gt;They syntax looks slick too!&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href=&quot;https://github.com/pyrustic/jesth&quot;&gt;https://github.com/pyrustic/jesth&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;mojo&quot;&gt;Mojo&lt;/h2&gt;

&lt;p&gt;A company called Modular announced a superset of Python called Mojo which compiles normal python code into MLIR. The article goes into way more background but MLIR is a a replacement for LLVM’s IR which is specifically designed for machine learning tasks (I know I’m not going into enough detail here but the article is really very good). The end result is that you get a C/Rust-comperable binary without needing to write anything other than vanilla Python. There &lt;em&gt;are&lt;/em&gt; a few Mojo specific annotations you can add to your code to help the compiler out, but they are optional, and really sensible. One is a struct and the other is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fn&lt;/code&gt;, a replacement for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;def&lt;/code&gt; keyword which requires your method is strictly type-annotated.&lt;/p&gt;

&lt;p&gt;I do urge critics to read the article since the author does a great job explaining why Python, why not C/Julia/etc, what are LLVM and MLIR, and the benefits of deploying code using Mojo.&lt;/p&gt;

&lt;p&gt;Link: &lt;a href=&quot;https://www.fast.ai/posts/2023-05-03-mojo-launch.html&quot;&gt;https://www.fast.ai/posts/2023-05-03-mojo-launch.html&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>fzf, xc, envio, and commandlinefu</title>
   <link href="https://nsbruce.github.io/dorktips/2023/05/02/fzf-xc-envio-fu/"/>
   <updated>2023-05-02T00:00:00+00:00</updated>
   <id>https://nsbruce.github.io/dorktips/2023/05/02/fzf-xc-envio-fu</id>
   <content type="html">&lt;h2 id=&quot;fzf&quot;&gt;fzf&lt;/h2&gt;

&lt;p&gt;Game changer. I’ve just started using it and it’s immediately changed (for the better) my workflow. It’s a CLI tool that stands for fuzzy find. The three main ways I use it are:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ctrl-R&lt;/code&gt; (the default keybinding is overwritten but can be used in much the same way): instead of having to get an exact match and only seeing one option, get a list of fuzzy matches&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Alt-C&lt;/code&gt;: cd into a fuzzy searched directory&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;**&amp;lt;TAB&amp;gt;&lt;/code&gt;: fuzzy autocomplete. For example &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cat **&amp;lt;TAB&amp;gt;&lt;/code&gt; will give you a list of fuzzy matches to cat while &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;code **&amp;lt;TAB&amp;gt;&lt;/code&gt; will give you a list of fuzzy directories to open in your IDE.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It also has a command &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fzf&lt;/code&gt; which opens the fuzzy finder. I have used it as drop-in to find paths for more specific commands like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;find&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Overall I’m not going to do a better job at describing it than Andrew Quinn (&lt;a href=&quot;https://andrew-quinn.me/fzf&quot;&gt;https://andrew-quinn.me/fzf&lt;/a&gt;) (although I just installed with apt like the repo suggests).&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href=&quot;https://github.com/junegunn/fzf&quot;&gt;https://github.com/junegunn/fzf&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;envio&quot;&gt;envio&lt;/h2&gt;

&lt;p&gt;I have not used this yet since most of my development work right now is not very environment variable dependent. However, in the past I have had to war regularly with environment variables and this looks like a great tool to help with that. It’s a CLI tool that helps you manage environment variables. It’s written in Rust and has a nice CLI interface. It’s also cross-platform. Essentially you can create encrypted environment profiles then switch between them. If you know, you know.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href=&quot;https://github.com/humblepenguinn/envio&quot;&gt;https://github.com/humblepenguinn/envio&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;command-line-fu&quot;&gt;Command Line Fu&lt;/h2&gt;

&lt;p&gt;Kinda cute. You know when you’re co-hacking with someone and they do something magical in one line? They knew some unix command you never took the time to figure out! Well, this website tries to crowd-source useful commands. Some are really “beginner” (the top voted of all time is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;!!&lt;/code&gt; to repeat the last command…) but some are fun!&lt;/p&gt;

&lt;p&gt;Link: &lt;a href=&quot;https://www.commandlinefu.com&quot;&gt;https://www.commandlinefu.com&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;xc&quot;&gt;xc&lt;/h2&gt;

&lt;p&gt;This is a markdown based task runner. I’ve begun using it and so far it’s a winner. The installation is simple (put binary in path), and then your tasks all go into a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;## Tasks&lt;/code&gt; section if your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;README.md&lt;/code&gt;. This is probably best described by example: lets ray you want to have a build task for your cpp project.&lt;/p&gt;

&lt;p&gt;In one architecture you write a makefile then document what it’s doing in your readme under some kind of “getting started” heading. In another architecture you add tasks to a task runner like “poe the poet” for python or “npm” for node and in your readme you say “install this taskrunner then use it to run my build task”. If the build task is updated it has to be done in two places and you may be requiring the user to install additional dependencies just to run a build task. It’s also bad design to ask users to type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sudo domybuildtask&lt;/code&gt;. Developers will have to take the time to go read exactly what it’s doing and decide if they trust it.&lt;/p&gt;

&lt;p&gt;In this architecture you just add a task to your readme. Let’s see a simplified example I’m currently using for a cpp project. In my &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;README.md&lt;/code&gt; I have:&lt;/p&gt;

&lt;div class=&quot;language-markdown highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gu&quot;&gt;## Tasks&lt;/span&gt;

This repository is &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;xc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt;https://xcfile.dev&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; compliant.  The following tasks are available:

&lt;span class=&quot;gu&quot;&gt;### build&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;```&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;bash
&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;mkdir&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; build
&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;build
cmake &lt;span class=&quot;nt&quot;&gt;-DCMAKE_INSTALL_PREFIX&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/usr/local &lt;span class=&quot;nt&quot;&gt;-DCMAKE_BUILD_TYPE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;Release ..
cmake &lt;span class=&quot;nt&quot;&gt;--build&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--target&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--config&lt;/span&gt; Release &lt;span class=&quot;nt&quot;&gt;-j&lt;/span&gt; &lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;nproc&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If someone has xc in their path they can just run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;xc build&lt;/code&gt; and it will execute the task. If someone does not have xc, they have a clear step-by-step guide to follow.&lt;/p&gt;

&lt;p&gt;It also lets you do things like pass arguments and use environment variables.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href=&quot;https://github.com/joerdav/xc&quot;&gt;https://github.com/joerdav/xc&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 

</feed>
